HTML5代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>五子棋</title>
<link rel="stylesheet" href="./css/chess.css" />
</head>
<body>
<p id="result_wrap">**********人机大战五子棋**********</p>
<canvas id="chess" width="450px" height="450px"></canvas>
<div id="demo">坐标:</div>
<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>
</body>
<script src="./js/chess.js"></script>
</html>
CSS3代码
body {
background: url('./images/背景图.jpg');
background-size: cover;
background-repeat: no-repeat;
width: 100%;
height: 100%;
}
canvas {
display: block; /*让棋盘块状显示*/
margin: 50px auto; /*让棋盘左右居中*/
box-shadow: -2px -2px 2px #efefef, 3px 3px 3px #ffdaaf; /*添加棋盘阴影,使棋盘看起来更有立体感*/
cursor: pointer; /*改变鼠标光标,增强用户的下棋落点准确性 */
background: url('./images/棋盘.jpg');
background-size: contain;
}
#demo {
text-align: center;
margin-top: -30px;
margin-bottom: 10px;
color: #ffffff;
}
.btn_wrap {
display: flex;
justify-content: center; /*水平居中*/
}
.btn_wrap div {
margin: 0 10px;
}
div > span {
display: inline-block;
padding: 10px 20px;
color: #fff;
background-color: #eeb741;
border-radius: 5px;
cursor: pointer;
}
div.unable span {
background: #d6d6d4;
color: #adacaa;
}
#result_wrap {
text-align: center;
font-weight: bold;
font-size: 28px;
line-height: 28px;
color: #000000;
}
JavaScript代码
var chess = document.getElementById('chess')
var context = chess.getContext('2d')
var demo = document.getElementById('demo')
var result_wrap = document.getElementById('result_wrap')
var restart = document.getElementById('restart')
var goback = document.getElementById('goback')
var returnbtn = document.getElementById('return')
var over = false
var me = true
var _nowi = 0,
_nowj = 0
var _compi = 0,
_compj = 0
var backAble = false,
returnAble = false
var chressBord = []
var _myWin = [],
_compWin = []
var myWin = []
var computerWin = []
var count = 0
var wins = []
for (var i = 0; i < 15; i++) {
wins[i] = []
for (var j = 0; j < 15; j++) {
wins[i][j] = []
}
}
context.strokeStyle = '#bfbfbf'
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()
}
}
window.onload = function () {
drawChessBoard()
}
for (var i = 0; i < 15; i++) {
chressBord[i] = []
for (var j = 0; j < 15; j++) {
chressBord[i][j] = 0
}
}
chess.onmousemove = function (e) {
var x = Math.floor((e.offsetX - 24) / 32 + 0.5),
y = Math.floor((e.offsetY - 24) / 32 + 0.5)
if (x >= 0 && y >= 0) {
demo.innerHTML = '坐标:' + x + ',' + y
}
}
chess.onmouseleave = function () {
demo.innerHTML = '坐标:'
}
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, '#6495ED')
gradient.addColorStop(1, '#f9f9f9')
}
context.fillStyle = gradient
context.fill()
}
restart.onclick = function () {
window.location.reload()
}
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.strokeStyle = '#bfbfbf'
context.stroke()
context.stroke()
context.stroke()
}
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++
}
}
for (var i = 0; i < count; i++) {
myWin[i] = 0
_myWin[i] = 0
computerWin[i] = 0
_compWin[i] = 0
}
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)
_nowi = i
_nowj = j
if (chressBord[i][j] == 0) {
oneStep(i, j, me)
chressBord[i][j] = 1
for (var k = 0; k < count; k++) {
if (wins[i][j][k]) {
myWin[k]++
_compWin[k] = computerWin[k]
computerWin[k] = 6
if (myWin[k] == 5) {
result_wrap.innerHTML = '********** 你赢了 **********'
over = true
}
}
}
if (!over) {
me = !me
computerAI()
}
}
goback.className = goback.className.replace(
new RegExp('(\\s|^)unable(\\s|$)'),
' ',
)
}
goback.onclick = function (e) {
if (!backAble) {
return
}
over = false
me = true
chressBord[_nowi][_nowj] = 0
minusStep(_nowi, _nowj)
for (var k = 0; k < count; k++) {
if (wins[_nowi][_nowj][k]) {
myWin[k]--
computerWin[k] = _compWin[k]
}
}
chressBord[_compi][_compj] = 0
minusStep(_compi, _compj)
for (var k = 0; k < count; k++) {
if (wins[_compi][_compj][k]) {
computerWin[k]--
myWin[k] = _myWin[i]
}
}
result_wrap.innerHTML = '**********人机大战五子棋**********'
returnAble = true
backAble = false
returnbtn.className = returnbtn.className.replace(
new RegExp('(\\s|^)unable(\\s|$)'),
' ',
)
}
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) {
result_wrap.innerHTML = '********** 你赢了 **********'
over = true
}
}
chressBord[_compi][_compj] = 2
oneStep(_compi, _compj, false)
for (var k = 0; k < count; k++) {
if (wins[_compi][_compj][k]) {
computerWin[k]++
_myWin[k] = myWin[k]
myWin[k] = 6
}
if (computerWin[k] == 5) {
result_wrap.innerHTML = '********** 电脑获胜 **********'
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) {
result_wrap.innerHTML = '********** 电脑获胜 **********'
over = true
}
}
}
if (!over) {
me = !me
}
backAble = true
returnAble = false
var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' ')
if (!hasClass) {
returnbtn.className += ' ' + 'unable'
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现