From 952c717153ae7073749490c563bae3cedc565f5b Mon Sep 17 00:00:00 2001
From: bionic85 <144353436+bionic85@users.noreply.github.com>
Date: Thu, 21 Nov 2024 23:43:53 +0100
Subject: [PATCH] Started working on Binary board generator

---
 PuzzlePlayer/Binary.cs | 102 ++++++++++++++++++++---------------------
 PuzzlePlayer/Board.cs  |  20 ++++++--
 2 files changed, 67 insertions(+), 55 deletions(-)

diff --git a/PuzzlePlayer/Binary.cs b/PuzzlePlayer/Binary.cs
index e3f2f20..9befa72 100644
--- a/PuzzlePlayer/Binary.cs
+++ b/PuzzlePlayer/Binary.cs
@@ -17,10 +17,10 @@ namespace PuzzlePlayer_Namespace
     {
 
         // constructor with baordSize parameter (default is set to 8 but can be changed)
-        public Binary(int boardSize = 8)
+        public Binary(int boardSize = 8) : base(boardSize)
         {
             // create a clear board with the specifide size
-            boardState = GetClearBoard(boardSize);
+            setBoardState(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";
             
@@ -29,30 +29,30 @@ namespace PuzzlePlayer_Namespace
         public override void Draw (Graphics gr, Point p, Size s)
         {
             gr.FillRectangle(Brushes.Beige, p.X, p.Y, s.Width, s.Height);
-            for (int i = 0; i < boardState.GetLength(0); i++)
+            for (int i = 0; i < BoardState.GetLength(0); i++)
             {
-                for(int j = 0; j < boardState.GetLength(1); j++)
+                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));
-                    if (boardState[i,j] == 0)
+                        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));
+                    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)(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);
                     }
-                    if (boardState[i, j] == 1)
+                    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)(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);
                     }
                 }
             }
@@ -79,7 +79,7 @@ namespace PuzzlePlayer_Namespace
         public override bool IsBoardValid(int[,] boardToCheck)
         {
             // check if the size is NOT the same
-            if(!(boardToCheck.GetLength(0) ==  boardState.GetLength(0) && boardToCheck.GetLength(1) == boardState.GetLength(1)))
+            if(!(boardToCheck.GetLength(0) ==  BoardState.GetLength(0) && boardToCheck.GetLength(1) == BoardState.GetLength(1)))
                 return false;
                 
 
@@ -100,6 +100,8 @@ namespace PuzzlePlayer_Namespace
                 }
             }
 
+            //check if there aren't any
+
             return true;
         }
 
@@ -107,12 +109,30 @@ namespace PuzzlePlayer_Namespace
         public override void Generate()
         {
             // start with a clear board
-            int[,] result = GetClearBoard(boardState.GetLength(0));
+            int[,] result = GetClearBoard(BoardState.GetLength(0));
 
-            throw new NotImplementedException();
+            // keep adding stuff until it works?
+            while (!setBoardState(result))
+            {
+                //add random things until it works?
+                throw new NotImplementedException();
 
+            }
         }
 
+        // checks if the move is valid
+        private static bool IsValidMove(Move m, int[,] board)
+        {
+            int opposite;
+            if (m.changeTo == 0)
+                opposite = 1;
+            else
+                opposite = 0;
+
+            return MiddleCheck(m.x, m.y, board, opposite) ||
+                    SideCheck(m.x, m.y, board, opposite) ||
+                    EvenCheck(m.x, m.y, board, opposite);
+        }
         
 
         // gets a list with all the possible moves
@@ -143,39 +163,19 @@ namespace PuzzlePlayer_Namespace
             // loop two times for checking 0 and 1
             for (int i = 0; i <= 1; i++)
             {
-                int opposite;
-
-                if (i == 0)
-                    opposite = 1;
-                else
-                    opposite = 0;
-
-                // check if one of the checks succeded
-                bool valid = MiddleCheck(x, y, boardToSolve, opposite) ||
-                    SideCheck(x, y, boardToSolve, opposite) ||
-                    EvenCheck(x, y, boardToSolve, opposite);
-
-                if (i == 0)
-                    validForZero = valid;
-                else
-                    validForOne = valid;
-            }
+                Move m = new Move(x, y, i);
 
-            // if both 1 and 0 are valid then something went wrong
-            if (validForZero && validForOne)
-                return null;
+                // check if it is a valid move
+                if(IsValidMove(m, boardToSolve))
+                    return m;
+            }
 
-            // change the specifided place in a 0 or 1 if they are valid. if both are not valid then there is no valid move on the checked space and null is returnd.
-            if (validForZero)
-                return new Move(x, y, 0);
-            else if (validForOne)
-                return new Move(x, y, 1);
-            else
-                return null;
+            // if both 0 and 1 fail, then the move is invalid and null is returned
+            return null;
         }
 
         // check if the space is surrounded on both sides by the same number. If it is, the checked space should be the opposite number
-        private bool MiddleCheck(int x, int y, int[,] b, int checkFor)
+        private static bool MiddleCheck(int x, int y, int[,] b, int checkFor)
         {
             // first check if x-1 and x+1 aren't out of bounds
             // after that do the check if the move is valid
@@ -193,7 +193,7 @@ namespace PuzzlePlayer_Namespace
         }
 
         // check if the two spaces left, right, up or down of the space are the opposite number. if so return true
-        private bool SideCheck(int x, int y, int[,] b, int checkFor)
+        private static bool SideCheck(int x, int y, int[,] b, int checkFor)
         {
             //check the two spaces left
             if (x - 2 >= 0)
@@ -219,7 +219,7 @@ namespace PuzzlePlayer_Namespace
         }
 
         // every row and colom should have an even number of 1'boardSize and 0'boardSize. So if the total number of 1'boardSize in a row is equal to half the with of the row a 0 should be filled in.
-        private bool EvenCheck(int x, int y, int[,] b, int checkFor)
+        private static bool EvenCheck(int x, int y, int[,] b, int checkFor)
         {
             // check for a row and colum (provided that the width and height of the board is the same)
             int countRow = 0, countCol = 0;
diff --git a/PuzzlePlayer/Board.cs b/PuzzlePlayer/Board.cs
index 48faf26..a3d630e 100644
--- a/PuzzlePlayer/Board.cs
+++ b/PuzzlePlayer/Board.cs
@@ -41,15 +41,24 @@ namespace PuzzlePlayer_Namespace
         public string description;
 
         // a property for getting and setting the boardsstate. The boardstate should only be setted if the imputed int[,] is valid.
-        public int[,] boardState;
+        private int[,] boardState;
 
+        public int[,] BoardState
+        {
+            get { return boardState; }
+        }
+
+        public Board(int size)
+        {
+            boardState = new int[size,size];
+        }
 
         // 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)
+            if (IsBoardValid(newState) && Solve(true) == SOLUTIONS.UNIQUE)
                 return true;
             else
             {
@@ -58,8 +67,10 @@ namespace PuzzlePlayer_Namespace
             }
         }
         public abstract void Draw(Graphics gr, Point p, Size s);
+
         // a methode for solving the whole board. It uses the private SolveStep methode untill the whole board is solved
-        public SOLUTIONS Solve()
+        // it has one parameter. setting this to true will only give a return value without changing the current boardState
+        public SOLUTIONS Solve(bool CheckOnly)
         {
             // two variables for storing the result and the next solveStep
             int[,] result = boardState;
@@ -84,7 +95,8 @@ namespace PuzzlePlayer_Namespace
                         return SOLUTIONS.NONE;
                     }
 
-            boardState = result;
+            if(!CheckOnly)
+                boardState = result;
             return SOLUTIONS.UNIQUE;
         }
 
-- 
GitLab