Advertisement
Guest User

ai.dart

a guest
Mar 25th, 2022
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 2.55 KB | None | 0 0
  1. // ignore_for_file: constant_identifier_names
  2.  
  3. import 'package:minigames/src/games/tictactoe/tac_utility.dart';
  4.  
  5. class TacAI {
  6.   // evaluation condition values
  7.   static const int HUMAN = 1;
  8.   static const int AI_PLAYER = -1;
  9.   static const int NO_WINNERS_YET = 0;
  10.   static const int DRAW = 2;
  11.  
  12.   static const int EMPTY_SPACE = 0;
  13.   static const SYMBOLS = {EMPTY_SPACE: "", HUMAN: "X", AI_PLAYER: "O"};
  14.  
  15.   // arbitrary values for winning, draw and losing conditions
  16.   static const int WIN_SCORE = 100;
  17.   static const int DRAW_SCORE = 0;
  18.   static const int LOSE_SCORE = -100;
  19.  
  20.   static const WIN_CONDITIONS_LIST = [
  21.     [0, 1, 2],
  22.     [3, 4, 5],
  23.     [6, 7, 8],
  24.     [0, 3, 6],
  25.     [1, 4, 7],
  26.     [2, 5, 8],
  27.     [0, 4, 8],
  28.     [2, 4, 6],
  29.   ];
  30.  
  31.   /// Returns the optimal move based on the state of the board.
  32.   int? play(List<int> board, int currentPlayer) {
  33.     return _getBestMove(board, currentPlayer).move;
  34.   }
  35.  
  36.   /// Returns the best possible score for a certain board condition.
  37.   /// This method implements the stopping condition.
  38.   int? _getBestScore(List<int> board, int currentPlayer) {
  39.     int evaluation = TacUtility.evaluateBoard(board);
  40.  
  41.     if (evaluation == currentPlayer) return WIN_SCORE;
  42.  
  43.     if (evaluation == DRAW) return DRAW_SCORE;
  44.  
  45.     if (evaluation == TacUtility.flipPlayer(currentPlayer)) {
  46.       return LOSE_SCORE;
  47.     }
  48.  
  49.     return _getBestMove(board, currentPlayer).score;
  50.   }
  51.  
  52.   /// This is where the actual Minimax algorithm is implemented
  53.   Move _getBestMove(List<int> board, int currentPlayer) {
  54.     // try all possible moves
  55.     List<int> newBoard;
  56.     // will contain our next best score
  57.     Move bestMove = Move(score: -10000, move: -1);
  58.  
  59.     for (int currentMove = 0; currentMove < board.length; currentMove++) {
  60.       if (!TacUtility.isMoveLegal(board, currentMove)) continue;
  61.  
  62.       // we need a copy of the initial board so we don't pollute our real board
  63.       newBoard = List.from(board);
  64.  
  65.       // make the move
  66.       newBoard[currentMove] = currentPlayer;
  67.  
  68.       // solve for the next player
  69.       // what is a good score for the opposite player is opposite of good score for us
  70.       int nextScore =
  71.           -_getBestScore(newBoard, TacUtility.flipPlayer(currentPlayer))!;
  72.  
  73.       // check if the current move is better than our best found move
  74.       if (nextScore > bestMove.score!) {
  75.         bestMove.score = nextScore;
  76.         bestMove.move = currentMove;
  77.       }
  78.     }
  79.  
  80.     return bestMove;
  81.   }
  82. }
  83.  
  84. class Move {
  85.   int? score;
  86.   int? move;
  87.  
  88.   Move({this.score, this.move});
  89. }
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement