html+javascript制作五子棋(附完整代码)
程序员文章站
2022-07-04 22:06:27
...
最近租了一个腾讯云开发的环境,感觉还是相当方便的。花个十几块钱租好一个环境之后就可以在给的域名上配置自己的云函数以及静态页面等等。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>五子棋</title>
<style>
body {
display: flex;
flex-direction: column;
margin: 0;
background-color: #f2f3f7;
}
#startbtn {
margin: 30px auto;
}
.topshow {
color: #555;
font-size: 22px;
text-align: center;
font-weight: 900;
margin: 30px 0;
}
button {
border: none;
height: 35px;
min-width: 140px;
padding: 0 20px;
background-color: #00a4ff;
color: #fff;
font-size: 14px;
line-height: 35px;
text-align: center;
display: inline-block;
cursor: pointer;
outline: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#chess {
width: 95%;
max-width: 480px;
position: relative;
margin: 0px auto;
}
#canvas {
width: 100%;
position: relative;
background-color: #f8e8b7;
display: block;
}
#newpos {
position: absolute;
width: 5%;
height: 5%;
}
p {
font-size: 12px !important;
width: 95%;
max-width: 480px;
margin: 10px auto;
line-height: 25px;
color: #898989;
}
</style>
</head>
<body>
<div class="topshow" id="msg">线上五子棋【初级】</div>
<div id="chess" style="display: none;">
<canvas id="canvas" width="480px" height="480px"></canvas>
<img src="white.png" id="newpos">
</div>
<button id="startbtn" onclick="start()">开始五子棋</button>
</body>
<script>
var myWin = [];
var compWin = [];
var compover = false;
var count = 0;
var allWin = [];
var mystep = false;
var step = 0;
var maparr = [];
var newpos = document.getElementById('newpos');
var o = document.getElementById("canvas");
var startbtn = document.getElementById('startbtn');
var canvas = document.querySelector("#canvas"); /*获取元素*/
var context = canvas.getContext("2d"); /*获取canvas绘制环境*/
var ChessColor = ["black", "#fafafa"];
function start() {
init(function() {
if (confirm('你是否先下子?')) {
setmsg('到你下子');
mystep = true;
} else {
setmsg('对方下子');
setTimeout(function() {
AIcode();
}, 300);
}
});
document.getElementById('chess').style = "";
document.getElementById('startbtn').style = "display: none;";
}
function setmsg(msg) {
document.getElementById('msg').innerText = msg;
}
function drawChess(x, y, color) {
//传入一个颜色代码,绘制一个棋子
context.fillStyle = color;
context.strokeStyle = color;
context.shadowBlur = 4;
context.shadowColor = 'rgba(0,0,0,0.5)';
context.beginPath(); /*停笔操作*/
context.arc(x, y, 13, 0, Math.PI * 2, false); /*圆心坐标轴x,y,半径r,起始度数,两个π等于一个满圆,逆时针旋转*/
context.fill(); /*填充*/
context.stroke();
context.closePath(); /*停笔操作*/
}
canvas.addEventListener("click", function(e) {
if (!mystep) return;
let h = o.offsetHeight; //高度
let w = o.offsetWidth; //宽度
var offsetX = e.offsetX / w * 480;
var offsetY = e.offsetY / h * 480;
var dx = Math.floor((offsetX + 15) / 30) * 30;
var dy = Math.floor((offsetY + 15) / 30) * 30;
console.log(dx, dy);
if (dx == 0 || dy == 0 | dx == 480 || dy == 480) {
return;
}
if (maparr[dx / 30][dy / 30] == 0 && !compover) {
let size = 28 * w / 480;
newpos.style = "width: " + size + "px;height: " + size + "px;top: calc(" + dy * h / 480 + "px - " + size / 2 +
"px);left: calc(" + dx * w / 480 + "px - " + size / 2 + "px);";
if (step % 2 == 1) {
newpos.src = "black.png";
} else {
newpos.src = "white.png";
}
drawChess(dx, dy, ChessColor[step % 2]);
maparr[dx / 30][dy / 30] = ChessColor[step % 2];
step++;
checkmy(dx / 30, dy / 30);
}
})
function checkmy(x, y) {
for (var k = 0; k < count; k++) {
if (allWin[x][y][k]) {
//此种赢法步数加1,如果为5表示全部走到
//此赢法computer已不可达,设置为6
myWin[k]++;
compWin[k] = 6;
}
if (myWin[k] == 5) {
setmsg('你赢了');
startbtn.style = "";
startbtn.innerText = "再来一局";
compover = true;
}
}
if (compover) {
document.getElementById('canvas').style = "cursor: not-allowed;";
return;
}
document.getElementById('canvas').style = "cursor: not-allowed;";
mystep = false;
setmsg('对方下子');
setTimeout(function() {
AIcode();
}, 300);
}
function checkcom(x, y) {
for (var k = 0; k < count; k++) {
if (allWin[x][y][k]) {
compWin[k]++;
myWin[k] = 6;
}
if (compWin[k] == 5) {
setmsg('你输了');
startbtn.style = "";
startbtn.innerText = "再来一局";
compover = true;
}
}
if (compover) {
document.getElementById('canvas').style = "cursor: not-allowed;";
return;
}
document.getElementById('canvas').style = "";
mystep = true;
setmsg('到你下子');
}
function AIcode() {
if (compover) return;
//表示所有位置的玩家总分数和电脑总分数
var myScore = [];
var compScore = [];
for (var i = 1; i < 16; i++) {
myScore[i] = [];
compScore[i] = [];
for (var j = 1; j < 16; j++) {
myScore[i][j] = 0;
compScore[i][j] = 0;
}
}
//对分数进行统计判断,选出分数最大的位置进行电脑下棋
var max = 0;
var maxX = 7;
var maxY = 7;
//创建加分规则
for (var i = 1; i < 16; i++) {
for (var j = 1; j < 16; j++) {
if (maparr[i][j] == 0) {
for (var k = 0; k < count; k++) {
if (allWin[i][j][k]) {
if (myWin[k] == 1) {
myScore[i][j] += 200;
} else if (myWin[k] == 2) {
myScore[i][j] += 500;
} else if (myWin[k] == 3) {
myScore[i][j] += 2000;
} else if (myWin[k] == 4) {
myScore[i][j] += 50000;
}
if (compWin[k] == 1) {
compScore[i][j] += 300;
} else if (compWin[k] == 2) {
compScore[i][j] += 800;
} else if (compWin[k] == 3) {
compScore[i][j] += 20000;
} else if (compWin[k] == 4) {
compScore[i][j] += 500000;
}
}
}
if (myScore[i][j] > max) {
max = myScore[i][j];
maxX = i;
maxY = j;
}
if (compScore[i][j] > max) {
max = compScore[i][j];
maxX = i;
maxY = j;
}
}
}
}
console.log(maxX, maxY)
let h = o.offsetHeight; //高度
let w = o.offsetWidth; //宽度
let size = 28 * w / 480;
newpos.style = "width: " + size + "px;height: " + size + "px;top: calc(" + maxY * 30 * h / 480 + "px - " + size / 2 +
"px);left: calc(" + maxX * 30 * w / 480 + "px - " + size / 2 + "px);";
if (step % 2 == 1) {
newpos.src = "black.png";
} else {
newpos.src = "white.png";
}
drawChess(maxX * 30, maxY * 30, ChessColor[step % 2]);
maparr[maxX][maxY] = ChessColor[step % 2];
step++;
checkcom(maxX, maxY);
};
function init(success) {
myWin = [];
compWin = [];
compover = false;
count = 0;
allWin = [];
mystep = false;
step = 0;
maparr = [];
newpos.style = "display:none";
context.clearRect(0, 0, 480, 480);
for (var i = 1; i < 16; i++) {
maparr[i] = [];
for (var j = 1; j < 16; j++) {
maparr[i][j] = 0;
}
}
context.lineWidth = 1;
context.strokeStyle = '#67563c';
context.shadowBlur = 0;
context.shadowColor = 'rgba(0,0,0,0)';
for (var i = 0; i < 15; i++) {
var fix1px = (context.lineWidth % 2 === 0) ? 0 : 0.5;
context.moveTo(30 * (i + 1) + fix1px, 30 + fix1px); /*第一个点坐标*/
context.lineTo(30 * (i + 1) + fix1px, 450 + fix1px); /*第二个点坐标*/
context.moveTo(30 + fix1px, 30 * (i + 1) + fix1px);
context.lineTo(450 + fix1px, 30 * (i + 1) + fix1px);
}
context.stroke(); /*将之前所有的路径全部绘制一遍,描边画法*/
for (var i = 1; i <= 15; i++) {
allWin[i] = [];
for (var j = 1; j <= 15; j++) {
allWin[i][j] = [];
}
}
for (var i = 1; i <= 15; i++) {
for (var j = 1; j <= 11; j++) {
for (var k = 0; k < 5; k++) {
allWin[j + k][i][count] = true;
}
count++;
}
}
for (var i = 1; i <= 15; i++) {
for (var j = 1; j <= 11; j++) {
for (var k = 0; k < 5; k++) {
allWin[i][j + k][count] = true;
}
count++;
}
}
for (var i = 1; i <= 11; i++) {
for (var j = 1; j <= 11; j++) {
for (var k = 0; k < 5; k++) {
allWin[i + k][j + k][count] = true;
}
count++;
}
}
for (var i = 14; i > 4; i--) {
for (var j = 1; j <= 11; j++) {
for (var k = 0; k < 5; k++) {
allWin[i - k][j + k][count] = true;
}
count++;
}
}
console.log(count); //572
for (var i = 0; i < count; i++) {
myWin[i] = 0;
compWin[i] = 0;
}
success();
}
</script>
</html>
这里是一个五子棋的小程序,大家可以拿去放到自己网站上,然后发给朋友玩一玩。上传这个文件的同时还要上传两个图片用于html里的显示。
所需的图片在这里给出来,加号下面也是一张图片,由于和背景颜色相同所以看不出来,两个图片分别保存成black和white,三个文件都上传到云开发里的静态页面里即可。
上一篇: 黑客避开检测的手段
下一篇: VsCode里的Vue模板的实现