diff --git a/PuzzlePlayer/Binary.cs b/PuzzlePlayer/Binary.cs
index cd9d37e1c739a353f3cb9364a1b52e5a90f3ab9f..41fc11ef21bf3f7cb57d7c231b788aea7ec4f47c 100644
--- a/PuzzlePlayer/Binary.cs
+++ b/PuzzlePlayer/Binary.cs
@@ -22,37 +22,48 @@ namespace PuzzlePlayer_Namespace
         {
             boardState = GetClearBoard(boardSize);
 
-            description = "Binary puzzle is played on any even-numbered square grid, with some cells initially containing black or white circles. The goal of the puzzle is to fill all cells such that:\r\n- More than two circles of the same color cannot be adjacent\r\n- Each row and column must contain an equal number of black and white circles\r\n- Each row and column cannot appear multiple times on the board";
-            
+
+            description = "Binary puzzle is played on any even-numbered square grid, with some cells initially containing black or white circles. The goal of the puzzle is to fill all cells such that:\r\n● More than two circles of the same color cannot be adjacent\r\n● Each row and column must contain an equal number of black and white circles\r\n● Each row and column cannot appear multiple times on the board";
+
+            // clear the board (fill it in with -1)
+            Clear();
         }
 
-        public override void Draw (Graphics gr, Point p, Size s)
+        public override void Draw (Graphics gr, Rectangle r) //draws board in rectangle R. warning: will stretch image unless FitBoard() is used for rectangle size
         {
-            gr.FillRectangle(Brushes.Beige, p.X, p.Y, s.Width, s.Height);
+            Size tilesize = new Size(r.Width / boardState.GetLength(0), r.Height / boardState.GetLength(1));
+            Pen border = new Pen(Color.Black, 2);
+            gr.FillRectangle(Brushes.Beige, r.X, r.Y, tilesize.Width*boardState.GetLength(0), tilesize.Height*boardState.GetLength(1));
             for (int i = 0; i < boardState.GetLength(0); i++)
             {
                 for(int j = 0; j < boardState.GetLength(1); j++)
                 {
-                    gr.DrawRectangle(Pens.Black,
-                        p.X+i*s.Width/ boardState.GetLength(0),
-                        p.Y+j*s.Height/boardState.GetLength(1),
-                        s.Width / boardState.GetLength(0),
-                        s.Height / boardState.GetLength(1));
+
+                    gr.DrawRectangle(Pens.LightGray,
+                        r.X+i* tilesize.Width,
+                        r.Y+j* tilesize.Height,
+                        tilesize.Width,
+                        tilesize.Height);
                     if (boardState[i,j] == 0)
                     {
                         gr.FillEllipse(Brushes.White,
-                            (int)(p.X + ((double)i + 0.125) * s.Width / boardState.GetLength(0)),
-                            (int)(p.Y + ((double)j + 0.125) * s.Height / boardState.GetLength(1)),
-                            s.Width / boardState.GetLength(0) * 3 / 4,
-                            s.Height / boardState.GetLength(1) * 3 / 4);
+                            (int)(r.X + ((double)i + 0.125) * tilesize.Width),
+                            (int)(r.Y + ((double)j + 0.125) * tilesize.Height),
+                            tilesize.Width * 3 / 4,
+                            tilesize.Height * 3 / 4);
+                        gr.DrawEllipse(border,
+                            (int)(r.X + ((double)i + 0.125) * tilesize.Width + border.Width/2),
+                            (int)(r.Y + ((double)j + 0.125) * tilesize.Height + border.Width/2),
+                            tilesize.Width * 3 / 4 - border.Width,
+                            tilesize.Height * 3 / 4 - border.Width);
                     }
                     if (boardState[i, j] == 1)
                     {
                         gr.FillEllipse(Brushes.Black,
-                            (int)(p.X + ((double)i + 0.125) * s.Width / boardState.GetLength(0)),
-                            (int)(p.Y + ((double)j + 0.125) * s.Height / boardState.GetLength(1)),
-                            s.Width / boardState.GetLength(0) * 3 / 4,
-                            s.Height / boardState.GetLength(1) * 3 / 4);
+                            (int)(r.X + ((double)i + 0.125) * tilesize.Width),
+                            (int)(r.Y + ((double)j + 0.125) * tilesize.Height),
+                            tilesize.Width * 3 / 4,
+                            tilesize.Height * 3 / 4);
                     }
                 }
             }
@@ -438,6 +449,10 @@ namespace PuzzlePlayer_Namespace
                 return true;
 
             return false;
+        public override void TileInput(Point p, int x)
+        {
+            if (x==0 || x==1) boardState[p.X, p.Y] = x;
+
         }
     }
 }
\ No newline at end of file
diff --git a/PuzzlePlayer/Board.cs b/PuzzlePlayer/Board.cs
index edc10d88bde424a171cf0bbfe6175c66cde37761..739b48af62f14fe0bedc6700cb7fe3387286292b 100644
--- a/PuzzlePlayer/Board.cs
+++ b/PuzzlePlayer/Board.cs
@@ -44,8 +44,22 @@ namespace PuzzlePlayer_Namespace
         public int[,] boardState;
         public int[,] lastGeneratedBoard;
 
-        public abstract void Draw(Graphics gr, Point p, Size s);
 
+
+        // checks if the board is valid and solvable before setting the variable.
+        public bool setBoardState(int[,] newState)
+        {
+            int[,] copy = boardState;
+            boardState = newState;
+            if (IsBoardValid(newState) && Solve() == SOLUTIONS.UNIQUE)
+                return true;
+            else
+            {
+                boardState = copy;
+                return false;
+            }
+        }
+        public abstract void Draw(Graphics gr, Rectangle r);
         // a methode for solving the whole board. It uses the private SolveStep methode untill the whole board is solved
         // it has one parameter. setting this to true will only give a return value without changing the current boardState
         public SOLUTIONS Solve(bool CheckOnly)
@@ -99,5 +113,14 @@ namespace PuzzlePlayer_Namespace
 
         // abstract methode for generating a random board
         public abstract void Generate();
+
+        // abstract methode for checking if a imputed boardstate is valid
+        public abstract bool IsBoardValid(int[,] boardToCheck);
+
+        // changes tile P to value X
+        public abstract void TileInput(Point p, int x);
+
+        // performs a left/right (X) click on tile P, changing its value
+        public virtual void TileClick(Point p, int x) { }
     }
 }
diff --git a/PuzzlePlayer/PuzzleForm.cs b/PuzzlePlayer/PuzzleForm.cs
index 6a2d6c680e372e9c8a5549f31ec4b54a9da0b5cb..dde1ea08cf464db52f64c8b1ce59135635bbd6de 100644
--- a/PuzzlePlayer/PuzzleForm.cs
+++ b/PuzzlePlayer/PuzzleForm.cs
@@ -1,4 +1,5 @@
 using System;
+using System.CodeDom;
 using System.Collections.Generic;
 using System.Drawing;
 using System.Drawing.Text;
@@ -11,67 +12,73 @@ namespace PuzzlePlayer_Namespace
 {
     internal class PuzzleForm : Form
     {
-        private Button solvebutton;
-        private Button hintbutton;
-        private Button generatebutton;
-        private Label boardlabel;
-        private TextBox informationbox;
-        public Graphics graphics;
-
+        private readonly Button solvebutton;
+        private readonly Button hintbutton;
+        private readonly Button generatebutton;
+        private readonly Label titlebox;
+        private readonly Label informationbox;
+        private Rectangle boardspace;
+        private readonly BufferedGraphics bufferedGraphics;
         private Board board;
-        public Board Board //Updating the Board member will immediately call board.Draw method so that the board is updated visually
+        public Board Board //updating the Board member will immediately call board.Draw method so that the board is updated visually
         {
             get { return board; }
             set
             {
                 board = value;
-                board.Draw(graphics, new Point(220, 30), new Size(400, 400));
+                this.Invalidate();
             }
         }
 
-        public PuzzleForm(Board b = null, Size s = default(Size)) //Takes Board and Size parameter and sets up the PuzzleForm window.
+        private readonly Button UPDATEBUTTON;
+        public PuzzleForm(Board b, Size s = default) //takes Board and Size parameter and sets up the PuzzleForm window.
         {
-            if (s == default(Size)) s = new Size(800, 500);
-            this.Size = s;
-            graphics = this.CreateGraphics();
+            if (s == default) s = new Size(700, 420);
+            this.Size = this.MinimumSize = s;
+            this.WindowState = FormWindowState.Maximized;
+            this.BackColor = Color.DarkGreen;
+            this.Text = "PuzzlePlayer";
+            bufferedGraphics = BufferedGraphicsManager.Current.Allocate(this.CreateGraphics(), this.DisplayRectangle);
+            bufferedGraphics.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
             generatebutton = new Button();
             hintbutton = new Button();
             solvebutton = new Button();
-            informationbox = new TextBox();
-            Board = b;
-            CreateUI();
-            UpdateUI();
-            this.Resize += (object sender, EventArgs ea) =>
+            UPDATEBUTTON = new Button();
+            titlebox = new Label();
+            informationbox = new Label();
+            boardspace = new Rectangle(220, 30, 400, 400);
+
+            this.Paint += (object o, PaintEventArgs pea) =>
             {
-                UpdateUI();
+                board.Draw(bufferedGraphics.Graphics, boardspace);
+                //bufferedGraphics.Graphics.FillRectangle(Brushes.LightCoral, 220, 30, this.Width - 350, this.Height - 100);
+                //bufferedGraphics.Graphics.FillRectangle(Brushes.DarkRed, boardspace);
+                bufferedGraphics.Render();
+            };
+            this.Resize += (object o, EventArgs ea) => UpdateUI();
+            this.Move += (object o, EventArgs ea) => this.Focus();
+            this.KeyPress += (object o, KeyPressEventArgs kea) => Input(kea.KeyChar);
+            this.MouseClick += (object o, MouseEventArgs mea) =>
+            {
+                if (mea.Button == MouseButtons.Left)
+                {
+                    Input('[');
+                    return;
+                }
+                if (mea.Button == MouseButtons.Right)
+                {
+                    Input(']');
+                    return;
+                }
             };
 
-            // example board: https://imgur.com/spyYaPl
-            /*
-            int[,] test = Binary.GetClearBoard(Board.boardState.GetLength(0));
-
-            test[0, 0] = 1;
-            test[1, 0] = 1;
-            test[6, 0] = 1;
-            test[3, 1] = 1;
-            test[0, 2] = 1;
-            test[1, 2] = 1;
-            test[3, 2] = 1;
-            test[5, 4] = 1;
-            test[6, 4] = 1;
-            test[1, 5] = 1;
-            test[2, 5] = 1;
-            test[5, 5] = 1;
-            test[1, 7] = 1;
-            test[3, 7] = 0;
-            test[6, 7] = 1;
-
-            board.boardState = test;
-            //Board.setBoardState(test);
+            Board = b;
+            CreateUI();
 
-            //*/
+            Board.boardState[1, 1] = 1;
+            Board.boardState[2, 2] = 0;
         }
-        private void CreateUI()
+        private void CreateUI() //sets up ui elements
         {
             Point boardP = new Point(220, 30);
             Size boardS = new Size(400, 400);
@@ -80,15 +87,18 @@ namespace PuzzlePlayer_Namespace
             {
                 Controls.Add(b);
                 b.Size = new Size(80, 50);
-                b.BackColor = Color.Gainsboro;
+                b.FlatAppearance.BorderColor = b.BackColor = Color.Gainsboro;
                 b.Text = "DEFAULT0";
+                b.Font = new Font("Verdana", 12, FontStyle.Bold | FontStyle.Italic);
+                b.FlatStyle = FlatStyle.Flat;
+                b.GotFocus += (object o, EventArgs ea) => this.Focus();
             }
             CreateButton(generatebutton);
-            generatebutton.Text = "Generate";
+            generatebutton.Text = "New Game";
             generatebutton.MouseClick += (object sender, MouseEventArgs mea) => 
             {
-                board.Generate();
-                board.Draw(graphics, boardP, boardS);
+                Board.Generate();
+                Board = Board;
             };
             CreateButton(hintbutton);
             hintbutton.Text = "Hint";
@@ -96,28 +106,94 @@ namespace PuzzlePlayer_Namespace
             {
                 board.Draw(graphics, boardP, boardS);
                 MessageBox.Show("Hint: geef op");
+                Board = Board;
             };
             CreateButton(solvebutton);
             solvebutton.Text = "Solve";
             solvebutton.MouseClick += (object sender, MouseEventArgs mea) =>
             {
-                board.Solve(false);
-                board.Draw(graphics, boardP, boardS);
+                Board.Solve();
+                Board = Board;
+            };
+
+            CreateButton(UPDATEBUTTON);
+            UPDATEBUTTON.Text = "Update";
+            UPDATEBUTTON.Font = new Font("Verdana", 11, FontStyle.Bold);
+            UPDATEBUTTON.FlatAppearance.BorderColor = UPDATEBUTTON.BackColor = Color.Pink;
+            UPDATEBUTTON.MouseClick += (object sender, MouseEventArgs mea) =>
+            {
+                Board = Board;
             };
 
+            Controls.Add(titlebox);
+            titlebox.Location = new Point(20, 15);
+            titlebox.Size = new Size(180, 50);
+            titlebox.BackColor = this.BackColor;
+            titlebox.ForeColor = Color.White;
+            titlebox.Text = "Binary";
+            titlebox.Font = new Font("Verdana", 24, FontStyle.Bold);
+
             Controls.Add(informationbox);
-            informationbox.Multiline = true;
-            informationbox.Size = new Size(160, 400);
-            informationbox.BackColor = Color.LightGray;
+            informationbox.Location = new Point(20, 65);
+            informationbox.Size = new Size(180, 300);
+            informationbox.BackColor = this.BackColor;
+            informationbox.ForeColor = Color.White;
             informationbox.Text = board.description;
+            informationbox.Font = new Font("Verdana", 10);
+            UpdateUI();
         }
-
-        private void UpdateUI()
+        private void UpdateUI() //resizes the boardspace rectangle and updates the rest of the ui around the new boardspace size
+        {
+            bufferedGraphics.Graphics.Clear(this.BackColor);
+            boardspace.Size = FitBoard(new Size(Board.boardState.GetLength(0),Board.boardState.GetLength(1)),new Size(this.Width - 350, this.Height - 100),8);
+            generatebutton.Location = new Point(boardspace.Right + 30, 30);
+            hintbutton.Location = new Point(boardspace.Right + 30, 110);
+            solvebutton.Location = new Point(boardspace.Right + 30, 190);
+            UPDATEBUTTON.Location = new Point(boardspace.Right + 30, 270);
+            this.Invalidate();
+        }
+        public static Size FitBoard(Size gamesize, Size maxboardsize, int drawfactor) //returns the largest rectangle smaller than MaxBoardSize that fits the given GameSize well
+        {
+            int TileLength = Math.Min(maxboardsize.Width / gamesize.Width, maxboardsize.Height / gamesize.Height) / drawfactor * drawfactor;
+            return new Size(gamesize.Width*TileLength, gamesize.Height*TileLength);
+            //after each of the divisions in this method, the value should be rounded down, 
+            //as the end value cannot exceed the size given by maxboardsize.
+            //however, C# rounds divisions of Int values down by default, so this does not have to be explicitly done.
+        }
+        private Point GetTile(Size gamesize, Rectangle r, Point p) //returns board coordinate at mouse position P of a Gamesize board drawn in R
+        {
+            Point res = this.PointToClient(p) - (Size)r.Location;
+            res.X /= (r.Width / gamesize.Width);
+            res.Y /= (r.Height / gamesize.Height);
+            return res;
+        }
+        public void Input(char c) //checks if a command binded to the keyboard key and runs it, affects tile that is hovered on if applicable
         {
-            generatebutton.Location = new Point(this.Width - 160, 30);
-            hintbutton.Location = new Point(this.Width - 160, 130);
-            solvebutton.Location = new Point(this.Width - 160, 230);
-            informationbox.Location = new Point(40, 30);
+            if (!"nhs[]1234567890".Contains(c)) return;
+            switch (c)
+            {
+                case 'n':
+                    return;
+                case 'h':
+                    MessageBox.Show("Hint: geef op");
+                    return;
+                case 's':
+                    return;
+
+            }
+            Point tile = GetTile(new Size(Board.boardState.GetLength(0), Board.boardState.GetLength(1)), boardspace, Control.MousePosition);
+            if (!(tile.X >= 0 && tile.X < Board.boardState.GetLength(0) && tile.Y >= 0 && tile.Y < Board.boardState.GetLength(1))) return;
+            if (c == '[' || c == ']') // '[' = 91, ']' = 93
+            {
+                //Board.TileClick(tile, (c - 91) / 2);
+                return;
+            }
+            if (char.GetNumericValue(c) != -1)
+            {
+                Board.TileInput(tile, (int)char.GetNumericValue(c));
+                return;
+            }
+            MessageBox.Show("uhoh");
         }
     }
 }