using System; using System.Collections.Generic; using System.Drawing; using System.Runtime.CompilerServices; namespace PuzzlePlayer_Namespace { /* The binair board consist of 1 and 0 * This means that the possible states a cell can be are: empty, one or zero * To specify this in an int[,] array we will use -1 for an empty space, * 0 for a space with a zero and 1 for a space with a one * The empty space is a constant defined in the abstract Board class */ internal class Binary : Board { // constructor with baordSize parameter (default is set to 8 but can be changed) public Binary(int boardSize = 8) { // create a board with the specifide size boardState = new int[boardSize,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"; // clear the board (fill it in with -1) Clear(); } public override void Draw (Graphics gr, Rectangle r) //draws board in rectangle R. warning: will stretch image unless FitBoard() is used for rectangle size { 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.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)(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)(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); } } } } private void Clear() { int size = boardState.GetLength(0); // fill the board with empty spaces (-1) for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) boardState[i, j] = emptySpace; } } /* this static methode returns true if the board is valid in a few steps 1: It checks if the size from boardToCheck is equal to the size from the boardState variable 2: it loops though the board and checks if one of the spaces contains something other than a -1,0 or 1 */ 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))) return false; // check if any of the spaces doesn't contain a -1,0 or 1 for(int i = 0;i < boardToCheck.GetLength(0);i++) { for(int j = 0; j < boardToCheck.GetLength(1);j++) { switch(boardToCheck[i,j]) { case -1: case 0: case 1: break; default: return false; } } } return true; } public override void Generate() { throw new NotImplementedException(); } protected override List<int[,]> GetSolveList(int[,] boardToSolve) { List<int[,]> result = new List<int[,]>(); for (int i = 0; i < boardToSolve.GetLength(0); i++) for (int j = 0; j < boardToSolve.GetLength(1); j++) { int[,] move = CheckMove(i, j, boardToSolve); if (move != null) result.Add(move); } return result; } private int[,] CheckMove(int x, int y, int[,] boardToSolve) { bool validForZero = false; bool validForOne = false; // empty check if (boardToSolve[x, y] != emptySpace) return null; // loop two times for checking 0 and 1 for (int i = 0; i <= 1; i++) { bool valid = false; // middle check valid = MiddleCheck(x, y, boardToSolve, i); // side check // even 1 and 0 in one row and colum } 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) { int opposite; if (checkFor == 0) opposite = 1; else opposite = 0; // first check if x-1 and x+1 aren't out of bounds // after that do the check if the move is valid if(!(x-1 < 0 || x+1 > b.GetLength(0))) if (b[x - 1, y] == opposite && b[x + 1, y] == opposite) return true; // same for y if (!(y - 1 < 0 || y + 1 > b.GetLength(1))) if (b[x, y - 1] == opposite && b[x, y + 1] == opposite) return true; // return false if nothing was found return false; } private bool SideCheck(int x, int y, int[,] b, int checkFor) { int opposite; if (checkFor == 0) opposite = 1; else opposite = 0; if (!(x - 2 < 0 || x + 2 > b.GetLength(0))) if ((b[x-2,y] == opposite && b[x-1,y] == opposite) || (b[x + 2, y] == opposite && b[x + 1, y] == opposite)) return true; if (!(y - 2 < 0 || y + 2 > b.GetLength(1))) if ((b[x, y - 2] == opposite && b[x, y - 1] == opposite) || (b[x, y + 2] == opposite && b[x, y + 1] == opposite)) return true; return false; } public override void TileInput(Point p, int x) { if (x==0 || x==1) boardState[p.X, p.Y] = x; } } }