Skip to content
Snippets Groups Projects
Commit 4503ca8c authored by bionic85's avatar bionic85
Browse files

Merge branch 'Binair'

parents 23f37f8a 6321af9f
No related branches found
Tags v1.32.3
No related merge requests found
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PuzzlePlayer_Namespace
{
internal class Binair : Board
{
public int[,] boardState { get; set; }
public static void Generate()
{
throw new NotImplementedException();
}
public static void Solve()
{
throw new NotImplementedException();
}
}
}
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 void Draw (Graphics gr, Point p, Size s)
{
for (int i = 0; i<boardState.GetLength(0); i++)
{
for(int j = 0; j<boardState.GetLength(1); j++)
{
gr.DrawRectangle(Pens.Beige, p.X+i*s.Width, p.Y+j*s.Height, s.Width, s.Height);
if (boardState[i,j] == 0)
{
gr.DrawEllipse(Pens.White,
(int)(p.X+((double)i+0.25)*s.Width),
(int)(p.Y+((double)j+0.25)*s.Height),
s.Width/2,s.Height/2);
return;
}
if (boardState[i, j] == 1)
{
gr.DrawEllipse(Pens.Black,
(int)(p.X + ((double)i + 0.25) * s.Width),
(int)(p.Y + ((double)j + 0.25) * s.Height),
s.Width / 2, s.Height / 2);
}
}
}
}
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);
{
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
}
}
// 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;
}
}
}
\ No newline at end of file
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection.Metadata;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace PuzzlePlayer_Namespace namespace PuzzlePlayer_Namespace
{ {
public interface Board public enum SOLUTIONS
{ {
int[,] boardState { get; set; } NONE = 0,
UNIQUE = 1,
MULTIPLE = 2
}
/*
* This abstract class can be used to implement any kind of puzzle
* One thing that is common for all puzzles is that a empty space is equal to -1
* GetSolveList and IsBoardValid need to be overwriten in a subclass of Board
*/
public abstract class Board
{
protected const int emptySpace = -1; // for every puzzle -1 represents a empty space
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
{
get { return boardState; }
set { setBoardState(value); }
}
// checks if the board is valid and solvable before setting the variable.
private bool setBoardState(int[,] newState)
{
int[,] copy = boardState;
boardState = newState;
if (IsBoardValid(newState) && Solve() == SOLUTIONS.UNIQUE)
return true;
else
{
boardState = copy;
return false;
}
}
// a methode for solving the whole board. It uses the private SolveStep methode untill the whole board is solved
public SOLUTIONS Solve()
{
// two variables for storing the result and the next solveStep
int[,] result = boardState;
int[,] step;
// keep looping until the SolveStep returns null
// if SolveStep returns null that could mean that either the whole board is solved or it is imposible to solve the board
while ((step = SolveStep(result)) != null)
{
result = step;
}
// check if the whole board is filled
// if not then the methode will return null because it is imposible to solve the board
for (int i = 0; i < result.GetLength(0); i++)
for (int j = 0; j < result.GetLength(1); j++)
if (result[i, j] == emptySpace)
{
return SOLUTIONS.NONE;
}
boardState = result;
return SOLUTIONS.UNIQUE;
}
// abstract methode for solving one step
private int[,] SolveStep(int[,] currentBoardState)
{
// get a list with all the possible moves
List<int[,]> moves = GetSolveList(currentBoardState);
// if there are no moves found then null is returned
if (moves.Count == 0)
return null;
// return one of the possible moves
// (if the first one is always chosen than that may lead to expected behavior. For example if the possible moves are checked in a certain order)
Random rnd = new Random();
return moves[rnd.Next(0, moves.Count - 1)];
}
// a abstract methode to get a list of all possible moves
protected abstract List<int[,]> GetSolveList(int[,] boardToSolve);
public abstract static void Solve(); // abstract methode for generating a random board
public abstract void Generate();
public abstract static void Generate(); // abstract methode for checking if a imputed boardstate is valid
public abstract bool IsBoardValid(int[,] boardToCheck);
} }
} }
...@@ -33,7 +33,7 @@ namespace PuzzlePlayer_Namespace ...@@ -33,7 +33,7 @@ namespace PuzzlePlayer_Namespace
private void SetUpPuzzleForms() private void SetUpPuzzleForms()
{ {
puzzleForms.Add(new PuzzleForm(new Binair())); puzzleForms.Add(new PuzzleForm(new Binary()));
} }
private void SetUpUI() private void SetUpUI()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment