Beispiel #1
0
        public bool GetNextMove(Board.Player player, out Tuple <int, int, Board.Move> mv, out string prompt)
        {
            prompt = String.Empty;
            mv     = Tuple.Create(-1, -1, Board.Move.Sp);
            //keep trying until the user quits or enters a valid input
            while (true)
            {
                //prompt user for imnput
                ConsoleWriteLine("Enter row and column for your move: row , column. \nor enter 'Q' to quit the game: ", false);
                string input = Console.ReadLine();

                //if player is quiting throw quit exception
                if (input.Trim().ToUpper() == "Q")
                {
                    throw new QuitGame("Quiting TicTacToe Game");
                }

                //split inputs into row and col numbers
                var inputs = input.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

                int        digit = -1;
                List <int> move  = new List <int>();
                foreach (string i in inputs)
                {
                    if (Int32.TryParse(i, out digit))
                    {
                        move.Add(digit);
                    }
                }

                //check move input for valid input
                if (move.Count == 2)
                {
                    if (currentBoard.ValidMove(move[0] - 1, move[1] - 1, player == Board.Player.O ? Board.Move.O : Board.Move.X))
                    {
                        mv = Tuple.Create(move[0] - 1, move[1] - 1, MoveFromPlayer(player));
                        return(true);
                    }

                    prompt = "\nInvalid Input read. Must enter an integer between 1 and 3 a comma and an integer between 1 and 3\n";
                }
                else if (move.Count > 2)
                {
                    prompt =
                        "\nToo many inputs entered" + "\nUser input was " + input +
                        "\nMust enter an integer between 0 and 2 a comma and an integer between 0 and 2\n";
                }
                else if (move.Count < 2)
                {
                    prompt =
                        "\nToo few inputs entered" + "\nUser input was " + input +
                        "Must enter an integer between 0 and 2 a comma and an integer between 0 and 2\n";
                }
            }
        }
Beispiel #2
0
        //Return Game Winner or if tie return Player.None
        public Board.Player PlayGame()
        {
            //play starts with X
            Board.Player player = Board.Player.O;

            try
            {
                //Alternate moves with computer until someone wins
                gameMoves = new List <string>();
                currentBoard.DisplayBoard();
                while (!currentBoard.Winner(player) && !currentBoard.IsTie())
                {
                    player = (player == Board.Player.O) ? Board.Player.X : Board.Player.O;
                    gameMoves.Add(currentBoard.ToString());
                    Tuple <int, int, Board.Move> move;
                    string prompt;
                    while (!GetNextMove(player, out move, out prompt))
                    {
                        ConsoleWriteLine(prompt);
                    }

                    currentBoard.DoMove(move.Item1, move.Item2, move.Item3);
                    currentBoard.DisplayBoard();
                    if (currentBoard.Winner(player))
                    {
                        break;
                    }
                    ConsoleWriteLine("The Computer moves.");
                    player = (player == Board.Player.O) ? Board.Player.X : Board.Player.O;
                    gameMoves.Add(currentBoard.ToString());
                    move = GetNextComputerMove(player);
                    currentBoard.DoMove(move.Item1, move.Item2, move.Item3);
                    currentBoard.DisplayBoard();
                }
            }
            catch (QuitGame)
            {
                ConsoleWriteLine("User has quit the game");
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                ConsoleWriteLine("Error in game" + ex.Message);
                Console.ForegroundColor = ConsoleColor.White;
            }

            //return winner
            if (currentBoard.IsTie())
            {
                player = Board.Player.None;
            }
            return(player);
        }
Beispiel #3
0
        void UpdateTreeWithGame(List <String> gameMoves, Board.Player winner)
        {
            //Bt Default X is the first move in all games
            //if the winner was X then first move and every other move is a winning move
            //otherwise first move and all alternate subsequent moves are losing moves
            //if game was a tie update nothing
            bool XWinner = winner == Board.Player.X;

            current = root;
            foreach (string move in gameMoves)
            {
                current = current.ChildExists(move);
                if (XWinner)
                {
                    current.RegisterWinningMove()
                    ;
                }
                else
                {
                    current.RegisterLosingMove();
                }
                XWinner = !XWinner;
            }
        }
Beispiel #4
0
        // minimax implementation
        private int ChooseBestMove(Board.Player currentPlayer, int depth)
        {                        
            Board.Player winner = _board.GetWinner();

            if (winner == Board.Player.Computer)
                return 1;
            if (winner == Board.Player.Human)
                return -1;
            if (_board.IsFull())
                return 0;
            
            int bestScore = currentPlayer == Board.Player.Computer ? -1 : 1;

            foreach (int validMove in _board.GetValidMoves())
            {
                _board.Put(validMove, currentPlayer);
                int score = ChooseBestMove(currentPlayer == Board.Player.Computer ? Board.Player.Human : Board.Player.Computer, depth + 1);

                // i could use negamax to simplify this code
                if ((currentPlayer == Board.Player.Computer && score > bestScore) ||
                    (currentPlayer == Board.Player.Human && score < bestScore))
                {
                    bestScore = score;
                }

                _board.Remove(validMove);

                // if we are on the top of the tree, i save every possibly move in order to be able to choose one at random between the best moves
                if (depth == 0)
                {
                    _possibleMoves.Add(new PossibleMove(){Move = validMove, Score = score});
                }
            }

            return bestScore;
        }
Beispiel #5
0
        private void GameOver()
        {
            int[]        winnerPositions;
            Board.Player winner = _board.GetWinner(out winnerPositions);

            if (winner != Board.Player.None)
            {
                foreach (int winnerPosition in winnerPositions)
                {
                    _panels[winnerPosition].BackColor = Color.Yellow;
                }

                if (winner == Board.Player.Human)
                {
                    humanScoreLabel.Text = (int.Parse(humanScoreLabel.Text) + 1).ToString();
                }
                else
                {
                    computerScoreLabel.Text = (int.Parse(computerScoreLabel.Text) + 1).ToString();
                }
            }

            _gameState = GameState.GameOver;
        }
Beispiel #6
0
        private Tuple <int, int, Board.Move> GetNextComputerMove(Board.Player player)
        {
            int move = currentBoard.RandomMove();

            return(Tuple.Create(move / 3, move % 3, MoveFromPlayer(player)));
        }
Beispiel #7
0
 public Board.Move MoveFromPlayer(Board.Player player)
 {
     return(player == Board.Player.O ? Board.Move.O : Board.Move.X);
 }
Beispiel #8
0
    private void Update()
    {
        if (board.currentPlayer == player)
        {
            switch (board.gameState)
            {
            case Board.GameState.TakeCardFromPile:
            {
                cardPile = FindObjectOfType <CardPile>();
                cardPile.RequestCard();
                player.cards[player.cards.Count - 1].transform.position = new Vector3(cardHolder.transform.position.x,
                                                                                      cardHolder.transform.position.y, player.cards[player.cards.Count - 1].transform.position.z);
                break;
            }

            case Board.GameState.PickCardAndPawnToPlay:
            {
                Pawn selectedPawn = null;
                Card selectedCard = null;

                // First find if we can attactk human player. If so, attack him.
                foreach (Card card in player.cards)
                {
                    if (card.pawnSelector == Card.PawnSelector.InGamePawn &&
                        card.sideSelector == Card.SideSelector.Opponenet &&
                        card.direction == Card.Direction.None)
                    {
                        Board.Player opponent = (board.mintPlayer == player ? board.violetPlayer : board.mintPlayer);
                        foreach (Pawn pawn in opponent.pawns)
                        {
                            if (pawn.InGame())
                            {
                                selectedPawn = pawn;
                                break;
                            }
                        }
                        selectedCard = card;
                        break;
                    }
                }

                if (selectedPawn != null && selectedCard != null)
                {
                    board.OnCardSelected(selectedCard, false);
                    board.OnPawnSelected(selectedPawn, false);
                    break;
                }

                selectedCard = null;
                selectedPawn = null;

                // First check if player should go forward or backword.
                foreach (Pawn pawn in player.pawns)
                {
                    float EPSILON = 0.1f;
                    if (!pawn.Finished() && pawn.InGame() &&
                        System.Math.Abs(pawn.transform.position.x - player.entry.transform.position.x) < EPSILON &&
                        System.Math.Abs(pawn.transform.position.y - player.entry.transform.position.y) < EPSILON)
                    {
                        selectedPawn = pawn;
                        break;
                    }
                }

                if (selectedPawn != null)
                {
                    foreach (Card card in player.cards)
                    {
                        if (card.pawnSelector == Card.PawnSelector.InGamePawn &&
                            card.sideSelector == Card.SideSelector.Own &&
                            card.direction == Card.Direction.Back)
                        {
                            selectedCard = card;
                            break;
                        }
                    }
                }

                if (selectedPawn != null && selectedCard != null)
                {
                    board.OnCardSelected(selectedCard, false);
                    board.OnPawnSelected(selectedPawn, false);
                    break;
                }

                selectedCard = null;
                selectedPawn = null;

                // Move player forward if possible
                foreach (Pawn pawn in player.pawns)
                {
                    if (!pawn.Finished() && pawn.InGame())
                    {
                        selectedPawn = pawn;
                        break;
                    }
                }

                foreach (Card card in player.cards)
                {
                    if ((card.pawnSelector == Card.PawnSelector.InGamePawn ||
                         card.pawnSelector == Card.PawnSelector.Both) &&
                        card.sideSelector == Card.SideSelector.Own &&
                        card.direction == Card.Direction.Forward)
                    {
                        selectedCard = card;
                        break;
                    }
                }

                if (selectedPawn != null && selectedCard != null)
                {
                    board.OnCardSelected(selectedCard, false);
                    board.OnPawnSelected(selectedPawn, false);
                    break;
                }

                selectedCard = null;
                selectedPawn = null;


                // Just try to spawn if we can't do anything
                foreach (Pawn pawn in player.pawns)
                {
                    if (!pawn.Finished() && pawn.InSpawn())
                    {
                        selectedPawn = pawn;
                        break;
                    }
                }

                foreach (Card card in player.cards)
                {
                    if (card.pawnSelector == Card.PawnSelector.SpawnPawn ||
                        card.pawnSelector == Card.PawnSelector.Both)
                    {
                        selectedCard = card;
                        break;
                    }
                }

                if (selectedPawn != null && selectedCard != null)
                {
                    board.OnCardSelected(selectedCard, false);
                    board.OnPawnSelected(selectedPawn, false);
                    break;
                }

                selectedCard = null;
                selectedPawn = null;

                // We can't do anything throw random card and random pawn
                foreach (Pawn pawn in player.pawns)
                {
                    if (!pawn.Finished())
                    {
                        selectedPawn = pawn;
                        break;
                    }
                }

                selectedCard = player.cards[0];

                board.OnCardSelected(selectedCard, false);
                board.OnPawnSelected(selectedPawn, false);
                break;
            }

            default:
            {
                break;
            }
            }
        }
    }