五子棋 源码

news/2024/11/24 6:27:19/

JS 五子棋 带成绩排名

游戏:http://wx0725.top/index.php/181.html

主程序学习:https://blog.csdn.net/qq_44731019/article/details/109586730

  • 改了几个 BUG
  • 添加了成绩截图功能
  • 去掉了悔棋

在这里插入图片描述

自己看着重新写吧,下面代码只是一个思路,也有bug。。。

1. 源码

HTML

 <div class="row"><h3 id="result-wrap" style="color: red;"><img src="http://wx0725.top/image/black_qizi.png" alt=""></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></div>

Javascript

代码中有注释啊啊啊

var fail_text = '👏,计算机赢了,继续加油哦!';
var win_text = '恭喜,你赢了!😱';
var back_text = '只能撤销一步哦😂';
var winner = ""; // 假设胜利者是计算机
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");document.getElementById("restart").onclick = function() {window.location.reload();
}function save_chess() { // 发送棋谱截图// 截图发送var chessSrc = chess.toDataURL("image/png");var data = {function: "gobangSave",base64: chessSrc,city: address, // 地址和IP自己找,不需要可以去掉,记得后台代码做对应的修改,可以使用时间戳命名保存的图片名称ip: ip,};$.ajax({ // 提交截图url: "gobangSave.php", // 填写后台php的链接type: "post",data: data,async: true,success: function(e) {},error: function(e) {}})
}function win_f() { // 我赢了resultTxt.innerHTML = win_text;over = true;var me_com = [0, 0, 0]; // 地图中 默认、我、计算机 分别占位的个数for (var i = 0; i < 15; i++) {for (var j = 0; j < 15; j++) {me_com[chressBord[i][j]]++;}}if (me_com[1] != me_com[2] + 1) {setTimeout(function() {alert("下棋成绩异常,如有问题请联系管理员或留言");}, 500);return;}winner = "me";setTimeout(function() {alert(win_text + " 您可以选择【重新开始】继续游戏!");}, 1000)
}function fail_f() { // 计算机赢了resultTxt.innerHTML = fail_text;over = true;winner = "computer";setTimeout(function() {alert(fail_text + " 您可以选择【重新开始】继续游戏!");}, 1000)
}function able_back() { // 允许悔棋backAble = true;backbtn.className = backbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
}function unable_back() { // 不允许悔棋backAble = false;var hasClass = new RegExp('unable').test(' ' + backbtn.className + ' ');if (!hasClass) {backbtn.className += ' ' + 'unable';}
}function able_return() { // 允许撤销悔棋returnAble = true;returnbtn.className = returnbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
}function unable_return() { // 不允许撤销悔棋returnAble = false;var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' ');if (!hasClass) {returnbtn.className += ' ' + 'unable';}
}// 我,下棋
chess.onclick = function(e) {if (over) {return;}if (!me) {return;}var x = e.offsetX;var y = e.offsetY;var i = Math.floor(x / 30);var j = Math.floor(y / 30);if (chressBord[i][j] == 0) {_nowi = i; // 源码中的BUG,这两行更新现在的位置需要放在if中,否则会在撤销的时候出现问题_nowj = j;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) {win_f();}}}if (!over) { // 没结束计算机下棋me = !me;computerAI();} else {if (winner == "me") {unable_back();save_chess();}}}}// 悔棋
backbtn.onclick = function(e) {if (!backAble) {return;}over = false;me = true;// 我,悔棋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]--;// 源代码中的BUG **** _myWin[k]中 i 改为 kmyWin[k] = _myWin[k]; //这个位置对方可能赢}}resultTxt.innerHTML = back_text;able_return(); // 允许撤销悔棋unable_back(); // 不允许悔棋}// 撤销悔棋
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; //这个位置对方不可能赢}}// 计算机撤销相应的悔棋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; //这个位置对方不可能赢}}able_back(); // 允许悔棋unable_return(); // 不允许撤销悔棋}// 计算机下棋
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) {fail_f();}}}able_back(); // 确保我下棋并且计算机也下棋,才能允许悔棋unable_return();if (!over) { // 如果没有结束,换棋手me = !me;} else { // 如果结束了if (winner == "computer") unable_back();}}//绘画棋盘
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();}
}
drawChessBoard(); // 画棋盘//画棋子
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();
}

php 保存成绩

gobangSave.php

function gobangSave()
{ // 五子棋if ($_POST['base64'] != "" && $_POST['city'] != "" && $_POST['ip'] != "") {//接收base64数据$image = $_POST['base64'];if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $image, $result)) {$name = $_POST["city"] . "-" . $_POST["ip"] .  "-" . time() . '.png';$imageName = "./wuziqi/" . $name;is_file($imageName) or fclose(fopen($imageName, 'w'));if (file_put_contents($imageName, base64_decode(str_replace($result[1], '', $image)))) {echo "成绩有效👍, 您的成绩已经展示在下方,刷新页面查看。";} else {echo "抱歉,文件写入有误,请联系管理员!";}} else {echo "抱歉,文件格式有误!";}} else {echo "抱歉,成绩无效。如有疑问请联系管理员或留言反馈!";}
}
$function = $_POST["function"];
if ($function == "gobangSave") {gobangSave();
} 
  • 前往游戏:http://wx0725.top/index.php/181.html

推荐:公众号能干吗?http://wx0725.top/index.php/archives/224/


http://www.ppmy.cn/news/881441.html

相关文章

五子棋AI算法

在本次“五子棋“程序的编写中&#xff0c;只编写了人机对弈部分&#xff0c;运用了博弈树进行搜索&#xff0c;在选取最优的走步时使用极大极小分析法&#xff0c;考虑到搜索的时间复杂度和空间复杂度&#xff0c;在程序中只进行了2步搜索&#xff0c;即计算机在考虑下一步的走…

五子棋 ai算法

博弈类人工智能&#xff0c;其中一个方法就是&#xff1a;博弈树极大极小值alpha-beta剪枝搜索。 是不是觉得这个名字很牛逼&#xff0c; 但经过我的详细解读&#xff0c; 你马上就会发现&#xff0c;原来不过如此。 对于要实现一个会智能下五子棋的AI&#xff0c;要怎么去实…

[人工智能]五子棋

#include<iostream> #include<memory.h> #include<string> #include<stdlib.h> #include<stdio.h> using namespace std; const int N 20; //定义棋盘规模 int pace 0;//统计步数 const char chess[2] {X, O}; //定义数组显示棋子颜色 黑 白b…

五子棋

文章目录 五子棋一、摘要二、代码实现&#xff08;PS:挺简单的&#xff09;三、输出 五子棋 一、摘要 目标&#xff1a;编程实现控制台版并支持两人对战的五子棋游戏绘制棋盘提示黑方&#xff08;用1表示&#xff09;和白方&#xff08;用2表示&#xff09;分别下棋&#xff…

五子棋游戏AI智能算法设计

五子棋游戏C语言AI智能算法设计 近来发现编制五子棋游戏很有趣&#xff0c;尤其是AI智能算法很烧脑。网上介绍有什么贪心算法&#xff0c;剪枝算法&#xff0c;博弈树算法等等&#xff0c;不一而足。 对于人机对战的电脑智能应子算法&#xff0c;参阅很多五子棋书籍棋谱和五…

《五子棋大师》技术支持

是非黑白&#xff0c;恩恩怨怨杀戮在方寸之间&#xff0c;阴阳变化&#xff0c;风云莫测&#xff0c;有谁能在生死的交错点识破天机&#xff1f;传统五子棋的奇妙之处&#xff0c;在于把纵横交错化为直线&#xff0c;在复杂的双人五子棋盘中找寻那决定乾坤的五子连珠。博弈五子…

【原创】五子棋大师2.0完整源码

大学期间与同班同学徐志强一起开发了五子棋大师2.0程序&#xff0c;到今年已有10个年头了&#xff0c;现共享出来以表纪念&#xff1a; 五子棋大师采用了专家系统的相关思想&#xff0c;内设棋谱库、推理机结合当前棋局就可以推理了&#xff0c;每次推理针对每个节点打分&…

基于STM32 ARM+FPGA伺服控制系统总体设计方案(一)

设计需求 一套完整的伺服控制方案包括了上位机、驱控一体控制器和功率板三者。操作人员 通过上位机发送各种不同指令&#xff0c;然后控制器解析指令后执行相应的伺服功能&#xff0c;其次控 制器将驱动信号传输至功率板驱动电机&#xff0c;最后控制器采集反馈信息进行闭环…