예제 #1
0
 /// <summary>
 /// Use this construtor for the "root" node
 /// </summary>
 /// <param name="currentGameModel"></param>
 /// <param name="currentPlayer"></param>
 /// <param name="currentPlayer"></param>
 public TicTacToeDecisionNode(TicTacToeGameModel currentGameModel, SquareLetter originalLetter, SquareLetter currentLetter)
 {
     OriginalLetter      = originalLetter;
     CurrentPlayerLetter = currentLetter;
     ThisModel           = currentGameModel;
     CreateChildNodes();
     SetNodeOutcome(this, true, originalLetter);
 }
예제 #2
0
        public TicTacToeDecisionNode(TicTacToeGameModel currentGameModel, bool forOriginalPlayer, SquareLetter originalLetter, SquareLetter currentLetter, int i = -1, int j = -1)
        {
            LastRowMove    = i;
            LastColumnMove = j;

            OriginalLetter      = originalLetter;
            CurrentPlayerLetter = currentLetter;
            ThisModel           = currentGameModel;
            CreateChildNodes();
            SetNodeOutcome(this, true, OriginalLetter);
        }
예제 #3
0
        public static bool IsBoardInWinningStateForPlayer(TicTacToeBoard board, SquareLetter letter)
        {
            // check for diagonal win from top left to bottom right
            if (board.Squares[0, 0].CurrentStatus == letter && board.Squares[1, 1].CurrentStatus == letter && board.Squares[2, 2].CurrentStatus == letter)
            {
                return(true);
            }

            // check for diagonal win form bottom left to top right
            if (board.Squares[2, 0].CurrentStatus == letter && board.Squares[1, 1].CurrentStatus == letter && board.Squares[0, 2].CurrentStatus == letter)
            {
                return(true);
            }

            // check for top row win
            if (board.Squares[0, 0].CurrentStatus == letter && board.Squares[0, 1].CurrentStatus == letter && board.Squares[0, 2].CurrentStatus == letter)
            {
                return(true);
            }

            // check for middle row win
            if (board.Squares[1, 0].CurrentStatus == letter && board.Squares[1, 1].CurrentStatus == letter && board.Squares[1, 2].CurrentStatus == letter)
            {
                return(true);
            }

            // check for bottom row win
            if (board.Squares[2, 0].CurrentStatus == letter && board.Squares[2, 1].CurrentStatus == letter && board.Squares[2, 2].CurrentStatus == letter)
            {
                return(true);
            }


            // check for left column win
            if (board.Squares[0, 0].CurrentStatus == letter && board.Squares[1, 0].CurrentStatus == letter && board.Squares[2, 0].CurrentStatus == letter)
            {
                return(true);
            }


            // check for middle column win
            if (board.Squares[0, 1].CurrentStatus == letter && board.Squares[1, 1].CurrentStatus == letter && board.Squares[2, 1].CurrentStatus == letter)
            {
                return(true);
            }

            // check for right column win
            if (board.Squares[0, 2].CurrentStatus == letter && board.Squares[1, 2].CurrentStatus == letter && board.Squares[2, 2].CurrentStatus == letter)
            {
                return(true);
            }

            return(false);
        }
예제 #4
0
 private bool Set(SquareLetter status)
 {
     if(CurrentStatus == SquareLetter.Empty)
     {
         CurrentStatus = status;
         return true;
     }
     else
     {
         return false;
     }
 }
예제 #5
0
        /*
         * private void Set_Can_Win(TicTacToeDecisionNode ticTacToeDecisionNode, Player originalPlayer)
         * {
         *  if(ticTacToeDecisionNode.IsWinForOriginalPlayer)
         *  {
         *      ticTacToeDecisionNode.CanWinNode = true;
         *      return;
         *  }
         *
         *  if(ticTacToeDecisionNode.CurrentPlayer.Letter == originalPlayer.Letter)
         *  {
         *      // if I am making the next move and any children is a winning move or a "killer move" it is also a killer move
         *      foreach(var childNode in ChildNodes)
         *      {
         *          if(childNode.IsWinForOriginalPlayer || childNode.CanWinNode)
         *          {
         *              ticTacToeDecisionNode.CanWinNode = true;
         *              return;
         *          }
         *      }
         *  }
         *  else
         *  {
         *      // if the other player is the next move and all of their children are killer moves, it is a killer move
         *      // if any of them are not killer moves, then it is not a killer move
         *      foreach (var childNode in ticTacToeDecisionNode.ChildNodes)
         *      {
         *          Set_Can_Win(childNode, originalPlayer);
         *          if (childNode.CanWinNode == false)
         *          {
         *              ticTacToeDecisionNode.CanWinNode = false;
         *              return;
         *          }
         *      }
         *      ticTacToeDecisionNode.CanWinNode = true;
         *      return;
         *  }
         * }
         *
         * private void Set_Will_Lose(TicTacToeDecisionNode ticTacToeDecisionNode, Player playerForNode)
         * {
         *  // No more child nodes, check these nodes
         *  if (ticTacToeDecisionNode.GameState == GameState.Tie)
         *  {
         *      ticTacToeDecisionNode.IsLosingNodeForOriginalPlayer = false;
         *      return;
         *  }
         *  else if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter == playerForNode.Letter)
         *  {
         *      ticTacToeDecisionNode.IsLosingNodeForOriginalPlayer = false;
         *      return;
         *  }
         *  else if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter != playerForNode.Letter)
         *  {
         *      ticTacToeDecisionNode.IsLosingNodeForOriginalPlayer = true;
         *      return;
         *  }
         *
         *  if (ticTacToeDecisionNode.GameState != GameState.InProgress && ticTacToeDecisionNode.ChildNodes.Count > 0)
         *  {
         *      throw new InvalidOperationException("Invalid state");
         *  }
         *
         *  foreach (var childNode in ticTacToeDecisionNode.ChildNodes)
         *  {
         *      Set_Will_Lose(childNode, playerForNode);
         *
         *      if (childNode.IsLosingNodeForOriginalPlayer == false)
         *      {
         *          ticTacToeDecisionNode.IsLosingNodeForOriginalPlayer = false;
         *          return;
         *      }
         *  }
         *
         *  ticTacToeDecisionNode.IsLosingNodeForOriginalPlayer = true;
         * }
         *
         * private void Set_Will_Win_Or_Tie(TicTacToeDecisionNode ticTacToeDecisionNode, Player playerForNode)
         * {
         *  // No more child nodes, check these nodes
         *  if (ChildNodes.Count == 0)
         *  {
         *      if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter == playerForNode.Letter)
         *      {
         *          ticTacToeDecisionNode.IsNonLosingNodeForOriginalPlayer = true;
         *          return;
         *      }
         *      else if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter != playerForNode.Letter)
         *      {
         *          ticTacToeDecisionNode.IsNonLosingNodeForOriginalPlayer = false;
         *          return;
         *      }
         *      else if (ticTacToeDecisionNode.GameState == GameState.Tie)
         *      {
         *          ticTacToeDecisionNode.IsNonLosingNodeForOriginalPlayer = true;
         *          return;
         *      }
         *  }
         *
         *  if (ticTacToeDecisionNode.GameState != GameState.InProgress && ticTacToeDecisionNode.ChildNodes.Count > 0)
         *  {
         *      throw new InvalidOperationException("Invalid state");
         *  }
         *
         *  foreach (var childNode in ticTacToeDecisionNode.ChildNodes)
         *  {
         *      Set_Will_Win_Or_Tie(childNode, playerForNode);
         *      if (childNode.IsNonLosingNodeForOriginalPlayer == false)
         *      {
         *          ticTacToeDecisionNode.IsNonLosingNodeForOriginalPlayer = false;
         *          return;
         *      }
         *  }
         *
         *  ticTacToeDecisionNode.IsNonLosingNodeForOriginalPlayer = true;
         * }
         *
         * private static void Set_Will_Win(TicTacToeDecisionNode ticTacToeDecisionNode, Player originalPlayer)
         * {
         *  // No more child nodes, check these nodes
         *  if (ticTacToeDecisionNode.ChildNodes.Count == 0)
         *  {
         *      if (ticTacToeDecisionNode.GameState == GameState.Tie)
         *      {
         *          ticTacToeDecisionNode.IsWinForOriginalPlayer = false;
         *          return;
         *      }
         *      else if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter != originalPlayer.Letter)
         *      {
         *          ticTacToeDecisionNode.IsWinForOriginalPlayer = false;
         *          return;
         *      }
         *      else if (ticTacToeDecisionNode.GameState == GameState.Win && ticTacToeDecisionNode.WinningPlayer.Letter == originalPlayer.Letter)
         *      {
         *          ticTacToeDecisionNode.IsWinForOriginalPlayer = true;
         *          return;
         *      }
         *  }
         *
         *  if (ticTacToeDecisionNode.GameState != GameState.InProgress && ticTacToeDecisionNode.ChildNodes.Count > 0)
         *  {
         *      throw new InvalidOperationException("Invalid state");
         *  }
         *
         *  foreach (var childNode in ticTacToeDecisionNode.ChildNodes)
         *  {
         *      Set_Will_Win(childNode, originalPlayer);
         *      if(childNode.IsWinForOriginalPlayer == false)
         *      {
         *          ticTacToeDecisionNode.IsWinForOriginalPlayer = false;
         *          return;
         *      }
         *  }
         *
         *  ticTacToeDecisionNode.IsWinForOriginalPlayer = true;
         * }
         */
        private void CreateChildNodes()
        {
            if (IsBoardInWinningState(ThisModel))
            {
                // don't add child nodes
                GameState = GameState.Win;
                //CurrentPlayer = null;
            }
            else if (IsBoardFull(ThisModel))
            {
                // don't add child nodes - game over with no winner
                GameState = GameState.Tie;
                //CurrentPlayer = null;
            }
            else
            {
                // there are still empty nodes
                GameState = GameState.InProgress;
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        if (!ThisModel.Board.Squares[i, j].Played)
                        {
                            // Get the current player for the next turn
                            SquareLetter nextLetter    = SquareLetter.O;
                            Player       currentPlayer = ThisModel.Player1;
                            if (CurrentPlayerLetter == ThisModel.Player1.Letter)
                            {
                                nextLetter    = this.ThisModel.Player2.Letter;
                                currentPlayer = this.ThisModel.Player2;
                            }
                            else
                            {
                                nextLetter    = this.ThisModel.Player1.Letter;
                                currentPlayer = this.ThisModel.Player1;
                            }

                            // create a new game state for hypothetical move
                            var newGameState = new TicTacToeGameModel(ThisModel.Player1.PlayerType, ThisModel.Player2.PlayerType, ThisModel.Board, currentPlayer, i, j);

                            var childNode = new TicTacToeDecisionNode(newGameState, !IsOriginalPlayer, OriginalLetter, nextLetter, i, j);

                            ChildNodes.Add(childNode);
                        }
                    }
                }
            }
        }
예제 #6
0
 public Player(SquareLetter playerLetter, PlayerType playerType)
 {
     Letter          = playerLetter;
     this.PlayerType = playerType;
 }
예제 #7
0
        private static void SetNodeOutcome(TicTacToeDecisionNode node, bool isForOriginalPlayer, SquareLetter originalLetter)
        {
            if (node.GameState == GameState.Win && node.WinningPlayer.Letter == originalLetter)
            {
                node.Score = 100;
                return;
            }
            else if (node.GameState == GameState.Win && node.WinningPlayer.Letter != originalLetter)
            {
                node.Score = -100;
                return;
            }
            else if (node.GameState == GameState.Tie)
            {
                node.Score = 0;
                return;
            }


            // check children
            if (isForOriginalPlayer)
            {
                // get max
                int max = int.MinValue;
                foreach (var childNode in node.ChildNodes)
                {
                    SetNodeOutcome(childNode, !isForOriginalPlayer, originalLetter);
                    max = Math.Max(max, childNode.Score);
                }
                node.Score = max;
                return;
            }
            else
            {
                // get min
                int min = int.MaxValue;
                foreach (var childNode in node.ChildNodes)
                {
                    SetNodeOutcome(childNode, !isForOriginalPlayer, originalLetter);
                    min = Math.Min(min, childNode.Score);
                }
                node.Score = min;
                return;
            }
        }