public virtual BoardStatus? CheckForWinner(IBoardCells boardCells) { foreach (var combination in _winningCombinations) { var firstCell = boardCells.GetCell(combination[0]); //if one cell of the combination is empty, it can't be part of a winning combination - move on if (firstCell == PieceType.Neither) continue; //if all three cells have the same non-empty value, we have a winner if ( boardCells.GetCell(combination[1]) == firstCell && boardCells.GetCell(combination[2]) == firstCell ) { return firstCell == PieceType.Nought ? BoardStatus.NoughtsWins : BoardStatus.CrossesWins; } } //no winning combination found return null; }
public virtual BoardStatus?CheckForWinner(IBoardCells boardCells) { foreach (var combination in _winningCombinations) { var firstCell = boardCells.GetCell(combination[0]); //if one cell of the combination is empty, it can't be part of a winning combination - move on if (firstCell == PieceType.Neither) { continue; } //if all three cells have the same non-empty value, we have a winner if ( boardCells.GetCell(combination[1]) == firstCell && boardCells.GetCell(combination[2]) == firstCell ) { return(firstCell == PieceType.Nought ? BoardStatus.NoughtsWins : BoardStatus.CrossesWins); } } //no winning combination found return(null); }
public Board(IBoardCells boardCells, IBoardWinningRules boardWinningRules, IBoardRenderer boardRenderer) { _boardCells = boardCells; _boardRenderer = boardRenderer; _boardWinningRules = boardWinningRules; _random = new Random(DateTime.Now.Millisecond); //seed is current time's milliseconds, which is a simple way to get a random number _boardSize = _boardCells.Size(); }
public BoardCells(IBoardCells boardCells) { if (boardCells == null) { throw new ArgumentNullException(nameof(boardCells)); } Board = boardCells.Board; Rows = boardCells.Rows; Columns = boardCells.Columns; Squares = boardCells.Squares; BoardCells other = (BoardCells)boardCells; if(other != null) { _squaresData = other._squaresData; } }
public MoveResult(IBoardCells board, List<IMove> movesPlayed, List<Cell> cellMoves) : this(board,movesPlayed, (List<IMove>)null) { MovesRemaining = new List<IMove>(); if(cellMoves != null) { foreach(var cell in cellMoves) { if (cell.Moves != null) { foreach (var move in cell.Moves) { MovesRemaining.Add(move); } } } } }
public string RenderAsText(IBoardCells boardCells) { Func <int, char> cell = x => _renderLookup[boardCells.GetCell(x)]; return(string.Format( " {0} | {1} | {2} \n" + "-----------\n" + " {3} | {4} | {5} \n" + "-----------\n" + " {6} | {7} | {8} \n", cell(0), cell(1), cell(2), cell(3), cell(4), cell(5), cell(6), cell(7), cell(8) )); }
public string RenderAsText(IBoardCells boardCells) { Func<int, char> cell = x => _renderLookup[boardCells.GetCell(x)]; return string.Format( " {0} | {1} | {2} \n" + "-----------\n" + " {3} | {4} | {5} \n" + "-----------\n" + " {6} | {7} | {8} \n", cell(0), cell(1), cell(2), cell(3), cell(4), cell(5), cell(6), cell(7), cell(8) ); }
public List<Cell> FindMoves(IBoardCells boardCells) { if (boardCells.Board.MovesRemaining == null) { var moves = new List<Cell>(); // visit each cell and get available moves for (int row = 0; row < boardCells.Board.Size; row++) { for (int col = 0; col < boardCells.Board.Size; col++) { var cellMoves = GetMovesForCell(boardCells, row, col); if (cellMoves.Moves.Count > 0) { moves.Add(cellMoves); } } } boardCells.Board.MovesRemaining = moves; } return boardCells.Board.MovesRemaining; }
public override IScore GetColScore(IBoardCells board, int col) { int numMoves = 0; int numEmptyCells = 0; for (int row = 0; row < board.Board.Size; row++) { var cell = MoveFinder.GetMovesForCell(board, row, col); if (cell.Moves != null) { numMoves += cell.Moves.Count; } if (board.Board[row, col] == 0) { numEmptyCells++; } } if (numEmptyCells == 0) { return Score.SolvedRegionScore; } return new MultiPartScore(new double[] { -numMoves, numEmptyCells }); }
public override IScore GetRowScore(IBoardCells board, int row) { // row score = #-1*empty cells.#total moves in row gd int numMoves = 0; int numEmptyCells = 0; for (int col = 0; col < board.Board.Size; col++) { var cell = MoveFinder.GetMovesForCell(board, row, col); if (cell.Moves != null && cell.Moves.Count > 0) { numMoves += cell.Moves.Count; } if (board.Board[row, col] == 0) { numEmptyCells++; } } if (numEmptyCells == 0) { return Score.SolvedRegionScore; } return new MultiPartScore(new double[] { -numMoves, numEmptyCells }); }
public Cell GetMovesForCell(IBoardCells boardCells, int row, int col) { List<IMove> moves = new List<IMove>(); if (boardCells.Board[row, col] == 0) { int[] availableNumbers = new int[boardCells.Board.Size]; for (int i = 0; i < boardCells.Board.Size; i++) { availableNumbers[i] = i + 1; } foreach (int num in boardCells.GetRowForCell(row, col)) { if (num == 0) { continue; } availableNumbers[num - 1] = 0; } foreach (int num in boardCells.GetColumnForCell(row, col)) { if (num == 0) { continue; } availableNumbers[num - 1] = 0; } foreach (int num in boardCells.GetSquareForCell(row, col)) { if (num == 0) { continue; } availableNumbers[num - 1] = 0; } foreach (int num in availableNumbers) { if (num == 0) { continue; } moves.Add(new Move(boardCells.Board, row, col, num)); } // if there is only one move for a cell then it's forced if (moves.Count == 1) { moves[0].IsForcedMove = true; } } return new Cell(row, col, moves); }
public MoveResult(IBoardCells board, List<IMove> movesPlayed, List<IMove> movesRemaining) { CurrentBoard = board; MovesPlayed = movesPlayed; MovesRemaining = movesRemaining; }
/// <summary> /// Will play all forced moves. The result returned will be the resulting /// board and an unsorted move list which does not have any forced moves. /// </summary> protected MoveResult PlayForcedMoves(IBoardCells board, List<IMove> moves,IList<IMove>previousMovesPlayed) { IBoard playboard = board.Board; List<IMove> movesPlayed = new List<IMove>(); if(previousMovesPlayed != null) { movesPlayed.AddRange(previousMovesPlayed); } List<IMove> forcedMoves = GetForcedMoves(moves); IBoardCells playboardCells = new BoardCells(playboard); List<Cell> movesRemaining = null; do { foreach (var move in forcedMoves) { playboard = new Board(playboard, move); movesPlayed.Add(move); _numMovesTried++; } playboardCells = new BoardCells(playboard); movesRemaining = MoveFinder.FindMoves(playboardCells); forcedMoves = GetForcedMoves(Board.GetMovesFrom(movesRemaining)); } while (forcedMoves.Count > 0); if (!Board.IsValid((Board)playboard)) { return null; } return new MoveResult(playboardCells, movesPlayed, movesRemaining); }
public override IScore GetScore(IBoardCells boardCells) { if (boardCells == null) { throw new ArgumentNullException(nameof(boardCells)); } if (Board.IsSolved((Board)boardCells.Board)) { return Score.SolvedBoardScore; } if (boardCells.BoardScore == null) { // for this basic implementation the score is 1/(# moves on board) var moves = MoveFinder.FindMoves(boardCells); int numMoves = 0; int numForcedMoves = 0; foreach (var cell in moves) { numMoves += cell.Moves.Count; foreach (var move in cell.Moves) { if (move.IsForcedMove.HasValue && move.IsForcedMove.Value) { numForcedMoves++; } } } if (numMoves == 0) { // board should be solved if (HasMoves(boardCells.Board)) { // unsolvable board return Score.InvalidBoardScore; } // the board is solved return Score.SolvedBoardScore; } double score = -1 * numMoves; if (numForcedMoves > 0) { score += ((double)numForcedMoves / (double)numMoves) * 0.5; } boardCells.BoardScore = new MultiPartScore(new double[1] { score }); // return new Score(score); // return new Score(1.0d/(1+numMoves + (numMoves-numForcedMoves))); } else { var foo = "bar"; } return boardCells.BoardScore; }
public abstract IScore GetSquareScore(IBoardCells board, int sqRow, int sqCol);
public abstract IScore GetScore(IBoardCells boardCells);
public abstract IScore GetRowScore(IBoardCells board, int row);
public abstract IScore GetColScore(IBoardCells board, int col);
public override IScore GetSquareScore(IBoardCells board, int sqRow, int sqCol) { int numMoves = 0; int numEmptyCells = 0; int sqSize = (int)Math.Sqrt(board.Board.Size); int row = sqRow * sqSize; int col = sqCol * sqSize; for (int r = row; r < row + sqSize; r++) { for (int c = col; c < col + sqSize; c++) { var cell = MoveFinder.GetMovesForCell(board, r, c); if (cell.Moves != null) { numMoves += cell.Moves.Count; } if (board.Board[r, c] == 0) { numEmptyCells++; } } } if (numEmptyCells == 0) { return Score.SolvedRegionScore; } return new MultiPartScore(new double[] { -numMoves, numEmptyCells }); }