在Tic Tac Toe实施Minimax Algo

时间:2016-12-24 06:16:13

标签: javascript jquery algorithm

美好的一天!我试图实现minimax算法无济于事。 想引导您到包含minimax函数的computerMove函数。 人工智能没有回应我的意见。

function Game() {
    var _this = this,
        moves,
        running,
        playerPiece,
        computerPiece,
        playerTurn,
        playerMoves,
        computerMoves,
        winner,
        overlay = $(".overlay"),
        chooseButton = $(".overlay button"),
        box = $(".box"),
        announcement = $(".title"),
        winConditions = [
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9],
            [1, 4, 7],
            [2, 5, 8],
            [3, 6, 9],
            [1, 5, 9],
            [3, 5, 7]
        ];
    this.init = function() {
        moves = 9; // max no. of moves
        running = false; //status of game
        playerPiece = ""; //piece of player
        computerPiece = ""; // piece of computer
        playerTurn = false; //computer always go first
        playerMoves = []; //stores player moves
        computerMoves = []; // stores computer moves
        winner = ""; //stores winner - Computer/Player
        chooseButton.off("click"); //removes event listeners
        box.off("click"); //removes event listeners
        box.html("") //clears out the board for fresh start
        choosePiece();
    }; //resets everything

    function choosePiece() {
        if (!running) {
            chooseButton.on("click", function() {
                playerPiece = $(this).text();
                computerPiece = playerPiece === 'X' ? 'O' : 'X';
                playerTurn = playerPiece === 'X' ? true : false; //allow X to go first.
                overlay.toggle("clip");
                startGame(); //after choice is made, initialise game with startGame function.
            });
        }
    }

    function startGame() {
        running = true;
        //player doesn't go first, computer does
        if (!playerTurn) {
            setTimeout(computerMove, 500);
        }
        box.click(function() {
            if (occupiedSpace().indexOf(posNum($(this))) !== -1) return; //if box is occupied, nothing happens.

            if (running && playerTurn) {
                $(this).html("<p class='player'>" + playerPiece + "</p>");
                playerMoves.push(posNum($(this)));
                //checks whether player won
                if (checkWin(playerMoves)) {
                    setTimeout(function() {
                        winner = "player";
                        running = false;
                        announcement.text("you won!");
                        _this.init(); //restarts the game
                    });
                }

                moves--; //no winner, continues.
                if (moves === 0) {
                    setTimeout(function() {
                        winner = "draw";
                        running = false;
                        announcement.text("Draw!");
                        _this.init();
                    }, 500);
                } //no more moves left, draw and restart
                playerTurn = false;
                setTimeout(computerMove, 500);
            }
        });

    } // initialises the game

    function computerMove() {

        var score = 0;
        var possibleMoves = [];

        function minimax(playerTurn, moves) {
            if (moves === 0) {
                if (checkWin(computerMoves)) {
                    return 10;
                } else if (checkWin(playerMoves)) {
                    return -10;
                } else {
                    return 0;
                }
            }

            var avail = openSpaces();
            if (!playerTurn) { //computer turn
                for (var i = 0; i < avail.length; i++) {
                    computerMoves.push(avail[i]);
                    var cBest = minimax(playerTurn, moves--);
                    if (cBest > score) {
                        score = cBest;
                        possibleMoves.push(avail[i]);
                    }
                }
            }
            if (playerTurn) { //player turn
                for (var j = 0; j < avail.length; j++) {
                    playerMoves.push(avail[j]);
                    var pBest = minimax(!playerTurn, moves--);
                    if (pBest < score) {
                        score = pBest;
                    }
                }
            }
        }
        var chosen = possibleMoves[0];
        $('.pos' + chosen).html("<p class='computer'>" + computerPiece + "</p>");
    } //AI
    function checkWin(arrays) {
        var result = false;
        if (arrays.length <= -3) return; //if a party makes less than 3 moves no way in hell they gon win. Makes code more efficient.
        winConditions.forEach(function(winArray) {
            var holdArr = winArray.filter(function(winNum) {
                if (arrays.indexOf(winNum) > -1) return false;
                return true;
            });
            if (holdArr.length === 0) result = true;
        });
        return result;
    } // checks against the winConditions

    function openSpaces() {
        var open = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        occupiedSpace().forEach(function(num) {
            open = open.filter(function(spots) {
                if (spots === num) return false;
                return true;
            });
        });
    } //returns array of availble spaces

    function occupiedSpace() {
        return playerMoves.concat(computerMoves);
    } //returns array of occupied spaces

    function posNum(div) {
        return parseInt(div.attr('class').split(' ')[2].split('')[3]);
    } // returns the number of the box selected


}

var ticTacToe = new Game();
ticTacToe.init();

如上所示。

1 个答案:

答案 0 :(得分:0)

我实际上写了一篇关于GeeksForGeeks的文章,解释了如何使用Minimax为Tic-Tac-Toe实现AI。我还包括一个非常容易理解的C ++实现

enter image description here

如果您想了解minimax的工作原理,可以启动here