2016-12-24 131 views
-1

美好的一天!我试图实现minimax算法无济于事。 想引导你到包含minimax函数的computerMove函数。 AI不响应我的输入。在井字游戏中实施Minimax Algo

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(); 

正如你在上面看到的。

+0

至于我可以看到你的'computerMove'函数声明一'minimax'功能,但实际上并没有以任何方式使用它... – Chris

+0

哦!你的意思是我宣布了一个没有打电话的功能吗? –

+0

它看起来确实如此! – Chris

回答

0

我实际上编写了一篇关于GeeksForGeeks的文章,它解释了如何使用Minimax来实现针对井字游戏的AI。我还包括一个C++实现是超级容易理解

enter image description here

如果你想了解如何极小的作品,你就可以开始here

+0

谢谢您的回复!我试图在javascript中实现它。不能在我的代码中找到错误。 –