public MiniMaxPlayer(string playerName, GridValue playerSide, GameRules rules) { PlayerName = playerName; PlayerSide = playerSide; var problem = new TicTacToeAdversarialSearchProblem(); var stateEvaluator = new TicTacToeStateEvaluator(PlayerSide, rules); _search = new AdversarialSearch<TicTacToeState, Move>(problem, stateEvaluator); }
/// <summary> /// New IterativeDeepening algorithm with no time limits /// </summary> /// <param name="game"></param> /// <param name="algorithm">Adversarial search algorithm to be used</param> public IterativeDeepening(IGame <S, A, P> game, Algorithm algorithm) { switch (algorithm) { case Algorithm.Minimax: this.search = new MinimaxSearchLimited <S, A, P>(game, 1); break; default: throw new ArgumentException("Invalid algorithm"); } this.algorithm = algorithm; this.game = game; this.timeout = -1; //Unlimited wait time }
public A makeDecision(S state) { int level = 1; A action = default; int currentTimeout = this.timeout; while (true) { switch (algorithm) { case Algorithm.Minimax: search = new MinimaxSearchLimited <S, A, P>(game, level); break; } A selectedGameAction = default; void taskAction() { selectedGameAction = search.makeDecision(state); } Task task = new Task(taskAction); var watch = System.Diagnostics.Stopwatch.StartNew(); task.Start(); bool finishedExecution = task.Wait(currentTimeout); watch.Stop(); if (finishedExecution) { String expandedNodes = ""; bool fullyExplored = false; switch (algorithm) { case Algorithm.Minimax: expandedNodes = MinimaxSearchLimited <S, A, P> .METRICS_NODES_EXPANDED; fullyExplored = ((MinimaxSearchLimited <S, A, P>)search).FullyExplored; break; } action = selectedGameAction; Console.WriteLine($"Level {level} completed"); Console.WriteLine($"Selected action: {selectedGameAction}"); Console.WriteLine($"Expanded nodes: {search.getMetrics().Get(expandedNodes)}"); Console.WriteLine($"Execution Time: {watch.ElapsedMilliseconds} ms\n"); if (fullyExplored) { Console.WriteLine("The tree has been fully explored.\n"); break; } } else { break; } if (currentTimeout > 0) { currentTimeout = currentTimeout - (int)watch.ElapsedMilliseconds; if (currentTimeout <= 0 || !finishedExecution) { break; } } level += 1; } Console.WriteLine($"Execution stopped at level {level}"); return(action); }