public IActionResult Index()
        {
            TicTacToeBoard board = new TicTacToeBoard();
            List <Cell>    cells = board.GetCells();

            foreach (Cell cell in cells)
            {
                cell.Mark = TempData[cell.Id]?.ToString();
            }
            board.CheckForWinner();

            TicTacViewModel model = new TicTacViewModel
            {
                Cells    = cells,
                Selected = new Cell {
                    Mark = TempData["nextTurn"]?.ToString() ?? "X"
                },
                IsGameOver = board.HasWinner || board.HasAllCellsSelected
            };

            if (model.IsGameOver)
            {
                TempData["nextTurn"] = "X";
                TempData["message"]  = board.HasWinner ? $"{board.WinningMark} wins" : "Its a tie";
            }
            else
            {
                TempData.Keep();
            }
            return(View(model));
        }
Exemple #2
0
    public int NegaMax(TicTacToeBoard game, Marker player, int depth)
    {
        int maxScore = -1;
        int sign     = 1;

        if (game.CheckForWinner(game.Board, Marker.X))        // return score/move
        {
            return(StaticEvaluation(Marker.X));
        }
        else if (game.CheckForWinner(game.Board, Marker.O))
        {
            return(StaticEvaluation(Marker.O));
        }
        else if (game.CheckForDraw(game.Board))          //return score/move
        {
            return(StaticEvaluation(Marker.Blank));
        }

        if (player != Marker.X)
        {
            sign = -1;
        }

        List <Vector2> moves    = game.FindBlankCells(game.Board);
        TicTacToeBoard gameCopy = new TicTacToeBoard();
        int            score    = 0;

        foreach (Vector2 nextMove in moves)
        {
            gameCopy.Board = gameCopy.CopyBoard(game.Board);
            gameCopy.PlaceMarker(gameCopy.Board, player, nextMove);
            score = sign * NegaMax(gameCopy, gameCopy.GetOppositeMarker(player), depth + 1);
            if (score > maxScore)
            {
                maxScore = score;
            }
        }
        return(maxScore * sign);
    }
Exemple #3
0
    public void PlayTicTacToe( )
    {
        if (IsGameover == false)
        {
            if (p1_X == null || p2_O == null)
            {
                return;
            }

            if (p1_X.IsTurnActive == true)
            {
                if (timed == false)
                {
                    t     = turnDelay + Time.time;
                    timed = true;
                }

                if (Time.time < t)
                {
                    return;
                }
                timed = false;

                TicTacToeMove bestMove = null;

                if (isSearching == false)
                {
                    bestMove    = p1_X.NegaMaxMove(board); // NEGAMAX tree-search
                    isSearching = true;
                }

                if (bestMove != null)
                {
                    FireRandomScribbleSFX( );
                    boardState[(int)bestMove.Cell.x][(int)bestMove.Cell.y] = Marker.X;

                    cells[bestMove.Cell].GetComponent <SpriteRenderer>().sprite = Resources.Load <Sprite> (ResourcePath.x);

                    p1_X.IsTurnActive = false;
                    p2_O.IsTurnActive = true;

                    if (board.CheckForWinner(boardState, Marker.X))
                    {
                        GameWinner         = "You lost!";
                        WinningCoordinates = board.WinningCoordinates;
                        IsGameover         = true;
                    }
                    if (board.CheckForDraw(boardState))
                    {
                        GameWinner         = "A draw - better than losing.";
                        WinningCoordinates = null;
                        IsGameover         = true;
                    }

                    isSearching = false;
                }
                else
                {
                    Debug.Log("AI is searching for a move ... ");
                    return;
                }
            }
            else if (p2_O.IsTurnActive == true)
            {
                GameObject clicked = p2_O.ClickHandler <Grid2DVertexComponent> ( );

                if (clicked == null)
                {
                    return;
                }

                Vector2 m = clicked.transform.position;
                if (boardState[(int)m.x][(int)m.y] == Marker.Blank)       //move success
                {
                    FireRandomScribbleSFX( );
                    boardState[(int)m.x][(int)m.y] = Marker.O;

                    clicked.GetComponent <SpriteRenderer> ( ).sprite = Resources.Load <Sprite> (ResourcePath.o);

                    if (board.CheckForWinner(boardState, Marker.O))
                    {
                        GameWinner         = "You won!";
                        WinningCoordinates = board.WinningCoordinates;
                        IsGameover         = true;
                    }
                    if (board.CheckForDraw(boardState))
                    {
                        GameWinner         = "A draw - better than losing.";
                        WinningCoordinates = null;
                        IsGameover         = true;
                    }

                    p2_O.IsTurnActive = false;
                    p1_X.IsTurnActive = true;
                }
            }
        }
        else
        {
            Debug.Log("GAMEOVER");
        }
    }