diff --git a/PuzzlePlayer/Board.cs b/PuzzlePlayer/Board.cs
index bab69e95c2da32ba0f8244fdb9fc065cb6fa7a30..caefc517f6c8e48972453b7f1ebe3a5b0aae6b8c 100644
--- a/PuzzlePlayer/Board.cs
+++ b/PuzzlePlayer/Board.cs
@@ -126,7 +126,7 @@ namespace PuzzlePlayer_Namespace
         }
 
         // changes tile P to value X
-        public abstract bool TileInput(Point? p, Keys k);
+        public virtual bool TileInput(Point? p, Keys k) { return false; }
 
         // performs a left/right (X) click on tile P, changing its value
         public virtual bool TileClick(Point p, int x) { return false; }
diff --git a/PuzzlePlayer/Maze.cs b/PuzzlePlayer/Maze.cs
index f1afe6fdfa2ea6b7be3374f33a0cf18c324088d6..a7d0467483b4d900990f9172bf1df0779541292e 100644
--- a/PuzzlePlayer/Maze.cs
+++ b/PuzzlePlayer/Maze.cs
@@ -40,14 +40,14 @@ namespace PuzzlePlayer_Namespace
         Point playerPos;
         List<Point> shortestPath;
 
-        public Maze(int sizeX = 6, int sizeY = 4)
+        public Maze(int sizeX = 32, int sizeY = 24)
         {
             drawFactor = 1;
             // init all 2D array's
             Reset(sizeX, sizeY);
             lastGeneratedBoard = GetClearBoard(sizeX, sizeY);
 
-            description = "Maze is played on a grid containing walls. You need to navigate through the maze until you reach the end. Use the arrow keys or WASD to move the blue square to the end goal";
+            description = "Maze is played on a grid containing walls. You have to navigate through the maze until you reach the end. Use the arrow keys or WASD to move the blue square to the end!";
         }
 
         private void Reset(int sizeX, int sizeY)
diff --git a/PuzzlePlayer/Minesweeper.cs b/PuzzlePlayer/Minesweeper.cs
index 06422e78007015ff993eaeb776dd8a49491ebd54..23a5249607404c9639144713b7601926332b11ef 100644
--- a/PuzzlePlayer/Minesweeper.cs
+++ b/PuzzlePlayer/Minesweeper.cs
@@ -14,9 +14,9 @@ namespace PuzzlePlayer_Namespace
     {
 
         private static Random random = new Random();
-        private bool[,] mineState;
+        private bool[,] mineState; 
         private bool isFirstClick;
-        public Minesweeper(int width = 6, int height = 6)
+        public Minesweeper(int width = 16, int height = 12)
         {
             if (width <= 1 || height <= 1) throw new ArgumentOutOfRangeException(); // breedte 1 mag niet door optimisatie bij Reveal()
             boardState = GetClearBoard(width, height);
@@ -24,7 +24,7 @@ namespace PuzzlePlayer_Namespace
             mineState = new bool[width, height];
             isFirstClick = false;
 
-            description = "zoek het uit";
+            description = "In Minesweeper, the number of a tile indicates the amount of adjacent mines.\r\n● You can place flags on suspected mines with right-click\r\n● Unlike the classic version of minesweeper, there is not a set number of mines and you will survive after clicking on a mine, at the cost of gaining less points \r\n● The first click is always safe!";
             drawFactor = 1;
 
         }
@@ -71,7 +71,7 @@ namespace PuzzlePlayer_Namespace
                             case -2:
                                 gr.DrawString("âš‘",
                                 new Font("Verdana", stringsize),
-                                Brushes.Black,
+                                Brushes.DarkRed,
                                 (int)(r.X + ((double)i + 0.5) * tilesize.Width),
                                 (int)(r.Y + ((double)j + 0.5) * tilesize.Height),
                                 stringFormat);
@@ -81,13 +81,26 @@ namespace PuzzlePlayer_Namespace
                                 gr.DrawString("✸",
                                 new Font("Verdana", stringsize),
                                 Brushes.Black,
-                                (int)(r.X + ((double)i + 0.5) * tilesize.Width),
-                                (int)(r.Y + ((double)j + 0.5) * tilesize.Height),
+                                (int)(r.X + ((double)i + 0.52) * tilesize.Width),
+                                (int)(r.Y + ((double)j + 0.54) * tilesize.Height),
                                 stringFormat);
                                 break;
                         }
                     }
 
+                    /*gr.DrawLine(Pens.Red,
+                        (int)(r.X + ((double)i + 0.5) * tilesize.Width),
+                        (int)(r.Y + ((double)j + 0.0) * tilesize.Height),
+                        (int)(r.X + ((double)i + 0.5) * tilesize.Width),
+                        (int)(r.Y + ((double)j + 1.0) * tilesize.Height)
+                        );
+                    gr.DrawLine(Pens.Red,
+                        (int)(r.X + ((double)i + 0.0) * tilesize.Width),
+                        (int)(r.Y + ((double)j + 0.5) * tilesize.Height),
+                        (int)(r.X + ((double)i + 1.0) * tilesize.Width),
+                        (int)(r.Y + ((double)j + 0.5) * tilesize.Height) 
+                        );*/
+
                     gr.DrawRectangle(Pens.DarkGray,
                     r.X + i * tilesize.Width,
                     r.Y + j * tilesize.Height,
@@ -102,7 +115,7 @@ namespace PuzzlePlayer_Namespace
             boardState = GetClearBoard(mineState.GetLength(0), mineState.GetLength(1));
             for (int i = 0; i < mineState.GetLength(0); i++) for (int j = 0; j < mineState.GetLength(1); j++)
                 {
-                    mineState[i, j] = random.Next(6) == 0; // het getal P in de Next methode geeft elke tile een 1/P kans om een bom te zijn
+                    mineState[i, j] = random.Next(6) == 0; // the number P, the Next method parameter indicates that there is a 1/P chance for a tile to have a mine
                 }
             isFirstClick = true;
         }
@@ -111,10 +124,6 @@ namespace PuzzlePlayer_Namespace
         {
             return SOLUTIONS.UNIQUE;
         }
-        public override bool TileInput(Point? p, Keys k)
-        {
-            return false;
-        }
         public override bool TileClick(Point p, int x)
         {
             if (x == 0)
@@ -128,7 +137,7 @@ namespace PuzzlePlayer_Namespace
             }
             return false;
 
-            bool Reveal(Point p, bool ForceOpen)
+            bool Reveal(Point p, bool ForceOpen) //opens the cell at the given Point and returns whether or not the game is finished after reveal. ForceOpen dictates whether or not the cell should be opened if a flag has been placed on it.
             {
                 if (ForceOpen && boardState[p.X, p.Y] == -2) { boardState[p.X, p.Y] = emptySpace; Reveal(p, false); }
                 if (boardState[p.X, p.Y] != emptySpace) return false;
@@ -144,21 +153,35 @@ namespace PuzzlePlayer_Namespace
                     return false;
                 } else { if (isFirstClick) isFirstClick = false; }
                 int result = 0;
-                List<Size> directions = new List<Size> { new(-1, -1), new(0, -1), new(1, -1), new(-1, 0),
-                                                        new(1, 0), new(-1, 1), new(0, 1), new(1, 1)};
-                if (p.X == 0) { directions.Remove(new(-1, -1)); directions.Remove(new(-1, 0)); directions.Remove(new(-1, 1)); }
-                else { if (p.X == boardState.GetLength(0) - 1) { directions.Remove(new(1, -1)); directions.Remove(new(1, 0)); directions.Remove(new(1, 1)); } }
-                if (p.Y == 0) { directions.Remove(new(-1, -1)); directions.Remove(new(0, -1)); directions.Remove(new(1, -1)); }
-                else { if (p.Y == boardState.GetLength(1) - 1) { directions.Remove(new(-1, 1)); directions.Remove(new(0, 1)); directions.Remove(new(1, 1)); } }
+                List<Size> directions = GetAdjacents(p);
                 foreach (Size s in directions) if (mineState[(p + s).X, (p + s).Y]) result++;
                 boardState[p.X, p.Y] = result;
                 if (result == 0) foreach (Size s in directions) Reveal(p + s, true);
                 return IsBoardSolved();
             }
 
-            bool Chord(Point p)
+            bool Chord(Point p) //attempts to execute a "chord" on cell P, assumes P is legal to "chord" on, but behaves normally if not legal anyway
+            {
+                List<Size> directions = GetAdjacents(p);
+                int adjacents = directions.Count;
+                for (int i = 0; i < directions.Count; i++)
+                {
+                    Point cell = p + directions[i];
+                    if (boardState[cell.X, cell.Y] == -2 || boardState[cell.X, cell.Y] == -3) { directions.RemoveAt(i); i--; }
+                }
+                if (adjacents - directions.Count == boardState[p.X, p.Y]) { foreach (Size s in directions) Reveal(p + s, true); return IsBoardSolved(); }
+                else return false;
+            }
+
+            List<Size> GetAdjacents(Point p) //returns direction vectors that point to all valid neighbors of cell P
             {
-                return false;
+                List<Size> res = new List<Size> { new(-1, -1), new(0, -1), new(1, -1), new(-1, 0),
+                                                        new(1, 0), new(-1, 1), new(0, 1), new(1, 1)};
+                if (p.X == 0) { res.Remove(new(-1, -1)); res.Remove(new(-1, 0)); res.Remove(new(-1, 1)); }
+                else { if (p.X == boardState.GetLength(0) - 1) { res.Remove(new(1, -1)); res.Remove(new(1, 0)); res.Remove(new(1, 1)); } }
+                if (p.Y == 0) { res.Remove(new(-1, -1)); res.Remove(new(0, -1)); res.Remove(new(1, -1)); }
+                else { if (p.Y == boardState.GetLength(1) - 1) { res.Remove(new(-1, 1)); res.Remove(new(0, 1)); res.Remove(new(1, 1)); } }
+                return res;
             }
         }
 
diff --git a/PuzzlePlayer/Properties/Settings.Designer.cs b/PuzzlePlayer/Properties/Settings.Designer.cs
index 38a04c7c48d469a2fdf8ee52617acff3610b14a9..9013f5f267c41831d6319a4e6bd7123d7aab45af 100644
--- a/PuzzlePlayer/Properties/Settings.Designer.cs
+++ b/PuzzlePlayer/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace PuzzlePlayer_Namespace.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.11.0.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.12.0.0")]
     internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
         
         private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/PuzzlePlayer/PuzzleForm.cs b/PuzzlePlayer/PuzzleForm.cs
index 7b9284d00aae6f6d124d0dd28221b681361abbb1..dc9104166bdcbc58d71feae511ac25c4517b1a76 100644
--- a/PuzzlePlayer/PuzzleForm.cs
+++ b/PuzzlePlayer/PuzzleForm.cs
@@ -55,13 +55,7 @@ namespace PuzzlePlayer_Namespace
             titlebox = new Label();
             informationbox = new Label();
             boardspace = new Rectangle(220, 55, 400, 400);
-            this.Paint += (object o, PaintEventArgs pea) =>
-            {
-                board.Draw(bufferedGraphics.Graphics, boardspace);
-                //bufferedGraphics.Graphics.FillRectangle(Brushes.LightCoral, boardspace.X, boardspace.Y, this.Width - 350, this.Height - 125);
-                //bufferedGraphics.Graphics.FillRectangle(Brushes.DarkRed, boardspace);
-                bufferedGraphics.Render();
-            };
+            this.Paint += (object o, PaintEventArgs pea) => Draw();
             this.Resize += (object o, EventArgs ea) => UpdateUI();
             this.Move += (object o, EventArgs ea) => this.Focus();
             this.PreviewKeyDown += (object o, PreviewKeyDownEventArgs e) => e.IsInputKey = true;
@@ -80,6 +74,13 @@ namespace PuzzlePlayer_Namespace
             CreateUI();
         }
 
+        private void Draw()
+        {
+            board.Draw(bufferedGraphics.Graphics, boardspace);
+            //bufferedGraphics.Graphics.FillRectangle(Brushes.LightCoral, boardspace.X, boardspace.Y, this.Width - 350, this.Height - 125);
+            //bufferedGraphics.Graphics.FillRectangle(Brushes.DarkRed, boardspace);
+            bufferedGraphics.Render();
+        }
         private void CreateUI() //sets up ui elements
         {
             MenuStrip menuStrip = new MenuStrip
@@ -140,28 +141,29 @@ namespace PuzzlePlayer_Namespace
             generatebutton.MouseClick += (object sender, MouseEventArgs mea) => 
             {
                 Board.Generate();
-                this.Invalidate();
+                Draw();
             };
             CreateButton(hintbutton);
             hintbutton.Text = "Hint";
             hintbutton.MouseClick += (object sender, MouseEventArgs mea) =>
             {
                 MessageBox.Show("Hint: geef op");
-                this.Invalidate();
+                Draw();
             };
             CreateButton(solvebutton);
             solvebutton.Text = "Solve";
             solvebutton.MouseClick += (object sender, MouseEventArgs mea) =>
             {
                 Board.Solve(false);
-                this.Invalidate();
+                if (Board.IsBoardSolved()) Win();
+                Draw();
             };
             CreateButton(restartbutton);
             restartbutton.Text = "Restart";
             restartbutton.MouseClick += (object sender, MouseEventArgs mea) =>
             {
                 Board.Restart();
-                this.Invalidate();
+                Draw();
             };
 
             //CreateButton(UPDATEBUTTON);
@@ -208,7 +210,7 @@ namespace PuzzlePlayer_Namespace
         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(Math.Max(6,gamesize.Width*TileLength), Math.Max(6,gamesize.Height*TileLength)); //dw dw
+            return new Size(Math.Max(2*gamesize.Width,gamesize.Width*TileLength), Math.Max(2*gamesize.Height,gamesize.Height*TileLength)); //dw dw
             //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.
@@ -230,11 +232,11 @@ namespace PuzzlePlayer_Namespace
                     return;
                 case Keys.H:
                     MessageBox.Show("Hint: geef op");
-                    this.Invalidate();
+                    Draw();
                     return;
                 case Keys.Space:
                     Board.Solve(false);
-                    this.Invalidate();
+                    Draw();
                     return;
                 case Keys.Up:
                 case Keys.Left:
@@ -245,7 +247,7 @@ namespace PuzzlePlayer_Namespace
                 case Keys.S:
                 case Keys.D:
                     if (Board.TileInput(null, k)) Win();
-                    this.Invalidate();
+                    Draw();
                     return;
             }
             Point tile = GetTile(new Size(Board.boardState.GetLength(0), Board.boardState.GetLength(1)), boardspace, Control.MousePosition);
@@ -255,28 +257,28 @@ namespace PuzzlePlayer_Namespace
             {
                 case Keys.Back:
                     Board.boardState[tile.X, tile.Y] = Board.emptySpace;
-                    this.Invalidate();
+                    Draw();
                     return;
                 case Keys.LButton:
                 case Keys.RButton:
                     if (Board.TileClick(tile, (int)k - 1)) Win();
-                    this.Invalidate();
+                    Draw();
                     return;
                 case Keys.OemOpenBrackets:
                 case Keys.OemCloseBrackets:
                     if (Board.TileClick(tile, ((int)k - 219)/2)) Win();
-                    this.Invalidate();
+                    Draw();
                     return;
                 default:
                     if (Board.TileInput(tile, k)) Win();
-                    this.Invalidate();
+                    Draw();
                     return;
             }
         }
 
         public void Win()
         {
-            this.Invalidate();
+            Draw();
             MessageBox.Show("oi oi oi");
         }
     }
diff --git a/PuzzlePlayer/PuzzlePlayer.cs b/PuzzlePlayer/PuzzlePlayer.cs
index b1336b8492e5a5dd6d218ec0297caf5b53aa1c8a..b516283e058b5eab1c4a3968cc2a0d59b4ad2485 100644
--- a/PuzzlePlayer/PuzzlePlayer.cs
+++ b/PuzzlePlayer/PuzzlePlayer.cs
@@ -11,7 +11,6 @@ namespace PuzzlePlayer_Namespace
     {
         internal static void Main(string[] args)
         {
-            //Application.Run(new ShopMenu());
             Application.Run(new MainForm());
         }
     }
diff --git a/PuzzlePlayer/Sudoku.cs b/PuzzlePlayer/Sudoku.cs
index e2424492c560e38f045d5857ebff38c792f281d5..85184d1e3b46831fd8e0f025141992e666f88c23 100644
--- a/PuzzlePlayer/Sudoku.cs
+++ b/PuzzlePlayer/Sudoku.cs
@@ -12,8 +12,8 @@ namespace PuzzlePlayer_Namespace
 {
     internal class Sudoku : Board
     {
-        private static int boardLength;
-        private static int rootBoardLength;
+        private readonly int boardLength;
+        private readonly int rootBoardLength;
         private static Random random = new Random();
         private double removeDensity = 0.5;
         public Sudoku(int boardSize = 4)
@@ -37,44 +37,32 @@ namespace PuzzlePlayer_Namespace
             };
             Size tilesize = new Size(r.Width / boardState.GetLength(0), r.Height / boardState.GetLength(1));
             Pen border = new Pen(Color.Black, 2);
+            Brush textcolor;
             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.LightGray,
                         r.X + i * tilesize.Width,
                         r.Y + j * tilesize.Height,
                         tilesize.Width,
                         tilesize.Height);
 
-                    if (boardState[i,j] != -1)
+                    if (boardState[i,j] != emptySpace)
                     {
-                        if (lastGeneratedBoard[i, j] != Board.emptySpace)
-                        {
-                            gr.DrawString(
-                                (boardState[i, j]).ToString(),
-                                new Font("Arial", tilesize.Width / 2),
-                                Brushes.Black,
-                                (int)(r.X + (i + 0.27) * tilesize.Width + tilesize.Width / 4),
-                                (int)(r.Y + (j + 0.33) * tilesize.Height + tilesize.Height / 4),
-                                format);
-                        } 
-                        else
-                        {
-                            gr.DrawString(
-                                (boardState[i, j]).ToString(),
-                                new Font("Arial", tilesize.Width / 2),
-                                Brushes.DarkBlue,
-                                (int)(r.X + (i + 0.27) * tilesize.Width + tilesize.Width / 4),
-                                (int)(r.Y + (j + 0.33) * tilesize.Height + tilesize.Height / 4),
-                                format);
-                        }
+                        if (lastGeneratedBoard[i, j] == Board.emptySpace) textcolor = Brushes.DarkBlue; else textcolor = Brushes.Black;
+                        gr.DrawString(
+                        (boardState[i, j]).ToString(),
+                        new Font("Arial", tilesize.Width / 2),
+                        textcolor,
+                        (int)(r.X + (i + 0.52) * tilesize.Width),
+                        (int)(r.Y + (j + 0.54) * tilesize.Height),
+                        format);
                     }
                 }
             }
-            for (int i = 1; i < Math.Sqrt(boardState.GetLength(0)); i++)
+            for (int i = 1; i < Math.Sqrt(boardState.GetLength(0)); i++) //draws box lines
             {
                 gr.DrawLine(Pens.Black,
                     r.X + i * (int)Math.Sqrt((double)boardState.GetLength(0)) * tilesize.Width,
@@ -184,7 +172,7 @@ namespace PuzzlePlayer_Namespace
         {
             for (int i = 0; i < boardLength; i++)
             {
-                if(num == boardState[i, j])
+                if( num == boardState[i, j])
                 {
                     return true;
                 }
@@ -265,7 +253,7 @@ namespace PuzzlePlayer_Namespace
             if (p == null) return false;
             int num = (int)k - 48;
             if (num >= 1 && num <= boardLength) boardState[((Point)p).X, ((Point)p).Y] = num;
-            return false;
+            return IsBoardSolved();
         }
         public override bool TileClick(Point p, int x)
         {
@@ -317,6 +305,33 @@ namespace PuzzlePlayer_Namespace
             }
         }
 
+        public override bool IsBoardSolved()
+        {
+            foreach (int n in boardState) if (n == emptySpace) return false; //first checks if all squares have been filled to prevent algoritm from requiring extra checks and running after each input
+
+            for (int i = 0; i < boardLength; i++) // simultaneous row/column check
+            {
+                HashSet<int> SetColumn = [];
+                HashSet<int> SetRow = []; 
+                for (int j = 0; j < boardLength; j++)
+                {
+                    if (!SetColumn.Add(boardState[i, j])) return false;
+                    if (!SetRow.Add(boardState[j, i])) return false;
+                }
+            }
+
+            for (int i = 0; i < rootBoardLength; i++) for (int j = 0; j < rootBoardLength; j++)  //box check
+                {
+                    HashSet<int> Set = [];
+                    for (int a = 0; a < rootBoardLength; a++) for (int b = 0; b < rootBoardLength; b++)
+                        {
+                            if (!Set.Add(boardState[i * rootBoardLength + a, j * rootBoardLength + b])) return false;
+                        }
+                }
+
+            return true;
+        }
+
         private void RemoveSpaces(int k)
         {
             for(int i = 0; i < k; i++)