private void SetPiece(Piece piece, Player player, int letter, int number) { // if a thread called this, invoke recursion if (this.InvokeRequired) { this.Invoke(new Action(() => SetPiece(piece, player, letter, number))); return; } // out of bounds if (letter < 0 || letter > 7 || number < 0 || number > 7) return; // throw new IndexOutOfRangeException("Chess board letter or number out of range"); // clear tile if (piece == Piece.NONE) { Board[number][letter].Image = null; Board[number][letter].Invalidate(); return; } // update our render Board[number][letter].Image = graphics.Pieces[player][piece]; Board[number][letter].Invalidate(); }
// Constructor public Message(bool error, string msg, string action, Player player) { this.error = error; this.msg = msg; this.player = player; this.action = action; }
// Method for the opening of popup public void open(Player player, coord position) { close (); foreach (Figure fig in this.figures) { TileWidget tile = new TileWidget ("", fig.name (), player.ToString (), this.tileSize); tile.position = position; fig.color = player.ToString (); box.PackStart (tile); tile.ButtonPressEvent += onTileClicked; } this.ShowAll (); }
/// <summary> /// Calculate and return the boards fitness value. /// </summary> /// <param name="max">Who's side are we viewing from.</param> /// <returns>The board fitness value, what else?</returns> public int fitness(Player max) { int fitness = 0; int[] blackPieces = { 0, 0, 0, 0, 0, 0 }; int[] whitePieces = { 0, 0, 0, 0, 0, 0 }; int blackMoves = 0; int whiteMoves = 0; // sum up the number of moves and pieces foreach (position_t pos in Pieces[Player.BLACK]) { blackMoves += LegalMoveSet.getLegalMove(this, pos).Count; blackPieces[(int)Grid[pos.number][pos.letter].piece]++; } // sum up the number of moves and pieces foreach (position_t pos in Pieces[Player.WHITE]) { whiteMoves += LegalMoveSet.getLegalMove(this, pos).Count; whitePieces[(int)Grid[pos.number][pos.letter].piece]++; } // if viewing from black side if (max == Player.BLACK) { // apply weighting to piece counts for (int i = 0; i < 6; i++) { fitness += pieceWeights[i] * (blackPieces[i] - whitePieces[i]); } // apply move value fitness += (int)(0.5 * (blackMoves - whiteMoves)); } else { // apply weighting to piece counts for (int i = 0; i < 6; i++) { fitness += pieceWeights[i] * (whitePieces[i] - blackPieces[i]); } // apply move value fitness += (int)(0.5 * (whiteMoves - blackMoves)); } return fitness; }
private static int mimaab(ChessBoard board, Player turn, int depth, int alpha, int beta) { // base case, at maximum depth return board fitness if (depth >= DEPTH) return board.fitness(MAX); else { List<ChessBoard> boards = new List<ChessBoard>(); // get available moves / board states from moves for the current player foreach (position_t pos in board.Pieces[turn]) { if (STOP) return -1; // interupts List<position_t> moves = LegalMoveSet.getLegalMove(board, pos); foreach (position_t move in moves) { if (STOP) return -1; // interupts ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, move)); boards.Add(b2); } } int a = alpha, b = beta; if (turn != MAX) // minimize { foreach (ChessBoard b2 in boards) { if (STOP) return -1; // interupt b = Math.Min(b, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b)); if (a >= b) return a; } return b; } else // maximize { foreach (ChessBoard b2 in boards) { if (STOP) return -1; // interupt a = Math.Max(a, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b)); if (a >= b) return b; } return a; } } }
public Board(Player whitePlayer, Player blackPlayer, string fenString = DEFAULT_STARTING_FEN) { this.StartFen = fenString; var config = FEN.Parse(fenString); this.Turn = config.Turn; foreach (var piece in config.Pieces) this[piece.Square] = piece.CreatePiece(this); this.castleAvailability.Add(PlayerColor.Black, config.BlackCastleAvailability); this.castleAvailability.Add(PlayerColor.White, config.WhiteCastleAvailability); this.History = new List<PieceMove>(); whitePlayer.Board = this; whitePlayer.PlayerColor = PlayerColor.White; blackPlayer.Board = this; blackPlayer.PlayerColor = PlayerColor.Black; this.Players = new Dictionary<PlayerColor, Player> { { PlayerColor.White, whitePlayer }, { PlayerColor.Black, blackPlayer } }; this.Players[PlayerColor.White].OnPreInit(); this.Players[PlayerColor.Black].OnPreInit(); }
public void SetTurn(Player p) { // if a thread called this, invoke recursion if (this.InvokeRequired) { this.Invoke(new Action(() => SetTurn(p))); return; } // update the turn indicator if (chess != null) { picTurn.Image = graphics.TurnIndicator[chess.Turn]; } else { picTurn.Image = graphics.TurnIndicator[Player.WHITE]; } // if not creating a board if (!m_manualBoard) { // toggle whos timer is running if (p == Player.WHITE) { tmrBlack.Stop(); tmrWhite.Start(); } else { tmrWhite.Stop(); tmrBlack.Start(); } // if game over just stop timers if (chess != null && (m_checkmate || chess.detectCheckmate())) { tmrWhite.Stop(); tmrBlack.Stop(); } } }
public ChessBoard(Player p1, Player p2) { //all white pieces whiteKing = new King(p1, 3, 0); ChessPiece whiteQueen = new Queen(p1, 4, 0); ChessPiece whiteRunner1 = new Runner(p1, 2, 0); ChessPiece whiteRunner2 = new Runner(p1, 5, 0); ChessPiece whiteHorse1 = new Horse(p1, 1, 0); ChessPiece whiteHorse2 = new Horse(p1, 6, 0); ChessPiece whiteTower1 = new Tower(p1, 0, 0); ChessPiece whiteTower2 = new Tower(p1, 7, 0); ChessPiece whiteFarmer1 = new Farmer(p1, 0, 1); ChessPiece whiteFarmer2 = new Farmer(p1, 1, 1); ChessPiece whiteFarmer3 = new Farmer(p1, 2, 1); ChessPiece whiteFarmer4 = new Farmer(p1, 3, 1); ChessPiece whiteFarmer5 = new Farmer(p1, 4, 1); ChessPiece whiteFarmer6 = new Farmer(p1, 5, 1); ChessPiece whiteFarmer7 = new Farmer(p1, 6, 1); ChessPiece whiteFarmer8 = new Farmer(p1, 7, 1); //all black pieces blackKing = new King(p2, 4, 7); ChessPiece blackQueen = new Queen(p2, 3, 7); ChessPiece blackRunner1 = new Runner(p2, 2, 7); ChessPiece blackRunner2 = new Runner(p2, 5, 7); ChessPiece blackHorse1 = new Horse(p2, 1, 7); ChessPiece blackHorse2 = new Horse(p2, 6, 7); ChessPiece blackTower1 = new Tower(p2, 0, 7); ChessPiece blackTower2 = new Tower(p2, 7, 7); ChessPiece blackFarmer1 = new Farmer(p2, 0, 6); ChessPiece blackFarmer2 = new Farmer(p2, 1, 6); ChessPiece blackFarmer3 = new Farmer(p2, 2, 6); ChessPiece blackFarmer4 = new Farmer(p2, 3, 6); ChessPiece blackFarmer5 = new Farmer(p2, 4, 6); ChessPiece blackFarmer6 = new Farmer(p2, 5, 6); ChessPiece blackFarmer7 = new Farmer(p2, 6, 6); ChessPiece blackFarmer8 = new Farmer(p2, 7, 6); //add all chesspieces to twodimensional array board[3, 0] = whiteKing; board[4, 0] = whiteQueen; board[2, 0] = whiteRunner1; board[5, 0] = whiteRunner2; board[1, 0] = whiteHorse1; board[6, 0] = whiteHorse2; board[0, 0] = whiteTower1; board[7, 0] = whiteTower2; board[0, 1] = whiteFarmer1; board[1, 1] = whiteFarmer2; board[2, 1] = whiteFarmer3; board[3, 1] = whiteFarmer4; board[4, 1] = whiteFarmer5; board[5, 1] = whiteFarmer6; board[6, 1] = whiteFarmer7; board[7, 1] = whiteFarmer8; board[4, 7] = blackKing; board[3, 7] = blackQueen; board[2, 7] = blackRunner1; board[5, 7] = blackRunner2; board[1, 7] = blackHorse1; board[6, 7] = blackHorse2; board[0, 7] = blackTower1; board[7, 7] = blackTower2; board[0, 6] = blackFarmer1; board[1, 6] = blackFarmer2; board[2, 6] = blackFarmer3; board[3, 6] = blackFarmer4; board[4, 6] = blackFarmer5; board[5, 6] = blackFarmer6; board[6, 6] = blackFarmer7; board[7, 6] = blackFarmer8; }
public Runner(Player p, int posX, int posY) : base(p, posX, posY) { }
public static Board Load(string fen, Player white = null, Player black = null) { return new Board(white ?? new Player(), black ?? new Player(), fen); }
/// <summary> /// Slide along the path steps until you hit something. Return path to point and if it ends attacking with the attack. /// </summary> private static List<position_t> Slide(ChessBoard board, Player p, position_t pos, position_t step) { List<position_t> moves = new List<position_t>(); for (int i = 1; i < 8; i++) { position_t moved = new position_t(pos.letter + i * step.letter, pos.number + i * step.number); if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) break; if (board.Grid[moved.number][moved.letter].piece != Piece.NONE) { if (board.Grid[moved.number][moved.letter].player != p) moves.Add(moved); break; } moves.Add(moved); } return moves; }
/// <summary> /// Determine if the provided player has any valid moves. /// </summary> /// <param name="b">The state of the game.</param> /// <param name="player">The player.</param> /// <returns>True if the player has moves.</returns> public static bool hasMoves(ChessBoard b, Player player) { foreach(position_t pos in b.Pieces[player]) if (b.Grid[pos.number][pos.letter].piece != Piece.NONE && b.Grid[pos.number][pos.letter].player == player && getLegalMove(b, pos).Count > 0) return true; return false; }
public static move_t MiniMaxAB(ChessBoard board, Player turn) { RUNNING = true; // we've started running STOP = false; // no interupt command sent MAX = turn; // who is maximizing // gather all possible moves Dictionary<position_t, List<position_t>> moves = LegalMoveSet.getPlayerMoves(board, turn); // because we're threading safely store best result from each thread int[] bestresults = new int[moves.Count]; move_t[] bestmoves = new move_t[moves.Count]; // thread the generation of each move Parallel.ForEach(moves, (movelist,state,index) => { if (STOP) // interupt { state.Stop(); return; } // initialize thread best bestresults[index] = int.MinValue; bestmoves[index] = new move_t(new position_t(-1, -1), new position_t(-1, -1)); // for each move for the current piece(thread) foreach (position_t move in movelist.Value) { if (STOP) // interupt { state.Stop(); return; } // make initial move and start recursion ChessBoard b2 = LegalMoveSet.move(board, new move_t(movelist.Key, move)); int result = mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, 1, Int32.MinValue, Int32.MaxValue); // if result is better or best hasn't been set yet if (bestresults[index] < result || (bestmoves[index].to.Equals(new position_t(-1, -1)) && bestresults[index] == int.MinValue)) { bestresults[index] = result; bestmoves[index].from = movelist.Key; bestmoves[index].to = move; } } }); // interupted if (STOP) return new move_t(new position_t(-1, -1), new position_t(-1, -1)); // find the best of the thread results int best = int.MinValue; move_t m = new move_t(new position_t(-1, -1), new position_t(-1, -1)); for(int i = 0; i < bestmoves.Length; i++) { if (best < bestresults[i] || (m.to.Equals(new position_t(-1,-1)) && !bestmoves[i].to.Equals(new position_t(-1,-1)))) { best = bestresults[i]; m = bestmoves[i]; } } return m; }
public void SetPiece(Piece piece, Player player, int letter, int number) { // set grid values Grid[number][letter].piece = piece; Grid[number][letter].player = player; // add piece to list Pieces[player].Add(new position_t(letter, number)); // update king position if (piece == Piece.KING) { Kings[player] = new position_t(letter, number); } }
private static bool allowCastle(ChessBoard board, Player player, position_t pos, bool isRight) { bool isValid = true; int rookPos; int kingDirection; if (isRight) { rookPos = 7; kingDirection = 1; } else { rookPos = 0; kingDirection = -1; } //Check for valid right castling // Is the peice at H,7 a rook owned by the player and has it moved if (board.Grid[pos.number][rookPos].piece == Piece.ROOK && board.Grid[pos.number][rookPos].player == player && board.Grid[pos.number][rookPos].lastPosition.Equals(new position_t(-1,-1))) { // Check that the adjacent two squares are empty for (int i = 0; i < 2; i++) { if (board.Grid[pos.number][pos.letter + (i + 1) * kingDirection].piece != Piece.NONE) { isValid = false; break; } } // Don't bother running secondary checks if the way isn't even clear if (isValid) { for (int i = 0; i < 2; i++) { // Move kings postion over i squares to check if king is passing over an attackable // square ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, new position_t(pos.letter + (i + 1) * kingDirection, pos.number))); // Attackable square is in between king and rook so // its not possible to castle to the right rook if (isCheck(b2, player)) { isValid = false; break; } } } } else { isValid = false; } return isValid; }
/// <summary> /// Checks to see if the king for a player is in check. This function /// works by pretending the king is each of the different board pieces and seeing if it can attack /// any of the same type of price from its current position. /// </summary> /// <param name="b">Board state</param> /// <param name="king">the currnet player</param> /// <returns>Is in check</returns> public static bool isCheck(ChessBoard b, Player king) { if (b.Kings.Count == 0) return true; position_t king_pos = b.Kings[king]; if (king_pos.number < 0 || king_pos.letter < 0) return true; Piece[] pieces = { Piece.PAWN, Piece.ROOK, Piece.KNIGHT, Piece.BISHOP, Piece.QUEEN, Piece.KING }; ChessBoard tempBoard = new ChessBoard(b); for (int i = 0; i < 6; i++) { tempBoard.Grid[king_pos.number][king_pos.letter] = new piece_t(pieces[i], king); List<position_t> moves = getLegalMove(tempBoard, king_pos, false); foreach (var move in moves) { if (b.Grid[move.number][move.letter].piece == pieces[i] && b.Grid[move.number][move.letter].player != king) { return true; } } } return false; }
public King(Player p, int posX, int posY) : base(p, posX, posY) { }
public Horse(Player p, int posX, int posY) : base(p, posX, posY) { }
public Farmer(Player p, int posX, int posY) : base(p, posX, posY) { }
public Queen(Player p, int posX, int posY) : base(p, posX, posY) { }
public Tower(Player p, int posX, int posY) : base(p, posX, posY) { }
/// <summary> /// Get all legal moves for the player on the current board. /// </summary> /// <param name="b">The state of the game.</param> /// <param name="player">The player whose moves you want.</param> /// <returns>A 1-to-many dictionary of moves from one position to many</returns> public static Dictionary<position_t, List<position_t>> getPlayerMoves(ChessBoard b, Player player) { Dictionary<position_t, List<position_t>> moves = new Dictionary<position_t, List<position_t>>(); foreach (position_t pos in b.Pieces[player]) if (b.Grid[pos.number][pos.letter].piece != Piece.NONE) { if (!moves.ContainsKey(pos)) moves[pos] = new List<position_t>(); moves[pos].AddRange(LegalMoveSet.getLegalMove(b, pos)); } return moves; }