コード例 #1
0
ファイル: FormMain.cs プロジェクト: REast/TicTacToeAI
      /// <summary>
      /// Called when the user clicks a square button in the game board visual area
      /// </summary>
      /// <param name="sender"></param>
      /// <param name="e"></param>
      private void square_clicked(object sender, EventArgs e)
      {
         Button squareClicked = (Button)sender;

         if (squareClicked.Enabled && gameActive != null)
         {
            Square squareObject = null;

            for (int iX = 0; iX < 3; iX++)
            {
               for (int iY = 0; iY < 3; iY++)
               {
                  if (squareButtons[iX,iY] == squareClicked)
                  {
                     squareObject = gameActive.Board.Squares[iX, iY];
                     break;
                  }
               }
            }

            if (squareObject != null)
            {
               Move move = new Move(gameActive.ActivePlayer, squareObject);
               gameActive.PlayMove(move);
            }
         }
      }
コード例 #2
0
ファイル: PlayerAI.cs プロジェクト: REast/TicTacToeAI
      /// <summary>
      /// Method called when the game passes control to this player
      /// </summary>
      /// <param name="game">Game object that this player belongs to</param>
      public override void PromptForMove(Game game)
      {
         Stopwatch stopwatch = new Stopwatch();
         stopwatch.Start();

         Square bestSquare = null;
         float bestValue = float.MinValue;

         _playerOpponent = game.Players[0];

         if (_playerOpponent == this)
         {
            _playerOpponent = game.Players[1];
         }

         Random rand = new Random();
         int equalSquares = 0;

         foreach (Square square in game.Board.Squares)
         {
            if (square.Owner == null)
            {
               square.Owner = this;
               float curValue = AlphaBetaPrune(game, int.MinValue, int.MaxValue, false);
               square.Owner = null;

               if (bestSquare == null || curValue > bestValue)
               {
                  bestValue = curValue;
                  bestSquare = square;
                  equalSquares = 0;
               }
               else if (curValue == bestValue)
               {
                  equalSquares++;
                  if (rand.Next(0,equalSquares + 1) == 0)
                  {
                     bestValue = curValue;
                     bestSquare = square;
                  }
               }
            }
         }

         int curTurnTime = (int)stopwatch.ElapsedMilliseconds;
         int turnTimeDiff = _minTurnTime - curTurnTime;

         Move move = new Move(this, bestSquare);

         Action playMove = () => game.PlayMove(move);

         int sleepMs = Math.Max(0, turnTimeDiff);

         // Ensure that the AI waits at least the minTurnTime before playing a move,
         // making the AI seem more human-like in that it won't make all of its moves near instantaniously.
         _timer = new Timer(PlayMoveAfterDelayCallback, playMove, sleepMs, Timeout.Infinite);
      }
コード例 #3
0
ファイル: Game.cs プロジェクト: REast/TicTacToeAI
      /// <summary>
      /// Attempt to play the given move
      /// </summary>
      /// <param name="move">Move to try and play</param>
      public void PlayMove(Move move)
      {
         if (move == null)
         {
            throw new InvalidMoveException("Cannot play null move.");
         }

         if (move.Player != ActivePlayer)
         {
            throw new InvalidMoveException("It is not this player's [" + move.Player.ToString() + "] turn.");
         }

         if (move.Square.Owner != null)
         {
            throw new InvalidMoveException("Board square [" + move.Square.ToString() + "] already has an owner.");
         }

         move.Square.Owner = move.Player;
         OnGameUpdate();
         AdvanceTurn();         

         if (GetGameState().IsCompleted == false)
         {
            ActivePlayer.PromptForMove(this);
         }
      }
コード例 #4
0
 /// <summary>
 /// Assigns arbitrary weights to a move. Used for computing a winner.
 /// </summary>
 /// <param name="move">
 /// The move whose weight to get.
 /// </param>
 /// <returns>
 /// An integer value weight for the move.
 /// </returns>
 private int GetWeightForMove(Move move)
 {
     int value = 0;
     switch (move)
     {
         case Move.X:
             value = 1;
             break;
         case Move.O:
             value = -1;
             break;
         case Move.Undefined:
             value = 0;
             break;
     }
     return value;
 }
コード例 #5
0
        /// <summary>
        /// Sets the target row and column in the board to the passed in move.
        /// </summary>
        /// <param name="slot">
        /// The slot to place the move in.
        /// </param>
        /// <param name="move">
        /// The move to make. X or O.
        /// </param>
        public void MakeMove(int slot, Move move)
        {
            if (slot < 1 || slot > 9)
            {
                throw new IndexOutOfRangeException("Slot numbers must be between 1 and 9");
            }

            var index = slot - 1;
            if (moves[index] == Move.Undefined)
            {
                this.moves[index] = move;
                this.winner = this.CheckForWinner();
            }
            else
            {
                throw new ArgumentException("Someone already moved there!");
            }
        }
コード例 #6
0
 /// <summary>
 /// Swaps X's to O's and O's to X's. Allows for alternating moves.
 /// </summary>
 /// <param name="currentPlayer">
 /// The current move to be made by a player. X or O.
 /// </param>
 /// <returns>
 /// If X, then O. If O, then X.
 /// </returns>
 private Move FlipCurrentPlayer(Move currentPlayer)
 {
     return currentPlayer == Move.X ? Move.O : Move.X;
 }
コード例 #7
0
 /// <summary>
 /// Prints out a move.
 /// </summary>
 /// <param name="move">
 /// The move to print.
 /// </param>
 /// <returns>
 /// Prints the symbol for the move.
 /// </returns>
 private string PrintMove(Move move)
 {
     return move == Move.X ? "X" : "O";
 }
コード例 #8
0
 /// <summary>
 /// Sets the target row and column in the board to the passed in move.
 /// </summary>
 /// <param name="slot">
 /// The slot to place the move in.
 /// </param>
 /// <param name="move">
 /// The move to make. X or O.
 /// </param>
 public void MakeMove(int slot, Move move)
 {
     throw new NotImplementedException();
 }