From 0e41261ff0e644c1b4482f293722404e5fda2253 Mon Sep 17 00:00:00 2001
From: Floris <f.k.h.vandezande@students.uu.nl>
Date: Sun, 5 Jan 2025 18:22:27 +0100
Subject: [PATCH] added minesweeper

---
 PuzzlePlayer/Board.cs        |   7 +-
 PuzzlePlayer/Minesweeper.cs  | 145 +++++++++++++++++++++++++++++++++++
 PuzzlePlayer/PuzzleForm.cs   |   4 +-
 PuzzlePlayer/PuzzlePlayer.cs |   2 +-
 4 files changed, 154 insertions(+), 4 deletions(-)
 create mode 100644 PuzzlePlayer/Minesweeper.cs

diff --git a/PuzzlePlayer/Board.cs b/PuzzlePlayer/Board.cs
index 40c3079..0be6bef 100644
--- a/PuzzlePlayer/Board.cs
+++ b/PuzzlePlayer/Board.cs
@@ -100,7 +100,12 @@ namespace PuzzlePlayer_Namespace
         public virtual Point Hint() { return new Point(0, 0); }
 
         // a abstract methode to get a list of all possible moves
-        protected abstract List<Move> GetSolveList(int[,] boardToSolve); 
+        protected virtual List<Move> GetSolveList(int[,] boardToSolve)
+        {
+            List<Move> result = new List<Move>();
+
+            return result;
+        }
 
         // abstract methode for generating a random board
         public abstract void Generate();
diff --git a/PuzzlePlayer/Minesweeper.cs b/PuzzlePlayer/Minesweeper.cs
new file mode 100644
index 0000000..ce7dabe
--- /dev/null
+++ b/PuzzlePlayer/Minesweeper.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.DirectoryServices;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace PuzzlePlayer_Namespace
+{
+    internal class Minesweeper : Board
+    {
+
+        private static Random random = new Random();
+        private bool[,] mineState;
+        private bool isFirstClick;
+        public Minesweeper(int width = 30, int height = 16)
+        {
+            if (width <= 1 || height <= 1) throw new ArgumentOutOfRangeException(); 
+            boardState = GetClearBoard(width, height);
+            lastGeneratedBoard = GetClearBoard(width, height);
+            mineState = new bool[width, height];
+            isFirstClick = false;
+
+            description = "zoek het uit";
+            drawFactor = 1;
+
+        }
+
+        public override void Draw(Graphics gr, Rectangle r)
+        {
+            Size tilesize = new Size(r.Width / boardState.GetLength(0), r.Height / boardState.GetLength(1));
+            int stringsize = Math.Min(tilesize.Height / 2, tilesize.Width);
+            StringFormat stringFormat = new StringFormat();
+            stringFormat.LineAlignment = StringAlignment.Center;
+            stringFormat.Alignment = StringAlignment.Center;
+            gr.FillRectangle(Brushes.DarkSlateGray, r);
+            for (int i = 0; i < boardState.GetLength(0); i++)
+            {
+                for (int j = 0; j < boardState.GetLength(1); j++)
+                {
+                    string text = "";
+                    if (boardState[i,j] >= 0)
+                    {
+                        gr.FillRectangle(Brushes.SlateGray,
+                        r.X + i * tilesize.Width,
+                        r.Y + j * tilesize.Height,
+                        tilesize.Width,
+                        tilesize.Height);
+                        if (boardState[i, j] != 0) text = Convert.ToString(boardState[i, j]);
+                    } 
+                    else
+                    {
+                        if (boardState[i,j] == -2) text = "🚩";
+                        if (boardState[i, j] == -3) text = "X";
+                    }
+                    gr.DrawString(text,
+                    new Font("Verdana", stringsize),
+                    Brushes.Black,
+                    (int)(r.X + ((double)i + 0.5) * tilesize.Width),
+                    (int)(r.Y + ((double)j + 0.5) * tilesize.Height),
+                    stringFormat);
+
+                    gr.DrawRectangle(Pens.DarkGray,
+                    r.X + i * tilesize.Width,
+                    r.Y + j * tilesize.Height,
+                    tilesize.Width,
+                    tilesize.Height);
+                }
+            }
+        }
+
+        public override void Generate()
+        {
+            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;
+                }
+            isFirstClick = true;
+        }
+
+        public override SOLUTIONS Solve(bool b)
+        {
+            return SOLUTIONS.UNIQUE;
+        }
+        public override bool TileInput(Point? p, Keys k)
+        {
+            return false;
+        }
+        public override bool TileClick(Point p, int x)
+        {
+            if (x == 0)
+            {
+                if (boardState[p.X, p.Y] == emptySpace) return Reveal(p);
+                if (boardState[p.X, p.Y] > 0) return Chord(p);
+            }
+            else
+            {
+                if (-3 < boardState[p.X, p.Y] && boardState[p.X, p.Y] < 0) boardState[p.X, p.Y] = -3 - boardState[p.X, p.Y];
+            }
+            return false;
+
+            bool Reveal(Point p)
+            {
+                if (boardState[p.X, p.Y] != emptySpace) return false;
+                if (mineState[p.X, p.Y])
+                {
+                    if (isFirstClick)
+                    {
+                        isFirstClick = false;
+                        mineState[p.X, p.Y] = false;
+                        return Reveal(p);
+                    }
+                    boardState[p.X, p.Y] = -3;
+                    return 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)); } }
+                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);
+                return IsBoardSolved();
+            }
+
+            bool Chord(Point p)
+            {
+                return false;
+            }
+        }
+
+        public override bool IsBoardSolved()
+        {
+            for (int i = 0; i < boardState.GetLength(0); i++) for (int j = 0; j < boardState.GetLength(1); j++) if (boardState[i, j] == emptySpace && !mineState[i, j]) return false;
+            return true;
+        }
+    }
+}
diff --git a/PuzzlePlayer/PuzzleForm.cs b/PuzzlePlayer/PuzzleForm.cs
index 84e3002..2f0bf48 100644
--- a/PuzzlePlayer/PuzzleForm.cs
+++ b/PuzzlePlayer/PuzzleForm.cs
@@ -162,7 +162,7 @@ namespace PuzzlePlayer_Namespace
                 this.Invalidate();
             };
 
-            CreateButton(UPDATEBUTTON);
+            //CreateButton(UPDATEBUTTON);
             UPDATEBUTTON.Text = "Update";
             UPDATEBUTTON.Font = new Font("Verdana", 11, FontStyle.Bold);
             UPDATEBUTTON.FlatAppearance.BorderColor = UPDATEBUTTON.BackColor = Color.Pink;
@@ -257,7 +257,7 @@ namespace PuzzlePlayer_Namespace
                     return;
                 case Keys.LButton:
                 case Keys.RButton:
-                    if (Board.TileInput(null, k)) Win();
+                    if (Board.TileClick(tile, (int)k - 1)) Win();
                     this.Invalidate();
                     return;
                 case Keys.OemOpenBrackets:
diff --git a/PuzzlePlayer/PuzzlePlayer.cs b/PuzzlePlayer/PuzzlePlayer.cs
index b9d14b8..cb920c4 100644
--- a/PuzzlePlayer/PuzzlePlayer.cs
+++ b/PuzzlePlayer/PuzzlePlayer.cs
@@ -10,7 +10,7 @@ namespace PuzzlePlayer_Namespace
     {
         internal static void Main(string[] args)
         {
-            Application.Run(new MainForm());
+            Application.Run(new PuzzleForm(new Minesweeper()));
         }
     }
 
-- 
GitLab