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"; } } }
//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); }
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; } }
// 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; }
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; }
private Tuple <int, int, Board.Move> GetNextComputerMove(Board.Player player) { int move = currentBoard.RandomMove(); return(Tuple.Create(move / 3, move % 3, MoveFromPlayer(player))); }
public Board.Move MoveFromPlayer(Board.Player player) { return(player == Board.Player.O ? Board.Move.O : Board.Move.X); }
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; } } } }