[javascript]js的五子棋让红蓝双方自己跟自己下棋

运行效果(这是未分出胜负):

 

 这是分出胜负:

 

 源代码,把下边的代码放到1.html,然后用浏览器打开,就可以,然后刷新网页:

<!DOCTYPE html>
<html><body><h3>AI五子棋游戏,这个程序有个非常大的Bug,你找到了吗?doge</h3><canvas id="chess" width="450px" height="450px"></canvas><script>var chressBord = []; //棋盘当前落子后的记录,是否已经落子,是哪方落子		var wins = [];  //存放所有5个棋子在一条线上所有可能性,第一维存放y, 第二维存放x,第三维存放当前的可能性编号var count = 0; //赢法总数量var blueWin = []; //我们赢法的统计数组var redWin = []; //计算机赢法的统计数组var chess = document.getElementById("chess");var context = chess.getContext('2d');var x = 0;var y = 0;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++){blueWin[i] = 0; //这个数组很精髓,记录下棋后每一个位置在每种赢法的得分redWin[i] = 0;}//程序运行入口function main() {				var role = "red";//两个下棋的角色不断切换x = Math.floor(Math.random() * 15);	//第一步随机x,y				y = Math.floor(Math.random() * 15);	for (i = 0; i < 225; i++){					if(chressBord[x][y] == 0) //computerAI计算后的x,y坐标还没有落子{	if (role == "red"){Move(x,y,role); //落子chressBord[x][y] = 1; //red玩家棋盘位置占位CheckWin(x,y,role, redWin);  //计算落子后是否获胜,这里也很精髓,递归思想}else{Move(x,y,role); //落子chressBord[x][y] = 2; //blue玩家棋盘位置占位CheckWin(x,y,role, blueWin);  //计算落子后是否获胜,这里也很精髓,递归思想}role = (role == "blue") ? "red" : "blue"; //落子后切换角色}computerAI(); //计算下一步落子的x,y坐标}}// 计算机下棋,找玩家最容易赢的位置或者电脑最容易赢的位置function computerAI(){var palyer1Score = []; //这两个数组存放的内容会不断变化,随着计算双方相互切换var palyer2Score = [];var max = 0;var u = 0, v = 0;for(var i = 0; i < 15; i++){palyer1Score[i] = [];palyer2Score[i] = [];for(var j = 0; j < 15; j++){palyer1Score[i][j] = 0;palyer2Score[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(blueWin[k]){case 1: palyer1Score[i][j] += 200; break;case 2: palyer1Score[i][j] += 400; break;case 3: palyer1Score[i][j] += 2000; break;case 4: palyer1Score[i][j] += 10000; break;}switch(redWin[k]){case 1: palyer2Score[i][j] += 220; break;case 2: palyer2Score[i][j] += 420; break;case 3: palyer2Score[i][j] += 2100; break;case 4: palyer2Score[i][j] += 20000; break;}}if(palyer1Score[i][j] > max) //如果玩家落子的分数多,就替换{max  = palyer1Score[i][j];u = i;v = j;}else if(palyer1Score[i][j] == max)  //如果玩家落子的分数跟原来最多分数一样多{if(palyer2Score[i][j] > palyer2Score[u][v]) //如果电脑在i,j落子的分数比u,v的分数多,就替换{u = i;v = j;    }}if(palyer2Score[i][j] > max) //如果电脑下棋新位置分数比原来的多,就替换{max  = palyer2Score[i][j];u = i;v = j;}else if(palyer2Score[i][j] == max) //如果电脑下棋新位置分数跟原来的一样多{if(palyer1Score[i][j] > palyer1Score[u][v]) //如果玩家落子的分数多,就准备把玩家最好的位置占掉{u = i;v = j;    }}}}x = u;y = v;}function Move(i,j,Role) //落子{context.beginPath();context.arc(15 + i * 30, 15 + j * 30, 13, 0, 2 * Math.PI);// 画圆context.closePath();    context.fillStyle = Role;context.fill(); //填充颜色				}function CheckWin(i, j, Role, WinArray){			for(var k = 0; k < count; k++)if(wins[i][j][k]) // 将可能赢的情况都加1{WinArray[k]++; //第k这个位置要注意,每一个k代表一种赢的可能性,并且前边的x,y代表第K种赢法x,y的坐标对,这个对于理解算法是否赢很重要if(WinArray[k] >= 5){alert(Role + ': 恭喜,你赢了!')throw new Error(Role + " player win!!");;}}}			function drawChessBoard(){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(); // 画棋盘main();</script></body>
</html>

 

import javax.swing.*;
import java.awt.*;public class FiveInOne extends JFrame {static Graphics graphics;private final Image buffer;  // 双缓冲图像private final Graphics bufferGraphics;  // 双缓冲图像的绘图上下文int player;int[][] chessBoard;int[][][] wins;int count;int[] blueWin;int[] redWin;int x, y;Color c;FiveInOne(){setLayout(null);setSize(700, 900);setLocationRelativeTo(null);setVisible(true);graphics = getContentPane().getGraphics();buffer = createImage(700, 900);bufferGraphics = buffer.getGraphics();chessBoard = new int[15][15];wins = new int[15][15][573];blueWin = new int[573];redWin = new int[573];player = 1;c = new Color(255,0,0);bufferGraphics.setColor(new Color(0,0,0));drawchessBoard();System.out.println("count: " +String.valueOf(count));generateWinArray();main2();}void generateWinArray(){//横线赢法for(int i = 0; i < 15; i++)for(int j = 0; j < 11; j++,count++)for(int k = 0; k < 5; k++)wins[i][j+k][count] = 1;//竖线赢法for(int i = 0; i < 15; i++)for(int j = 0; j < 11; j++,count++)for(int k = 0; k < 5; k++)wins[j+k][i][count] = 1;//正斜线赢法for(int i = 0; i < 11; i++)for(int j = 0; j < 11; j++,count++)for(int k = 0; k < 5; k++)wins[i+k][j+k][count] = 1;//反斜线赢法for(int i = 0; i < 11; i++)for(int j = 14; j > 3; j--,count++)for(int k = 0; k < 5; k++)wins[i+k][j-k][count] = 1;}void main2(){String role = "red";//两个下棋的角色不断切换x = (int) Math.floor(Math.random() * 15);	//第一步随机x,yy = (int) Math.floor(Math.random() * 15);for (int i = 0; i < 225; i++){if(chessBoard[x][y] == 0) //computerAI计算后的x,y坐标还没有落子{if (role.equals("red")){drawChess(x,y); //落子chessBoard[x][y] = 1; //red玩家棋盘位置占位CheckWin(x,y,role, redWin);  //计算落子后是否获胜,这里也很精髓,递归思想}else{drawChess(x,y); //落子chessBoard[x][y] = 2; //blue玩家棋盘位置占位CheckWin(x,y,role, blueWin);  //计算落子后是否获胜,这里也很精髓,递归思想}role = (role == "blue") ? "red" : "blue"; //落子后切换角色}computerAI(); //计算下一步落子的x,y坐标System.out.println("x: " + x + ", y: " + y);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}void computerAI(){int[][] palyer1Score = new int[15][15]; //这两个数组存放的内容会不断变化,随着计算双方相互切换int[][] palyer2Score = new int[15][15];int max = 0;int u = 0, v = 0;//找落子赢的概率最大坐标for(int i = 0; i < 15; i++){for(int j = 0; j < 15; j++){for(int k = 0; k < count; k++) //遍历到i,j这个坐标时,计算谁的得分更高{if(chessBoard[i][j] != 0 || 0 == wins[i][j][k]) //当前i,j坐标还没落子continue;switch(blueWin[k]){case 1: palyer1Score[i][j] += 200; break;case 2: palyer1Score[i][j] += 400; break;case 3: palyer1Score[i][j] += 2000; break;case 4: palyer1Score[i][j] += 10000; break;}switch(redWin[k]){case 1: palyer2Score[i][j] += 220; break;case 2: palyer2Score[i][j] += 420; break;case 3: palyer2Score[i][j] += 2100; break;case 4: palyer2Score[i][j] += 20000; break;}}if(palyer1Score[i][j] > max) //如果玩家落子的分数多,就替换{max  = palyer1Score[i][j];u = i;v = j;}else if(palyer1Score[i][j] == max)  //如果玩家落子的分数跟原来最多分数一样多{if(palyer2Score[i][j] > palyer2Score[u][v]) //如果电脑在i,j落子的分数比u,v的分数多,就替换{u = i;v = j;}}if(palyer2Score[i][j] > max) //如果电脑下棋新位置分数比原来的多,就替换{max  = palyer2Score[i][j];u = i;v = j;}else if(palyer2Score[i][j] == max) //如果电脑下棋新位置分数跟原来的一样多{if(palyer1Score[i][j] > palyer1Score[u][v]) //如果玩家落子的分数多,就准备把玩家最好的位置占掉{u = i;v = j;}}}}x = u;y = v;}void CheckWin(int i, int j, String Role, int[] WinArray){for(int  k = 0; k < count; k++)if(wins[i][j][k] == 1) // 将可能赢的情况都加1{WinArray[k]++; //第k这个位置要注意,每一个k代表一种赢的可能性,并且前边的x,y代表第K种赢法x,y的坐标对,这个对于理解算法是否赢很重要if(WinArray[k] >= 5){//alert(Role + ': 恭喜,你赢了!')System.out.println(Role + " player win!!");break;}}}void drawChess(int mouse_x, int mouse_y){mouse_x = 15 + mouse_x * 30; //把一个区域的点击放到一个点mouse_y = 15 + mouse_y * 30;if (player == 1){c = new Color(255,0,0);player = 2;}else{c = new Color(0,0,255);player = 1;}bufferGraphics.setColor(c);bufferGraphics.fillArc(mouse_x - 12, mouse_y - 38, 20, 20, 0, 360);graphics.drawImage(buffer, 0, 0, null);}void drawchessBoard(){for (int i = 0; i < 15; i++){bufferGraphics.drawLine(15 + i * 30, 15, 15 + i * 30, 435);bufferGraphics.drawLine(15, 15 + i * 30, 435, 15 + i * 30);}}//这个程序有个非常大的Bug,你找到了吗?public static void main(String[] args) {new FiveInOne();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/61248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【list的模拟实现】—— 我与C++的模拟实现(十四)

一、list节点 ​ list是一个双向循环带头的链表&#xff0c;所以链表节点结构如下&#xff1a; template<class T>struct ListNode{T val;ListNode* next;ListNode* prve;ListNode(int x){val x;next prve this;}};二、list迭代器 2.1、list迭代器与vector迭代器区别…

ssh隧道代理访问内网应用

目录 场景 ssh配置 .ssh目录结构 常见文件及用途 config id_rsa 和 id_rsa.pub authorized_keys known_hosts&#xff1a; known_hosts.old&#xff1a; environment&#xff1a; ssh_config&#xff1a; 配置隧道访问内网应用流程 1.生成密钥对 2.将公钥添加到远…

从0开始学习机器学习--Day26--聚类算法

无监督学习(Unsupervised learning and introduction) 监督学习问题的样本 无监督学习样本 如图&#xff0c;可以看到两者的区别在于无监督学习的样本是没有标签的&#xff0c;换言之就是无监督学习不会赋予主观上的判断&#xff0c;需要算法自己去探寻区别&#xff0c;第二张…

基于YOLOv8深度学习的智慧农业猪行为检测系统研究与实现(PyQt5界面+数据集+训练代码)

随着智慧农业的快速发展&#xff0c;畜牧业的智能化管理已逐渐成为提高生产效率、提升动物福利、降低运营成本的关键手段之一。在此背景下&#xff0c;畜牧场对动物行为的自动化监测需求日益增长&#xff0c;尤其是在大型养猪场&#xff0c;猪群的日常行为检测对于疾病预防、饲…

C++:指针和引用

指针的基础 数据在内存当中是怎么样被存储的 数据在内存中的存储方式取决于数据的类型和计算机的体系结构 基本数据类型 整数类型&#xff1a;整数在内存中以二进制补码的形式存储。对于有符号整数&#xff0c;最高位为符号位&#xff0c;0 表示正数&#xff0c;1 表示负数。…

使用esp32c3开发板通过wifi连网络web服务器

实验基本拓扑就是&#xff1a; esp32c3开发板通过Wifi模块连上局域网&#xff0c;局域网一台服务器通过FastAPI提供8000端口的web服务&#xff0c;在esp32c3开发板中烧录micropython固件&#xff0c;在python交互模式下&#xff0c;连上Wifi模块&#xff0c;并使用socket模块获…

自动化运维-检测Linux服务器CPU、内存、负载、IO读写、机房带宽和服务器类型等信息脚本

前言&#xff1a;以上脚本为今年8月1号发布的&#xff0c;当时是没有任何问题&#xff0c;但现在脚本里网络速度测试py文件获取不了了&#xff0c;测速这块功能目前无法实现&#xff0c;后面我会抽时间来研究&#xff0c;大家如果有建议也可以分享下。 脚本内容&#xff1a; #…

网络安全:我们的安全防线

在数字化时代&#xff0c;网络安全已成为国家安全、经济发展和社会稳定的重要组成部分。网络安全不仅仅是技术问题&#xff0c;更是一个涉及政治、经济、文化、社会等多个层面的综合性问题。从宏观到微观&#xff0c;网络安全的重要性不言而喻。 宏观层面&#xff1a;国家安全与…

通威传媒:移动AI数字人OLED透明屏应用案例

在科技与创新不断交融的今天&#xff0c;尼伽OLED品牌与通威传媒携手合作&#xff0c;共同推出了移动AI数字人OLED透明屏显示设备。这款设备不仅融合了尼伽OLED品牌的卓越显示技术与通威传媒的深厚积累&#xff0c;更在定点介绍、手动讲解模式、中控控制以及数字人联动等方面实…

Proteus 8.17的详细安装教程

通过百度网盘分享的文件&#xff1a;Proteus8.17(64bit&#xff09;.zip 链接&#xff1a;https://pan.baidu.com/s/1zu8ts1Idhgg9DGUHpAve7Q 提取码&#xff1a;8q8v 1.右击【Proteus8.17(64bit&#xff09;.zip】&#xff0c;选择【全部解压缩......】。 &#xff0c; 2.…

人工智能:塑造未来的工作与生活

目录 人工智能技术的应用前景与影响 人工智能的历史与现状 人工智能的应用领域 人工智能的前景与挑战 个人视角&#xff1a;人工智能的应用前景与未来 人工智能在生活中的潜力 面对人工智能带来的挑战 我的观点与建议 结语 人工智能技术的应用前景与影响 随着人工智能…

VSCode自定义插件创建教程

文章目录 一、前言二、插件维护三、调试插件四、使用 vsce 生成 vsix 插件五、问题&#xff1a;打开调试窗口后&#xff0c;输入helloworld并没有指令提示六、插件创建实战七、拓展阅读 一、前言 对于前端程序猿来讲&#xff0c;最常用的开发利器中VSCode首当其冲&#xff0c;…

vue功能基础元素使用

4.:inline"true"元素&#xff0c;能够左右元素保持在同一行 这个好处非常直观&#xff0c;但要注意和el-col同时使用时&#xff0c;就会出现el-input换行&#xff0c;即便调整好&#xff0c;放大缩小也会出现换行问题。 5.filterable 下拉框带搜索功能 6.clearable下…

uniapp 购物弹窗组件 (微信小程序)

效果图&#xff0c;暂时只适应单规格&#xff0c;居中弹出和下方弹出&#xff0c;如需求不满足&#xff0c;请自行修改代码 &#xff08;更新于24/11/15) 居中显示效果 下方弹出效果 html <template><view class"" v-if"show":class"mod…

单片机学习笔记 5. 数码管静态显示

更多单片机学习笔记&#xff1a;单片机学习笔记 1. 点亮一个LED灯单片机学习笔记 2. LED灯闪烁单片机学习笔记 3. LED灯流水灯单片机学习笔记 4. 蜂鸣器滴~滴~滴~ 目录 0、实现的功能 1、Keil工程 1-1 数码管显示原理 1-2 静态与动态显示 1-3 74HC573锁存器的工作原理 1-…

内容占位符:Kinetic Loader HTML+CSS 使用CSS制作三角形原理

内容占位符 前言 随着我们对HTML和CSS3的学习逐渐深入&#xff0c;相信大家都已经掌握了网页制作的基础知识&#xff0c;包括如何使用HTML标记构建网页结构&#xff0c;以及如何运用CSS样式美化页面。为了进一步巩固和熟练这些技能&#xff0c;今天我们一起来完成一个有趣且实…

【YOLOv8】安卓端部署-1-项目介绍

【YOLOv8】安卓端部署-1-项目介绍 1 什么是YOLOv81.1 YOLOv8 的主要特性1.2 YOLOv8分割模型1.2.1 YOLACT实例分割算法之计算掩码1.2.1.1 YOLACT 的掩码原型与最终的掩码的关系1.2.1.2 插值时的目标检测中提取的物体特征1.2.1.3 coefficients&#xff08;系数&#xff09;作用1.…

Hadoop 学习心得

一、引言 &#xff08;一&#xff09;学习 Hadoop 的背景和目的 随着信息技术的飞速发展&#xff0c;数据量呈爆炸式增长&#xff0c;传统的数据处理方式已难以满足需求。在这样的背景下&#xff0c;为了能够在大数据领域有所发展&#xff0c;我开始学习 Hadoop。Hadoop 作为处…

【全面解读】Apache SeaTunnel常见问题全攻略

使用SeaTunnel需要安装Spark或者Flink这样的引擎么&#xff1f; 不需要&#xff0c;SeaTunnel 支持 Zeta、Spark 和 Flink 作为同步引擎的选择&#xff0c;您可以选择之一就行&#xff0c;社区尤其推荐使用 Zeta 这种专为同步场景打造的新一代超高性能同步引擎。Zeta 被社区用…

STM32完全学习——系统时钟设置

一、时钟框图的解读 首先我们知道STM32在上电初始化之后使用的是内部的HSI未经过分频直接通过SW供给给系统时钟&#xff0c;由于内部HSI存在较大的误差&#xff0c;因此我们在系统完成上电初始化&#xff0c;之后需要将STM32的时钟切换到外部HSE作为系统时钟&#xff0c;那么我…