JavaScript如何通过极大极小值算法实现AI井字棋游戏,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
话不多说直接上运行截图:
黑棋是玩家的位置,红色方是电脑。电脑会根据当前棋盘的情况选择一个对自己有利却对玩家不利的情况。
算法可以实现电脑胜利,或者电脑和玩家平局。
代码如下:
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>井字棋AI</title><style>.title {text-align: center;}.chess {display: block;margin: 50px auto;box-shadow: 5px 5px 5px #B9B9B9, -2px -2px 2px #EFEFEF;cursor: pointer;}div {text-align: center;}.restart {padding: 10px 20px;background-color: #EE82EE;border-radius: 5px;color: white;cursor: pointer;}</style></head> <body><h4 class="title">--井字棋--</h4><canvas class="chess" width="450px" height="450px"></canvas><div><a class="restart" onclick="rst()">重新开始</a></div></body> <script>var chess = document.getElementsByClassName("chess")[0];var title = document.getElementsByClassName("title")[0];var context = chess.getContext("2d");context.strokeStyle = "#B9B9B9" window.onload = function() {drawChessBoard();Init()} function drawChessBoard() {for(var i = 0; i < 4; i++) {//设置横线起始点坐标context.moveTo(15, 15 + i * 140)//设置横线结束点坐标context.lineTo(435, 15 + i * 140)//连接2点context.stroke();//设置竖线context.moveTo(15 + i * 140, 15)//设置横线结束点坐标context.lineTo(15 + i * 140, 435)//连接2点context.stroke();}} //定义二维数组标记棋子var chessboard = []for(var i = 0; i < 4; i++) {chessboard[i] = [];for(var j = 0; j < 4; j++) {chessboard[i][j] = 0;}} const NUMBER = 3const STEP = 9const MAN = 1const COMPUTER = -1const SEARCHDEPTH = 9const INT_MAX = 999999const INT_MIN = -1000000 var player = 0var isGameOver = falsevar currentDepth = 0var bestPosition = {x: 0,y: 0} function Init() {for(let i = 0; i < NUMBER; i++) {for(let j = 0; j < NUMBER; j++) {chessboard[i][j] = 0}}player = MANisGameOver = falsecurrentDepth = 0} function isEnd() {let i = 0let j = 0var count = 0for(i = 0; i < NUMBER; i++) { //行count = 0;for(j = 0; j < NUMBER; j++)count += chessboard[i][j];if(count == 3 || count == -3)return count / 3;}for(j = 0; j < NUMBER; j++) { //列count = 0;for(i = 0; i < NUMBER; i++)count += chessboard[i][j];if(count == 3 || count == -3)return count / 3;}count = 0;count = chessboard[0][0] + chessboard[1][1] + chessboard[2][2];if(count == 3 || count == -3)return count / 3;count = chessboard[0][2] + chessboard[1][1] + chessboard[2][0];if(count == 3 || count == -3)return count / 3;return 0;} function MaxMinSearch(depth) {var value = 0;if(player == MAN) value = INT_MIN;if(player == COMPUTER) value = INT_MAX;if(isEnd() != 0) {return Evaluate();}if(depth == SEARCHDEPTH) {value = Evaluate();return value;} for(let i = 0; i < NUMBER; i++) {for(let j = 0; j < NUMBER; j++) {if(chessboard[i][j] == 0) {if(player == MAN) {chessboard[i][j] = MAN;player = COMPUTER;var nextvalue = MaxMinSearch(depth + 1);player = MAN;if(value < nextvalue) {value = nextvalue;if(depth == currentDepth) {bestPosition.x = i;bestPosition.y = j;} } } else if(player == COMPUTER) {chessboard[i][j] = COMPUTER;player = MAN;var nextvalue = MaxMinSearch(depth + 1);player = COMPUTER;if(value > nextvalue) {value = nextvalue;if(depth == currentDepth) {bestPosition.x = i;bestPosition.y = j;} }}chessboard[i][j] = 0;} }} return value;}function Logic(){if (isGameOver) {if (isEnd() == MAN) {alert("游戏结束 玩家胜利")} else if (isEnd() == COMPUTER) {alert("游戏结束 电脑胜利")} else {alert("游戏结束 平局")}}} function Evaluate() {var value = isEnd();if(value == MAN) return INT_MAX;if(value == COMPUTER) return INT_MIN;} chess.onclick = function(event) {if(player != MAN) {return;}//获取坐标var x = event.offsetX;var y = event.offsetY; x = Math.trunc((x - 15) / 140)y = Math.trunc((y - 15) / 140) ManPlay(x, y)if(isEnd() == 0 && currentDepth < 8) {ComputerPlay()if(isEnd() != 0) {isGameOver = true}} else {isGameOver = true}Logic()} function ManPlay(x, y) {chessboard[x][y] = MANDrawBroad(x,y,MAN)currentDepth++player = COMPUTER} function ComputerPlay() {MaxMinSearch(currentDepth)chessboard[bestPosition.x][bestPosition.y] = COMPUTERDrawBroad(bestPosition.x,bestPosition.y,COMPUTER)currentDepth++player = MAN} //落子时绘画棋盘function DrawBroad(i, j, player) {context.beginPath();context.arc(85 + i * 140, 85 + j * 140, 40, 0, 2 * Math.PI); //画圆context.closePath(); var color;if(player == MAN) {color = "#000";} else {color = "red"}context.fillStyle = color;context.fill();} function rst() {window.location.reload();}</script> </html>
其中,代码的242行和244行中的
context.beginPath();context.arc(85 + i * 140, 85 + j * 140, 40, 0, 2 * Math.PI); //画圆context.closePath();
分别是落笔和抬笔的操作。这样可以避免canvas上画圆时路径相连的问题。
关于JavaScript如何通过极大极小值算法实现AI井字棋游戏问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。