【前端】AI五子棋游戏186行

2024-04-18 16:04

本文主要是介绍【前端】AI五子棋游戏186行,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这个来源于网上,不过代码改了不少,减少了些代码便于学习。 

<!DOCTYPE html>
<html><body><h3>AI五子棋游戏</h3><canvas id="chess" width="450px" height="450px"></canvas><script>var chressBord = []; //棋盘			var wins = [];  //存放所有5个棋子在一条线上所有可能性,第一维存放y, 第二维存放x,第三维存放当前的可能性编号var count = 0; //赢法总数量var myWin = []; //我们赢法的统计数组var computerWin = []; //计算机赢法的统计数组var chess = document.getElementById("chess");var context = chess.getContext('2d');for(var i = 0; i < 15; i++){chressBord[i] = [];wins[i] = [];for(var j = 0; j < 15; j++){chressBord[i][j] = 0;wins[i][j] = [];}}//横线赢法for(var i = 0; i < 15; i++)for(var j = 0; j < 11; j++,count++)for(var k = 0; k < 5; k++)wins[i][j+k][count] = true;//竖线赢法for(var i = 0; i < 15; i++)for(var j = 0; j < 11; j++,count++)for(var k = 0; k < 5; k++)wins[j+k][i][count] = true;//正斜线赢法for(var i = 0; i < 11; i++)for(var j = 0; j < 11; j++,count++)for(var k = 0; k < 5; k++)wins[i+k][j+k][count] = true;//反斜线赢法for(var i = 0; i < 11; i++)  for(var j = 14; j > 3; j--,count++)for(var k = 0; k < 5; k++)wins[i+k][j-k][count] = true;for(var i = 0; i < count; i++){myWin[i] = 0; //这个数组很精髓,记录下棋后我方每一个位置在每种赢法的得分computerWin[i] = 0;}chess.onclick = function(e) // 我,下棋{var i = Math.floor(e.offsetX / 30);var j = Math.floor(e.offsetY / 30);if(chressBord[i][j] == 0){MoveStep(i,j,"red", 1, myWin);computerAI();}         }// 计算机下棋,找玩家最容易赢的位置或者电脑最容易赢的位置var computerAI = function (){var myScore = [];var computerScore = [];var max = 0;var u = 0, v = 0;for(var i = 0; i < 15; i++){myScore[i] = [];computerScore[i] = [];for(var j = 0; j < 15; j++){myScore[i][j] = 0;computerScore[i][j] = 0;}}//找落子赢的概率最大坐标for(var i = 0; i < 15; i++){for(var j = 0; j < 15; j++){						for(var k = 0; k < count; k++) //遍历到i,j这个坐标时,计算谁的得分更高{if(chressBord[i][j] != 0 || !wins[i][j][k]) //当前i,j坐标还没落子continue;switch(myWin[k]){case 1: myScore[i][j] += 200; break;case 2: myScore[i][j] += 400; break;case 3: myScore[i][j] += 2000; break;case 4: myScore[i][j] += 10000; break;}switch(computerWin[k]){case 1: computerScore[i][j] += 220; break;case 2: computerScore[i][j] += 420; break;case 3: computerScore[i][j] += 2100; break;case 4: computerScore[i][j] += 20000; break;}}if(myScore[i][j] > max) //如果玩家落子的分数多,就替换{max  = myScore[i][j];u = i;v = j;}else if(myScore[i][j] == max)  //如果玩家落子的分数跟原来最多分数一样多{if(computerScore[i][j] > computerScore[u][v]) //如果电脑在i,j落子的分数比u,v的分数多,就替换{u = i;v = j;    }}if(computerScore[i][j] > max) //如果电脑下棋新位置分数比原来的多,就替换{max  = computerScore[i][j];u = i;v = j;}else if(computerScore[i][j] == max) //如果电脑下棋新位置分数跟原来的一样多{if(myScore[i][j] > myScore[u][v]) //如果玩家落子的分数多,就准备把玩家最好的位置占掉{u = i;v = j;    }}}}MoveStep(u,v,"blue", 2, computerWin);}var CheckWin = function(i, j, Role, WinArray){			for(var k = 0; k < count; k++)if(wins[i][j][k]) // 将可能赢的情况都加1{WinArray[k]++;if(WinArray[k] >= 5)alert(Role + ': 恭喜,你赢了!')}}//绘画棋盘var drawChessBoard = function() {for(var i = 0; i < 15; i++){context.moveTo(15 + i * 30 , 15);context.lineTo(15 + i * 30 , 435);context.moveTo(15 , 15 + i * 30);context.lineTo(435 , 15 + i * 30);context.stroke();}}drawChessBoard(); // 画棋盘var MoveStep = function(i,j,Role, ID, WinArray) //落子{context.beginPath();context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);// 画圆context.closePath();    context.fillStyle = Role;context.fill(); //填充颜色chressBord[i][j] = ID; //玩家ID棋盘位置占位CheckWin(i,j,Role, WinArray);  //判断是否获胜,这里也很精髓,递归思想}</script></body>
</html>

附原来的代码:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>AI五子棋游戏</title><style type='text/css'>canvas {display: block;margin: 50px auto;box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;cursor: pointer;}.btn-wrap { display: flex; flex-direction: row; justify-content:center;}.btn-wrap div { margin: 0 10px;}div>span {display: inline-block;padding: 10px 20px;color: #fff;background-color: #EE82EE;border-radius: 5px;cursor: pointer;}div.unable span { background: #D6D6D4; color: #adacaa;}#result-wrap {text-align: center;}</style></head><body><h3 id="result-wrap">AI五子棋</h3><canvas id="chess" width="450px" height="450px"></canvas><div class="btn-wrap"><div id='restart' class="restart"><span>重新开始</span></div><div id='goback' class="goback unable"><span>悔棋</span></div><div id='return' class="return unable"><span>撤销悔棋</span></div></div><script type="text/javascript" charset="utf-8">var over = false;var me = true; //我var _nowi = 0, _nowj = 0; //记录自己下棋的坐标var _compi = 0, _compj = 0; //记录计算机当前下棋的坐标var _myWin = [], _compWin = []; //记录我,计算机赢的情况var backAble = false, returnAble = false; var resultTxt = document.getElementById('result-wrap');var chressBord = [];//棋盘for(var i = 0; i < 15; i++){chressBord[i] = [];for(var j = 0; j < 15; j++){chressBord[i][j] = 0;}}//赢法的统计数组var myWin = [];var computerWin = [];//赢法数组var wins = [];for(var i = 0; i < 15; i++){wins[i] = [];for(var j = 0; j < 15; j++){wins[i][j] = [];}}var count = 0; //赢法总数//横线赢法for(var i = 0; i < 15; i++){for(var j = 0; j < 11; j++){for(var k = 0; k < 5; k++){wins[i][j+k][count] = true;}count++;}}//竖线赢法for(var i = 0; i < 15; i++){for(var j = 0; j < 11; j++){for(var k = 0; k < 5; k++){wins[j+k][i][count] = true;}count++;}}//正斜线赢法for(var i = 0; i < 11; i++){for(var j = 0; j < 11; j++){for(var k = 0; k < 5; k++){wins[i+k][j+k][count] = true;}count++;}}//反斜线赢法for(var i = 0; i < 11; i++){ for(var j = 14; j > 3; j--){for(var k = 0; k < 5; k++){wins[i+k][j-k][count] = true;}count++;}}// debugger;for(var i = 0; i < count; i++){myWin[i] = 0;_myWin[i] = 0;computerWin[i] = 0;_compWin[i] = 0;}var chess = document.getElementById("chess");var context = chess.getContext('2d');context.strokeStyle = '#bfbfbf'; //边框颜色var backbtn = document.getElementById("goback");var returnbtn = document.getElementById("return");window.onload = function(){drawChessBoard(); // 画棋盘}document.getElementById("restart").onclick = function(){window.location.reload();}// 我,下棋chess.onclick = function(e){if(over){return;}if(!me){return;}// 悔棋功能可用backbtn.className = backbtn.className.replace( new RegExp( "(\\s|^)unable(\\s|$)" )," " ); var x = e.offsetX;var y = e.offsetY;var i = Math.floor(x / 30);var j = Math.floor(y / 30);_nowi = i;_nowj = j;if(chressBord[i][j] == 0){oneStep(i,j,me);chressBord[i][j] = 1; //我,已占位置        for(var k = 0; k < count; k++){ // 将可能赢的情况都加1if(wins[i][j][k]){// debugger;myWin[k]++;_compWin[k] = computerWin[k];computerWin[k] = 6;//这个位置对方不可能赢了if(myWin[k] == 5){// window.alert('你赢了');resultTxt.innerHTML = '恭喜,你赢了!';over = true;}}}if(!over){me = !me;computerAI();}}         }// 悔棋backbtn.onclick = function(e){if(!backAble) { return;}over = false;me = true;// resultTxt.innerHTML = 'o(╯□╰)o,悔棋中';// 撤销悔棋功能可用returnbtn.className = returnbtn.className.replace( new RegExp( "(\\s|^)unable(\\s|$)" )," " ); // 我,悔棋chressBord[_nowi][_nowj] = 0; //我,已占位置 还原minusStep(_nowi, _nowj); //销毁棋子                                  for(var k = 0; k < count; k++){ // 将可能赢的情况都减1if(wins[_nowi][_nowj][k]){myWin[k]--;computerWin[k] = _compWin[k];//这个位置对方可能赢}}// 计算机相应的悔棋chressBord[_compi][_compj] = 0; //计算机,已占位置 还原minusStep(_compi, _compj); //销毁棋子                                  for(var k = 0; k < count; k++){ // 将可能赢的情况都减1if(wins[_compi][_compj][k]){computerWin[k]--;myWin[k] = _myWin[i];//这个位置对方可能赢}}resultTxt.innerHTML = '--益智五子棋--';returnAble = true;backAble = false;}// 撤销悔棋returnbtn.onclick = function(e){if(!returnAble) { return; }// 我,撤销悔棋chressBord[_nowi][_nowj] = 1; //我,已占位置 oneStep(_nowi,_nowj,me);                              for(var k = 0; k < count; k++){ if(wins[_nowi][_nowj][k]){myWin[k]++;_compWin[k] = computerWin[k];computerWin[k] = 6;//这个位置对方不可能赢}if(myWin[k] == 5){resultTxt.innerHTML = '恭喜,你赢了!';over = true;}}// 计算机撤销相应的悔棋chressBord[_compi][_compj] = 2; //计算机,已占位置   oneStep(_compi,_compj,false);                               for(var k = 0; k < count; k++){ // 将可能赢的情况都减1if(wins[_compi][_compj][k]){computerWin[k]++;_myWin[k] = myWin[k];myWin[k] = 6;//这个位置对方不可能赢}if(computerWin[k] == 5){resultTxt.innerHTML = 'o(╯□╰)o,计算机赢了,继续加油哦!';over = true;}}returnbtn.className += ' '+ 'unable';returnAble = false;backAble = true;}// 计算机下棋var computerAI = function (){var myScore = [];var computerScore = [];var max = 0;var u = 0, v = 0;for(var i = 0; i < 15; i++){myScore[i] = [];computerScore[i] = [];for(var j = 0; j < 15; j++){myScore[i][j] = 0;computerScore[i][j] = 0;}}for(var i = 0; i < 15; i++){for(var j = 0; j < 15; j++){if(chressBord[i][j] == 0){for(var k = 0; k < count; k++){if(wins[i][j][k]){if(myWin[k] == 1){myScore[i][j] += 200;}else if(myWin[k] == 2){myScore[i][j] += 400;}else if(myWin[k] == 3){myScore[i][j] += 2000;}else if(myWin[k] == 4){myScore[i][j] += 10000;}if(computerWin[k] == 1){computerScore[i][j] += 220;}else if(computerWin[k] == 2){computerScore[i][j] += 420;}else if(computerWin[k] == 3){computerScore[i][j] += 2100;}else if(computerWin[k] == 4){computerScore[i][j] += 20000;}                        }}if(myScore[i][j] > max){max  = myScore[i][j];u = i;v = j;}else if(myScore[i][j] == max){if(computerScore[i][j] > computerScore[u][v]){u = i;v = j;    }}if(computerScore[i][j] > max){max  = computerScore[i][j];u = i;v = j;}else if(computerScore[i][j] == max){if(myScore[i][j] > myScore[u][v]){u = i;v = j;    }}}}}_compi = u;_compj = v;oneStep(u,v,false);chressBord[u][v] = 2;  //计算机占据位置for(var k = 0; k < count; k++){if(wins[u][v][k]){computerWin[k]++;_myWin[k] = myWin[k];myWin[k] = 6;//这个位置对方不可能赢了if(computerWin[k] == 5){resultTxt.innerHTML = 'o(╯□╰)o,计算机赢了,继续加油哦!';over = true;}}}if(!over){me = !me;}backAble = true;returnAble = false;var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' ');if(!hasClass) {returnbtn.className += ' ' + 'unable';}}//绘画棋盘var drawChessBoard = function() {for(var i = 0; i < 15; i++){context.moveTo(15 + i * 30 , 15);context.lineTo(15 + i * 30 , 435);context.stroke();context.moveTo(15 , 15 + i * 30);context.lineTo(435 , 15 + i * 30);context.stroke();}}//画棋子var oneStep = function(i,j,me) {context.beginPath();context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);// 画圆context.closePath();//渐变var gradient = context.createRadialGradient(15 + i * 30 + 2, 15 + j * 30 - 2, 13, 15 + i * 30 + 2, 15 + j * 30 - 2, 0);if(me){gradient.addColorStop(0,'#0a0a0a');gradient.addColorStop(1,'#636766');}else{gradient.addColorStop(0,'#d1d1d1');gradient.addColorStop(1,'#f9f9f9');}context.fillStyle = gradient;context.fill();}//销毁棋子var minusStep = function(i,j) {//擦除该圆context.clearRect((i) * 30, (j) * 30, 30, 30);// 重画该圆周围的格子context.beginPath();context.moveTo(15+i*30 , j*30);context.lineTo(15+i*30 , j*30 + 30);context.moveTo(i*30, j*30+15);context.lineTo((i+1)*30 , j*30+15);context.stroke();}</script></body>
</html>

这篇关于【前端】AI五子棋游戏186行的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/915235

相关文章

spring-boot-starter-thymeleaf加载外部html文件方式

《spring-boot-starter-thymeleaf加载外部html文件方式》本文介绍了在SpringMVC中使用Thymeleaf模板引擎加载外部HTML文件的方法,以及在SpringBoo... 目录1.Thymeleaf介绍2.springboot使用thymeleaf2.1.引入spring

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

SpringBoot整合DeepSeek实现AI对话功能

《SpringBoot整合DeepSeek实现AI对话功能》本文介绍了如何在SpringBoot项目中整合DeepSeekAPI和本地私有化部署DeepSeekR1模型,通过SpringAI框架简化了... 目录Spring AI版本依赖整合DeepSeek API key整合本地化部署的DeepSeek