public static int Heuristic(ulong board, List <ulong> possible_moves = null) { if (Board.CurrentPlayerHasLessThanThree(board)) { return(-1000); // this is a losing position } if (possible_moves == null) { possible_moves = Board.GetMoves(board); } if (possible_moves.Count == 0) { return(-1000); // this is a losing position } /* We score +1 for a move, +2 if it forms a mill */ int score = 0; var old_runs = Board.GetRunPieces(board); foreach (var move in possible_moves) { var new_runs = Board.GetRunPieces(move); if (new_runs != old_runs && Board.CountBits(new_runs) >= Board.CountBits(old_runs)) { score += 5; } else { score++; } } return(score); }
public override ulong GetMove(ulong board) { // just return a random possible move var possible_moves = Board.GetMoves(board); return(possible_moves[rnd.Next(0, possible_moves.Count - 1)]); }
int minimax(ulong board, int depth, bool maximizingPlayer, out ulong move) { if (cache_v[depth].TryGetValue(board, out var cached)) { move = cache_move[depth][board]; return(cached); } var children = Board.GetMoves(board); if (depth == 0 || Board.CurrentPlayerHasLessThanThree(board) || children.Count == 0) { move = 0UL; return(Heuristic(board, IsWhite, children)); } if (maximizingPlayer) { var bestValue = int.MinValue; ulong best_move = 0UL; foreach (var child in children) { var v = minimax(child, depth - 1, false, out var unused); if (v > bestValue) { bestValue = v; best_move = child; } } move = best_move; cache_v[depth][board] = bestValue; cache_move[depth][board] = move; return(bestValue); } else { // minimizing player var bestValue = int.MaxValue; ulong best_move = 0UL; foreach (var child in children) { var v = minimax(child, depth - 1, true, out var unused); if (v < bestValue) { bestValue = v; best_move = child; } } move = best_move; cache_v[depth][board] = bestValue; cache_move[depth][board] = move; return(bestValue); } }
public override ulong GetMove(ulong board) { // minimise the heuristic for the opponent int min_h = int.MaxValue; ulong best_move = 0UL; foreach (var move in Board.GetMoves(board)) { var h = AIPlayer.Heuristic(move); if (h < min_h) { min_h = h; best_move = move; } } return(best_move); }
public static int Heuristic(ulong board, bool max_for_white, List <ulong> possible_moves = null) { if (!Board.IsPlacementPhase(board)) { if (Board.IsWhiteTurn(board) && Board.WhitePiecesOnBoard(board) < 3) { if (max_for_white) { return(-1000); } else { return(1000); } } else if (!Board.IsWhiteTurn(board) && Board.BlackPiecesOnBoard(board) < 3) { if (max_for_white) { return(1000); } else { return(-1000); } } } if (possible_moves == null) { possible_moves = Board.GetMoves(board); } if (possible_moves.Count == 0) { if (Board.IsWhiteTurn(board)) { if (max_for_white) { return(-1000); } else { return(1000); } } else { if (max_for_white) { return(1000); } else { return(-1000); } } } /* We score +1 for a move, +2 if it forms a mill */ int score = 0; var old_runs = Board.GetRunPieces(board); foreach (var move in possible_moves) { var new_runs = Board.GetRunPieces(move); if (new_runs != old_runs && Board.CountBits(new_runs) >= Board.CountBits(old_runs)) { score += 5; } else { score++; } } if (Board.IsWhiteTurn(board)) { if (max_for_white) { return(score); } else { return(-score); } } else { if (max_for_white) { return(-score); } else { return(score); } } }
public bool MakeTurn() { if (next_player) { Console.WriteLine("Turn: " + (turn++).ToString()); } Board.PrintBoard(board); List <ulong> AllowedMoves = null; if (Board.CurrentPlayerHasLessThanThree(board) || (AllowedMoves = Board.GetMoves(board)).Count == 0) { // Current player has lost if (next_player) { Console.Write("Black"); } else { Console.Write("White"); } Console.WriteLine(" Wins!"); return(false); } while (true) { ulong move; if (next_player) { move = White.GetMove(board); } else { move = Black.GetMove(board); } // ensure move is valid foreach (var allowed_move in AllowedMoves) { if (allowed_move == move) { next_player = !next_player; DumpMove(board, move); board = move; return(true); } } // move is invalid if (next_player) { White.IllegalMove(move); } else { Black.IllegalMove(move); } // request again } }