public override IEnumerator ExecuteRequest() { var request = new ExecuteFunctionRequest { FunctionName = Constants.AI_MOVE_FUNCTION_NAME, FunctionParameter = new PlayFabIdRequest { PlayFabId = Player.PlayFabId }, AuthenticationContext = new PlayFabAuthenticationContext { EntityToken = Player.EntityToken } }; PlayFabCloudScriptAPI.ExecuteFunction(request, (result) => { ExecutionCompleted = true; AIMoveResult = PlayFabSimpleJson.DeserializeObject <TicTacToeMove>(result.FunctionResult.ToString()); }, (error) => { throw new Exception($"MakeAIMove request failed. Message: {error.ErrorMessage}, Code: {error.HttpCode}"); }); yield return(WaitForExecution()); }
public override void MakeMove(TicTacToeGame currentGame) { Move currentMove; GameState currentState = stateTree.Find(currentGame.GetStateId()).Value; int temp = currentGame.CheckForPossibleWin(); if (temp == -1) { temp = currentGame.CheckForBlock(); if (temp != -1) { currentMove = new TicTacToeMove(currentGame.GameBoard.Tiles[temp]); } else { currentMove = currentState.BestMove; } } else { currentMove = new TicTacToeMove(currentGame.GameBoard.Tiles[temp]); } currentGame.MakeMove(currentMove); accessedStates[count++] = currentState; }
public IGameMove DoMove(IGameState state) { var states = state.GameMoves; TicTacToeMove lastState = (TicTacToeMove)states[states.Length - 1]; var board = lastState.Board; this.PrintBoard(board); int chosenColumn = -1; int chosenRow = -1; do { Console.WriteLine("Choose where to place an X by selecting one of the available numbers from 1-9"); string rawChoice = Console.ReadLine(); if (!Int32.TryParse(rawChoice, out int parsedChoice)) { continue; } int choice = parsedChoice - 1; chosenRow = choice / board.Length; chosenColumn = choice % board.Length; } while(!ValidateChoice(board, chosenRow, chosenColumn)); ImmutableArray <string> newRow = board[chosenRow].SetItem(chosenColumn, this.Id); ImmutableArray <ImmutableArray <string> > newBoard = lastState.Board.SetItem(chosenRow, newRow); return(new TicTacToeMove(this.Id, newBoard)); }
public IEnumerator MakeMove(TicTacToeMove move) { var request = GetExecuteFunctionRequest( Constants.MULTIPLAYER_MOVE_FUNCTION_NAME, new MakeMultiplayerMoverRequest() { SharedGroupId = sharedGroupId, PlayerId = Player.PlayFabId, PlayerMove = move }); PlayFabCloudScriptAPI.ExecuteFunction( request, (result) => { ExecutionCompleted = true; MultiplayerMoveResponse = JsonUtility.FromJson <MakeMultiplayerMoveResponse>(result.FunctionResult.ToString()); }, (error) => { Debug.Log($"Make multiplayer move request failed. Message: {error.ErrorMessage}, Code: {error.HttpCode}"); } ); yield return(WaitForExecution()); }
public TicTacToeMove NegaMaxMove(TicTacToeBoard game) { List <Vector2> moves = game.FindBlankCells(game.Board); float score; TicTacToeMove bestMove = new TicTacToeMove(); TicTacToeBoard boardCopy = new TicTacToeBoard(); bestMove.Score = -10000; int depth = 0; foreach (Vector2 v in moves) { boardCopy.Board = game.CopyBoard(game.Board); boardCopy.PlaceMarker(boardCopy.Board, Marker.X, v); score = NegaMax(boardCopy, boardCopy.GetOppositeMarker(Marker.X), depth); if (score >= bestMove.Score) { bestMove.Score = (int)score; bestMove.Cell = v; } } return(bestMove); }
public void CheckFirstMove() { var game = TicTacToeGame.Classic; EngineResult aiResult = _ai.Analyse(game); TicTacToeMove bestMove = aiResult.BestMove as TicTacToeMove; Assert.IsNotNull(aiResult); Assert.IsNotNull(bestMove); // check it's one of good first moves -- 4 corners or center var goodMoves = new[] { Tuple.Create(0, 0), Tuple.Create(2, 0), Tuple.Create(0, 2), Tuple.Create(2, 2), Tuple.Create(0, 0), }; bool goodMove = false; foreach (var p in goodMoves) { if (bestMove.X == p.Item1 && bestMove.Y == p.Item2) { goodMove = true; break; } } Assert.IsTrue(goodMove, $"first move is bad: {bestMove}"); }
public TicTacToeMove GetAndResetMove() { var move = LatestPlayerMove; LatestPlayerMove = null; return(move); }
public IEnumerator WaitForNextMove() { // Enable the board SetEnabled(true); while (true) { for (int i = 0; i < Rows.Length; i++) { // Query the row for the next move on it StartCoroutine(Rows[i].GetNextMove()); // On the first row that gets clicked if (Rows[i].ColumnClicked != -1) { // Get the move that was requested LatestPlayerMove = new TicTacToeMove { row = i, col = Rows[i].ColumnClicked }; // Reset the row Rows[i].ColumnClicked = -1; // Disable the board SetEnabled(false); yield break; } } yield return(null); } }
public void MoveOFail() { var game = new TicTacToe(state); var move = new TicTacToeMove(TicTacToePlayer.O, new TicTacToeCell(0, 1)); var newState = game.MakeMove(move); Assert.IsNull(newState); }
/// <summary> /// Gets a random move. This can be used to make the game play interesting /// particularly in the beginning of the game or if you wish to weaken the computer's /// play by adding randomness. /// </summary> /// <param name="board">The board.</param> /// <returns>A new <see cref="TicTacToeMove"/>.</returns> private TicTacToeMove GetRandomMove(Board board) { var openPositions = board.OpenPositions.Length; var random = new Random(); var squareToMoveTo = random.Next(openPositions); var move = new TicTacToeMove(squareToMoveTo, this.PlayerPiece); return(move); }
public void ChangeGame() { NpgsqlConnection _connection = new NpgsqlConnection(connString); _connection.Open(); IRoomRepository repo = new PostgresRoomRepository(_connection, null); IUserRepository userRepo = new PostgresUserRepository(_connection, null); Room r = new Room(4); repo.Create(r); User amir = User.NewUser("Amir"); User budi = User.NewUser("Budi"); userRepo.Create(amir); userRepo.Create(budi); r.Join(amir); r.Join(budi); repo.Join(r, amir); repo.Join(r, budi); GameConfig config = new GameConfig(2, 2); r.StartGame("tic-tac-toe", config); repo.ChangeGame(r, r.Game, config); Room r2 = repo.FindById(r.ID); Assert.NotNull(r2); Assert.Equal("tic-tac-toe", r2.Game.Name()); Move m = new TicTacToeMove(amir.ID, 3); r.Move(m); repo.AddMove(r, m); Move m2 = new TicTacToeMove(budi.ID, 2); r.Move(m2); repo.AddMove(r, m2); Room r3 = repo.FindById(r.ID); char[] board = ((TicTacToeMemento)r3.Game.GetMemento()).Board; Assert.Equal('-', board[1]); Assert.Equal('O', board[2]); Assert.Equal('X', board[3]); _connection.Close(); }
private static void SetCursorToMove(TicTacToeMove move) { if (Console.CursorLeft > 0) { Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); Console.Write("_"); } Console.SetCursorPosition(1 + move.X * 4, 3 + move.Y * 2); }
public void SendMove(TicTacToeMove move) { var message = new PartyNetworkMessageWrapper <TicTacToeMove> { MessageType = PartyNetworkMessageEnum.Move, MessageData = move }; SendDataMessage(message); }
async Task DoTurn(int tappedRow, int tappedCol, uint length = 100) { var square = squares [tappedRow, tappedCol]; var position = (tappedRow * 3) + (tappedCol); if (game.IsGameOver()) { // game already over, no clicks allowed } else { if (!String.IsNullOrWhiteSpace(square.Text)) { // position already used } else { square.Text = xturn ? "X" : "O"; var piece = xturn ? Board.Pieces.X : Board.Pieces.O; TicTacToeMove playerMove; if (Oturn) { // O turn playerMove = GetMoveForPlayer(players[1]); // computer } else { // X turn playerMove = new TicTacToeMove(position, piece); game.MakeMove(playerMove); playerMove = GetMoveForPlayer(players[1]); // computer } game.MakeMove(playerMove); System.Diagnostics.Debug.WriteLine("Over: " + game.IsGameOver()); if (game.IsGameOver()) { if (game.GameBoard.IsDraw()) { await DisplayAlert("Game Drawn", "There was no winner", "OK", null); } else { await DisplayAlert("Game Over", square.Text + " won", "OK", null); } } xturn = !xturn; } } }
public void KeepTrackOfCorrectMoveOrder_BadMove() { _game.CurrentMove.Should().NotBe(_playerA.Mark); var move = new TicTacToeMove(_playerA, 0, 0); var result = _game.MakeMove(move); result.Should().BeFalse(); _game.CurrentMove.Should().Be(_playerB.Mark); }
public void WinVertical() { using (var uw = new PostgresUnitOfWork(connString)) { User amir = User.NewUser("Amir"); User budi = User.NewUser("Budi"); uw.UserRepo.Create(amir); uw.UserRepo.Create(budi); Room room = new Room(2); uw.RoomRepo.Create(room); room.Join(amir); uw.RoomRepo.Join(room, amir); room.Join(budi); uw.RoomRepo.Join(room, budi); room.StartGame("tic-tac-toe", GameConfig.Default(), uw.UserRepo); uw.RoomRepo.ChangeGame(room, room.Game, GameConfig.Default()); Move move; move = new TicTacToeMove(amir.ID, 4); room.Move(move); uw.RoomRepo.AddMove(room, move); move = new TicTacToeMove(budi.ID, 3); room.Move(move); uw.RoomRepo.AddMove(room, move); move = new TicTacToeMove(amir.ID, 7); room.Move(move); uw.RoomRepo.AddMove(room, move); move = new TicTacToeMove(budi.ID, 0); room.Move(move); uw.RoomRepo.AddMove(room, move); move = new TicTacToeMove(amir.ID, 1); room.Move(move); uw.RoomRepo.AddMove(room, move); move = new TicTacToeMove(budi.ID, 3); Exception ex = Assert.Throws <Exception>(() => room.Move(move)); uw.RoomRepo.AddMove(room, move); Assert.Equal("game already ended", ex.Message); Assert.Equal(5, uw.UserRepo.FindById(amir.ID).Exp); Assert.Equal(2, uw.UserRepo.FindById(budi.ID).Exp); } }
public async Task WhenThereIsDraw_SendMessagesToBothPlayers_AndRemoveGameSession() { int x = 0, y = 0; var senderMock = new Mock <IPlayer>(MockBehavior.Strict); var opponentMock = new Mock <IPlayer>(MockBehavior.Strict); var sessionMock = new Mock <IGameSession>(MockBehavior.Strict); var senderSocketMock = new Mock <IWebSocket>(MockBehavior.Strict); var opponentSocketMock = new Mock <IWebSocket>(MockBehavior.Strict); var gameMove = new TicTacToeMove(x, y); senderMock.SetupGet(p => p.Socket).Returns(senderSocketMock.Object); opponentMock.SetupGet(p => p.Socket).Returns(opponentSocketMock.Object); sessionMock.SetupGet(s => s.PlayerOne).Returns(senderMock.Object); sessionMock.SetupGet(s => s.PlayerTwo).Returns(opponentMock.Object); sessionMock.Setup(s => s.Play(senderMock.Object, gameMove)) .Returns(PlayResult.Draw); collectionsMock.Setup(c => c.FindSessionOfAPlayer( It.Is <IPlayer>(p => p == senderMock.Object))) .Returns(sessionMock.Object); collectionsMock.Setup(c => c.RemoveSession(sessionMock.Object)); msgSenderMock.Setup(m => m.SendMessageAsync(It.IsAny <IWebSocket>(), It.IsAny <MoveResultMessage>())) .Returns(Task.Delay(0)); var handler = new MakeMoveHandler(collectionsMock.Object, loggerMock.Object, msgSenderMock.Object); await handler.HandleMessageAsync(senderMock.Object, new MakeMoveMessage() { X = x, Y = y }); msgSenderMock.Verify(m => m.SendMessageAsync( It.Is <IWebSocket>(s => s == senderSocketMock.Object), It.Is <MoveResultMessage>( m => m.Message == PlayResult.Draw.ToString() || m.X == x || m.Y == y))); msgSenderMock.Verify(m => m.SendMessageAsync( It.Is <IWebSocket>(s => s == opponentSocketMock.Object), It.Is <MoveResultMessage>( m => m.Message == PlayResult.Draw.ToString() || m.X == x || m.Y == y))); collectionsMock.Verify(c => c.RemoveSession(sessionMock.Object)); }
/// <summary> /// Undoes a move. /// </summary> /// <param name="move">The move.</param> public void UndoMove(TicTacToeMove move) { if (!this.IsOnBoard(move.Position)) { throw new InvalidMoveException(this.language.GetWord("CantUndoAMoveOnAnInvalidSquare") ?? string.Empty); } // Just reset the position var p = GetPoint(move.Position); this.board[p.X, p.Y] = 0; }
public void GameMoveFactoryTest() { // Arrange IGameMove expectedMove = new TicTacToeMove(TicTacToePlayer.O, new TicTacToeCell(0, 0)); string serializedMove = JsonConvert.SerializeObject(expectedMove); Factory factory = new Factory(); // Act IGameMove result = factory.GameMoveFactory("TicTacToe", serializedMove); // Assert Assert.AreEqual(typeof(TicTacToeMove), result.GetType()); Assert.AreEqual(JsonConvert.SerializeObject(expectedMove), JsonConvert.SerializeObject(result)); }
public TicTacToeGameState(string stateString, ref BST <GameState> tree) { int position = 0; int idLength = GetIntFromString(stateString, ref position, 2); int numDigits; for (int i = 0; i < idLength; i++) { numDigits = GetIntFromString(stateString, ref position, 2); if (idLength > 1) { stateId[i] = GetIntFromString(stateString, ref position, numDigits); } } stateTree = tree; int playerTurn = GetIntFromString(stateString, ref position, 1); player1Turn = playerTurn == 1 ? true : false; numDigits = GetIntFromString(stateString, ref position, 1); winProbability1 = GetDoubleFromString(stateString, ref position, numDigits); numDigits = GetIntFromString(stateString, ref position, 1); winProbability2 = GetDoubleFromString(stateString, ref position, numDigits); numDigits = GetIntFromString(stateString, ref position, 2); winCount = GetIntFromString(stateString, ref position, numDigits); numDigits = GetIntFromString(stateString, ref position, 2); lossCount = GetIntFromString(stateString, ref position, numDigits); numDigits = GetIntFromString(stateString, ref position, 2); gameCount = GetIntFromString(stateString, ref position, numDigits); if (position >= (stateString.Length - 1)) { bestMove = null; statePossibleMoves = new Move[0]; } else { bestMove = new TicTacToeMove(stateString.Substring(position, 5)); position += 5; int count = (stateString.Length - position) / 5; statePossibleMoves = new Move[count]; for (int i = 0; i < count; i++) { statePossibleMoves[i] = new TicTacToeMove(stateString.Substring(position, 5)); position += 5; } } }
public void OneMoveToWinTheGame() { var game = TicTacToeGame.Classic; game.State.SetCell(1, 1, Player.Maximizing); game.State.SetCell(2, 0, Player.Maximizing); game.State.NextMovePlayer = Player.Maximizing; EngineResult aiResult = _ai.Analyse(game); TicTacToeMove bestMove = aiResult.BestMove as TicTacToeMove; Assert.AreEqual(0, bestMove.X); Assert.AreEqual(2, bestMove.Y); }
public void KeepTrackOfCorrectMoves_MarkSamePosition() { _game.CurrentMove.Should().Be(_playerB.Mark); var move = new TicTacToeMove(_playerB, 0, 0); var result = _game.MakeMove(move); result.Should().BeTrue(); _game.CurrentMove.Should().Be(_playerA.Mark); var illegalMove = _game.MakeMove(_playerA, 0, 0); // same coords illegalMove.Should().BeFalse(); }
/// <inheritdoc cref="Node"/> /// <summary> /// Generates the node's children. Minimum nodes have maximum children. /// </summary> /// <seealso cref="Node"/> protected override void GenerateChildren() { if (this.Board is null) { throw new ArgumentNullException(nameof(this.Board), "The board wasn't initialized properly."); } var openPositions = this.Board.OpenPositions; foreach (var i in openPositions) { var b = (Board)this.Board.Clone(); var m = new TicTacToeMove(i, this.MyPieceLocal); b.MakeMove(i, this.MyPieceLocal); this.Children.Add(new MaximumNode(b, this, m)); } }
/// <summary> /// Makes the move for the specified player. /// </summary> /// <param name="m">The move to make.</param> /// <param name="p">The player making the move.</param> private void MakeMove(TicTacToeMove m, Players p) { if (this.CurrentPlayerTurn != p) { throw new InvalidMoveException(this.language.GetWord("OutOfTurn") ?? string.Empty); } if (!this.GameBoard.IsValidSquare(m.Position)) { throw new InvalidMoveException(this.language.GetWord("PickASquare") ?? string.Empty); } if (!Enum.IsDefined(typeof(Players), p)) { throw new InvalidEnumArgumentException(nameof(p), (int)p, typeof(Players)); } this.GameBoard.MakeMove(m.Position, m.Piece); this.moves.Push(m); this.SwapTurns(); }
protected TicTacToeMove GetMoveForPlayer(Player p) { lastMove = null; // playerThread = new Thread(p.Move); // playerThread.Start(game.GameBoard); // if (!xturn) { // computer p.Move(game.GameBoard); // make the change on the board lastMove = p.CurrentMove; var row = lastMove.Position / 3; var col = lastMove.Position - (row * 3); var square = squares [row, col]; square.Text = xturn ? "X" : "O"; // } // register a listener // p.PlayerMoved += new PlayerMovedHandler(player_PlayerMoved); // // // p.Move (game.GameBoard); // computer only // // // // lastMove is assigned in the player_PlayerMoved handler // while (lastMove == null) // ; // // // if we get here the player moved // // // unregister the listenter // p.PlayerMoved -= player_PlayerMoved; // kill the thread //playerThread.Abort(); return(p.CurrentMove); }
public override TicTacToeMove NextMove(TicTacToeGameState gameState) { // Can I win? TicTacToeMove winningMove = this.CheckForWin(gameState, this.BoardValue); // Can they win? TicTacToeBoardValue otherBoardValue = this.BoardValue == TicTacToeBoardValue.O ? TicTacToeBoardValue.X : TicTacToeBoardValue.O; TicTacToeMove blockingMove = this.CheckForWin(gameState, otherBoardValue); // Can I play a corner? TicTacToeMove cornerMove = new TicTacToeMove[] { new TicTacToeMove(0, 0), new TicTacToeMove(0, 2), new TicTacToeMove(2, 0), new TicTacToeMove(2, 2) }.OrderBy(move => Guid.NewGuid()).FirstOrDefault(move => gameState.Board.IsValidMove(move)); // play best move return(winningMove ?? blockingMove ?? cornerMove ?? base.NextMove(gameState)); }
public IGameMove DoMove(IGameState state) { var states = state.GameMoves; TicTacToeMove lastState = (TicTacToeMove)states[states.Length - 1]; for (int r = 0; r < lastState.Board.Length; r++) { ImmutableArray <string> row = lastState.Board[r]; for (int c = 0; c < row.Length; c++) { if (String.IsNullOrWhiteSpace(row[c])) { ImmutableArray <string> newRow = row.SetItem(c, this.Id); ImmutableArray <ImmutableArray <string> > newBoard = lastState.Board.SetItem(r, newRow); return(new TicTacToeMove(this.Id, newBoard)); } } } // If we got here then there was no valid move for us to make return(lastState); }
private float EvalCandidate(Network candidate) { var game = gameFactory.Invoke(); do { var outputs = candidate.Compute(game.GetState()); var move = new TicTacToeMove { Index = (int)outputs[0], Value = 1 }; // if the NN attempts an illegal move it loses immediately if (!game.TryMove(move)) { return(0.0f); } // TODO: get an opponent // TODO: get the opponent to move // TODO: if the opponent makes an illegal move the candidate wins immediately }while (!game.HasEnded()); return(game.Score.GetValueOrDefault()); }
/// <inheritdoc cref="EventArgs"/> /// <summary> /// Initializes a new instance of the <see cref="PlayerMovedArgs"/> class. /// </summary> /// <param name="m">The move to make.</param> /// <seealso cref="EventArgs"/> public PlayerMovedArgs(TicTacToeMove m) { this.Move = m; }
public PlayerMoveHandler(PlayerInfo player, TicTacToeMove NextMove) : base(player) { MoveToExecute = NextMove; }