static void MinimaxSearch() { /* alpha-beta(player,board,alpha,beta) if(game over in current board position) return winner children = all legal moves for player from this board */ //starting game position (default) GameBoard parent = new GameBoard(); parent.SetNodeType(GameBoard.MinMax.Min); int total_moves = 0; /* //forced loss test parent.SetStones(0, 0, 10, Colour.WHITE); parent.SetStones(1, 0, 3, Colour.BLACK); parent.SetStones(0, 1, 3, Colour.BLACK); parent.SetStones(1, 1, 4, Colour.BLACK); parent.SetStones(3, 0, 0, Colour.NONE); parent.SetStones(0, 3, 0, Colour.NONE); */ Console.WriteLine("Starting move:"); displayBoard(parent); bool turn = false; //turn 0 = player's turn(black,min), turn 1 = our turn(white,max) GameBoard next_move = null; //while we still have moves left, or haven't played over 1000 moves while(total_moves < 5000) { if (turn == false)//their turn (BLACK) { Console.WriteLine("Black - Their Move / Player 1"); //Random moves :( //choose random child int moves = parent.GetChildren().Count; if (moves <= 0) { moves = CalculateMoves(parent); } //player 2 wins if (moves == 0) { break; } Random random_number = new Random(); int black_move = random_number.Next(parent.GetChildren().Count - 1); next_move = parent.GetChildren().ElementAt(black_move); //parent.SetAlphaBetaValue(next_move.GetAlphaBetaValue()); turn = true; } else //my move (WHITE) { Console.WriteLine("White - My Move / Player 2"); //GameBoard start_move = parent; // CalculateMaxMove(parent); //current node is a beta next_move = parent; //GameBoard next_move_tmp = start_move; int counter = 0; //iterative deepening int internal_counter = 1; //keep adding one more iteration while (internal_counter > counter) { int moves = 0; if (next_move.GetChildren().Count > 0) { moves = next_move.GetChildren().Count; } else { moves = CalculateMoves(next_move); } //player 1 wins-need to avoid if (moves == 0) { break; } if (parent.GetNodeType() == GameBoard.MinMax.Min) { if (CalculateMaxMove(next_move) == null) //end node { break; } next_move = CalculateMaxMove(next_move); } else { if (CalculateMinMove(next_move) == null) //end node { break; } next_move = CalculateMinMove(next_move); } counter++; if (counter == internal_counter && internal_counter < 50) //deepen search { internal_counter = internal_counter + 1; } } while (next_move.GetParent().GetParent() != null) { next_move = next_move.GetParent(); } turn = false; } Console.WriteLine("Move #: " + total_moves); displayBoard(next_move); parent = next_move; total_moves++; next_move.SetParent(null); //get rid of useless nodes System.GC.Collect(); // parent is always root node } //TIE if (next_move.GetChildren().Count > 0) { Console.WriteLine("NO winner. Try again..."); return; } //WINNER if (next_move.GetNodeType() == GameBoard.MinMax.Max) { Console.WriteLine("Player 1 wins"); } else { Console.WriteLine("Computer wins"); } return; }
static void AlphaBetaSearch() { GameBoard parent = new GameBoard(); parent.SetNodeType(GameBoard.MinMax.Min); int total_moves = 0; Console.WriteLine("Starting move:"); displayBoard(parent); CalculateMoves(parent); bool turn = false; //turn 0 = player's turn(black,min), turn 1 = our turn(white,max) GameBoard next_move = parent; while (total_moves < 5000) { if (turn == false)//their turn (BLACK) { Console.WriteLine("Their Move / Player 1"); //next_move = CalculateBeta(parent); //Random Agent :( //choose random child if (parent.GetChildren().Count <= 0) { CalculateMoves(parent); } if (parent.GetChildren().Count <= 0) { break; //win condition for player 2 } Random random_number = new Random(); int black_move = random_number.Next(parent.GetChildren().Count - 1); next_move = parent.GetChildren().ElementAt(black_move); turn = true; } else //my move (WHITE) { Console.WriteLine("My Move / Player 2"); //next_move = null; int best = 100000; if (parent.GetChildren().Count <= 0) { CalculateMoves(parent); } if (parent.GetChildren().Count <= 0) { break; //win condition for player 1 } //the parent is a max node (next_move) //the children are min nodes Collection<GameBoard> potentialMoves = new Collection<GameBoard>(); foreach (GameBoard child in parent.GetChildren()) { CalculateAlphaBeta(child, 3, -100000, best, GameBoard.MinMax.Min); if (child.GetAlphaBetaValue() < best) { best = child.GetAlphaBetaValue(); potentialMoves.Clear(); potentialMoves.Add(child); } else if (child.GetAlphaBetaValue() == best) { potentialMoves.Add(child); } } Random random_number = new Random(); int white_move = random_number.Next(potentialMoves.Count - 1); next_move = potentialMoves.ElementAt(white_move); potentialMoves.Clear(); parent.SetAlphaBetaValue(best); //System.GC.Collect(); turn = false; } //each move Console.WriteLine("Move #: " + total_moves); displayBoard(next_move); parent = next_move; total_moves++; next_move.SetParent(null); System.GC.Collect(); } //WINNER if (next_move.GetNodeType() == GameBoard.MinMax.Max) { Console.WriteLine("Player 1 wins"); } else { Console.WriteLine("Computer wins"); } }