canvas 绘制五子棋

这是一个使用JavaScript编写的五子棋游戏,包含HTML和CSS样式。游戏实现了棋盘绘制、用户交互、AI智能决策等功能。AI算法根据赢法统计来选择最佳落子位置,当某一方连成五子时,游戏结束并提示胜者。此外,游戏还随机显示不同背景图片增加趣味性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//html
<canvas id="chess" width="450px" height="450px"></canvas>
//js
<script>
		var chess = document.getElementById("chess");
		var context = chess.getContext('2d');

		var me = true;
		var chessBoard = [];
		var over = false;
		//  AI 赢法的数组
		var wins = [];
		// 赢法的统计数组
		var myWin = [];  //  我方
		var computerWin = [];  //计算机方

		for (var i = 0; i < 15; i++) {
			chessBoard[i] = [];
			for (var j = 0; j < 15; j++) {
				chessBoard[i][j] = 0;
			}
		}

		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++) {
				// 第0种赢法
				//wins[0][0][0] = true
				//wins[0][1][0] = true
				//wins[0][2][0] = true
				//wins[0][3][0] = true
				//wins[0][4][0] = true
				// 第0种赢法
				//wins[0][1][1] = true
				//wins[0][2][1] = true
				//wins[0][3][1] = true
				//wins[0][4][1] = true
				//wins[0][5][1] = true
				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++;
			}
		}

		console.log("count:" + count);

		for (var i = 0; i < count; i++) {
			myWin[i] = 0;
			computerWin[i] = 0;
		}

		context.strokeStyle = "#BFBFBF";
		var logo = new Image();
		let imgNum = Math.ceil(Math.random() * 5);
		switch (imgNum) {
			case 1:
				logo.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimage.shumiao.net%2Fuploads%2F20190222%2F20%2F1550837706-vzmAVQdjhE.jpg&refer=http%3A%2F%2Fimage.shumiao.net&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1636343972&t=feee365641fb75811e67ea8b817130c5";
				break;
			case 2:
				logo.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg2.niutuku.com%2Fdesk%2F1207%2F1112%2Fbizhi-1112-13889.jpg&refer=http%3A%2F%2Fimg2.niutuku.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1636344043&t=6b942b670168adb5cd17f28338d53ee1";
				break;
			case 3:
				logo.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdesk.fd.zol-img.com.cn%2Fg5%2FM00%2F02%2F03%2FChMkJ1bKxyOISUGoAAeRUrLJyt0AALHvgFTIm8AB5Fq241.jpg&refer=http%3A%2F%2Fdesk.fd.zol-img.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1636343845&t=88ac08cc9f29bd57529b819d90a075ac";
				break;
			case 4:
				logo.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdik.img.kttpdq.com%2Fpic%2F20%2F13793%2F605a02d26a246813_1280x1024.jpg&refer=http%3A%2F%2Fdik.img.kttpdq.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1636343879&t=7151f7e27eb899fa993858ae67ea1d8f";
				break;
			case 5:
				logo.src = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fuploads.5068.com%2Fallimg%2F1712%2F151-1G2010Z047.jpg&refer=http%3A%2F%2Fuploads.5068.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1636342793&t=2ebbf46cef771287734b3008b415dadd";
				break;
		}

		logo.onload = function () {
			context.drawImage(logo, 0, 0, 450, 450);
			drawChessBoard();
		}

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

		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 (chessBoard[i][j] == 0) {
				oneStep(i, j, me);
				chessBoard[i][j] = 1;
				for (var k = 0; k < count; k++) {
					if (wins[i][j][k]) {
						myWin[k]++;
						computerWin[k] = 6;  // 表示计算机在第k种赢法种类上不可能赢
						if (myWin[k] == 5) {
							window.alert("你赢了");
							over = true;
						}
					}
				}
				if (!over) {
					me = !me;
					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++) {
					if (chessBoard[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;
							}
						}
					}
				}
			}
			oneStep(u, v, false);
			chessBoard[u][v] = 2;

			for (var k = 0; k < count; k++) {
				if (wins[u][v][k]) {
					computerWin[k]++;
					myWin[k] = 6;  // 表示计算机在第k种赢法种类上不可能赢
					if (computerWin[k] == 5) {
						window.alert("计算机赢了");
						over = true;
					}
				}
			}
			if (!over) {
				me = !me;
			}
		}
	</script>

//css
canvas {
			display: block;
			margin: 50px auto;
			box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #B9B9B9;
		}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值