private static List <Position> Pawn(BoardHelper board, Position pos, bool verify_check = true) { List <Position> moves = new List <Position>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == PieceType.None) { return(moves); } // gather relative moves List <Position> relative = new List <Position>(); relative.Add(new Position(-1, 1 * ((p.player == PieceSide.Black) ? -1 : 1))); relative.Add(new Position(0, 1 * ((p.player == PieceSide.Black) ? -1 : 1))); relative.Add(new Position(0, 2 * ((p.player == PieceSide.Black) ? -1 : 1))); relative.Add(new Position(1, 1 * ((p.player == PieceSide.Black) ? -1 : 1))); // iterate moves foreach (Position move in relative) { Position moved = new Position(move.letter + pos.letter, move.number + pos.number); // bounds check if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) { continue; } // double forward move if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == PieceType.None && Math.Abs(moved.number - pos.number) == 2) { // check the first step int step = -((moved.number - pos.number) / (Math.Abs(moved.number - pos.number))); bool hasnt_moved = pos.number == ((p.player == PieceSide.Black) ? 6 : 1); if (board.Grid[moved.number + step][moved.letter].piece == PieceType.None && hasnt_moved) { moves.Add(moved); } } // if it's not blocked we can move forward else if (moved.letter == pos.letter && board.Grid[moved.number][moved.letter].piece == PieceType.None) { moves.Add(moved); } // angled attack else if (moved.letter != pos.letter && board.Grid[moved.number][moved.letter].piece != PieceType.None && board.Grid[moved.number][moved.letter].player != p.player) { moves.Add(moved); } // en passant else if (isEnPassant(board, new Move(pos, moved))) { moves.Add(moved); } } if (verify_check)// make sure each move doesn't put us in check { for (int i = moves.Count - 1; i >= 0; i--) { BoardHelper b2 = LegalMoveSet.move(board, new Move(pos, moves[i])); if (isCheck(b2, p.player)) { moves.RemoveAt(i); } } } return(moves); }
private Move MiniMaxAB(BoardHelper board, PieceSide turn) { RUNNING = true; // we've started running STOP = false; // no interupt command sent MAX = turn; // who is maximizing // gather all possible moves Dictionary <Position, List <Position> > moves = LegalMoveSet.getPlayerMoves(board, turn); // because we're threading safely store best result from each thread int[] bestresults = new int[moves.Count]; Move[] bestmoves = new Move[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(new Position(-1, -1), new Position(-1, -1)); // for each move for the current piece(thread) foreach (Position move in movelist.Value) { if (STOP) // interupt { state.Stop(); return; } // make initial move and start recursion BoardHelper b2 = LegalMoveSet.move(board, new Move(movelist.Key, move)); int result = mimaab(b2, (turn == PieceSide.White) ? PieceSide.Black : PieceSide.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(-1, -1)) && bestresults[index] == int.MinValue)) { bestresults[index] = result; bestmoves[index].from = movelist.Key; bestmoves[index].to = move; } } }); // interupted if (STOP) { return(new Move(new Position(-1, -1), new Position(-1, -1))); } // find the best of the thread results int best = int.MinValue; Move m = new Move(new Position(-1, -1), new Position(-1, -1)); for (int i = 0; i < bestmoves.Length; i++) { if (best < bestresults[i] || (m.to.Equals(new Position(-1, -1)) && !bestmoves[i].to.Equals(new Position(-1, -1)))) { best = bestresults[i]; m = bestmoves[i]; } } return(m); }
private static List <Position> King(BoardHelper board, Position pos, bool verify_check = true) { List <Position> moves = new List <Position>(); piece_t p = board.Grid[pos.number][pos.letter]; if (p.piece == PieceType.None) { return(moves); } // collect all relative moves possible List <Position> relative = new List <Position>(); relative.Add(new Position(-1, 1)); relative.Add(new Position(0, 1)); relative.Add(new Position(1, 1)); relative.Add(new Position(-1, 0)); relative.Add(new Position(1, 0)); relative.Add(new Position(-1, -1)); relative.Add(new Position(0, -1)); relative.Add(new Position(1, -1)); // Iterate moves foreach (Position move in relative) { Position moved = new Position(move.letter + pos.letter, move.number + pos.number); // bound check if (moved.letter < 0 || moved.letter > 7 || moved.number < 0 || moved.number > 7) { continue; } // if it's not blocked we can move if (board.Grid[moved.number][moved.letter].piece == PieceType.None || board.Grid[moved.number][moved.letter].player != p.player) { if (verify_check) // make sure we don't put ourselves in check { BoardHelper b2 = LegalMoveSet.move(board, new Move(pos, moved)); if (!isCheck(b2, p.player)) { moves.Add(moved); } } else { moves.Add(moved); } } } // Castling /* A king can only castle if: * king has not moved * rook has not moved * king is not in check * king does not end up in check * king does not pass through any other peieces * king does not pass through any squares under attack * king knows secret handshake */ if (verify_check) { if (!isCheck(board, p.player) && p.lastPosition.Equals(new Position(-1, -1))) { bool castleRight = allowCastle(board, p.player, pos, true); bool castleLeft = allowCastle(board, p.player, pos, false); if (castleRight) { moves.Add(new Position(6, pos.number)); } if (castleLeft) { moves.Add(new Position(2, pos.number)); } } } return(moves); }
private int mimaab(BoardHelper board, PieceSide turn, int depth, int alpha, int beta) { // base case, at maximum depth return board fitness if (depth >= DEPTH) { return(board.fitness(MAX)); } else { List <BoardHelper> boards = new List <BoardHelper>(); // get available moves / board states from moves for the current player foreach (Position pos in board.Pieces[turn]) { if (STOP) { return(-1); // interupts } List <Position> moves = LegalMoveSet.getLegalMove(board, pos); foreach (Position move in moves) { if (STOP) { return(-1); // interupts } BoardHelper b2 = LegalMoveSet.move(board, new Move(pos, move)); boards.Add(b2); } } int a = alpha, b = beta; if (turn != MAX) // minimize { foreach (BoardHelper b2 in boards) { if (STOP) { return(-1); // interupt } b = Math.Min(b, mimaab(b2, (turn == PieceSide.White) ? PieceSide.Black : PieceSide.White, depth + 1, a, b)); if (a >= b) { return(a); } } return(b); } else // maximize { foreach (BoardHelper b2 in boards) { if (STOP) { return(-1); // interupt } a = Math.Max(a, mimaab(b2, (turn == PieceSide.White) ? PieceSide.Black : PieceSide.White, depth + 1, a, b)); if (a >= b) { return(b); } } return(a); } } }