---
layout: false
---
{% raw %}
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>五子棋 | TRHX'S BLOG</title>
    <link rel="shortcut icon" href="https://cdn.jsdelivr.net/gh/TRHX/CDN-for-itrhx.com@3.0.4/images/favicon.ico"type="image/x-icon">
	<style type='text/css'>
		canvas {
			display: block;
			margin: 60px auto;
			box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
			cursor: pointer;
		}
		.btn-wrap {
			display: flex;
			flex-direction: row;
			justify-content: center;
		}
		.btn-wrap div {
			margin: 0 10px;
		}
		div>span {
			display: inline-block;
			padding: 10px 20px;
			color: #fff;
			background-color: #6496ED;
			border-radius: 5px;
			cursor: pointer;
		}
		div.unable span {
			background: #D6D6D4;
			color: #adacaa;
		}
		#result-wrap {
            text-align: center;
            margin:50px 0 0 0;
        }
        #footer{position:relative;clear:both;padding:10px 20px 40px 0;padding:10px 0;width:100%;text-align:center}#footer address{display:inline-block;padding:2px 10px;color:rgba(0,0,0,.5);font-style:normal}
        #footer a{color:rgba(0,0,0,.5);cursor:grab}#footer a:hover{border-bottom:1px dotted #00387d;color:#00387d}
	</style>
</head>
<body ondragstart="window.event.returnValue=false" oncontextmenu="window.event.returnValue=false" onselectstart="event.returnValue=false">
	<h3 id="result-wrap">人机五子棋对弈</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>
	<script type="text/javascript" charset="utf-8">
		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");
		window.onload = function () {
			drawChessBoard();
			// 画棋盘
		}
		document.getElementById("restart").onclick = function () {
			window.location.reload();
		}
		// 我，下棋
		chess.onclick = function (e) {
			if (over) {
				return;
			}
			if (!me) {
				return;
			}
			// 悔棋功能可用
			backbtn.className = backbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
			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++) {
					// 将可能赢的情况都加1
					if (wins[i][j][k]) {
						// debugger;
						myWin[k]++;
						_compWin[k] = computerWin[k];
						computerWin[k] = 6; //这个位置对方不可能赢了
						if (myWin[k] == 5) {
							// window.alert('你赢了');
							resultTxt.innerHTML = '恭喜，你赢了！';
							over = true;
						}
					}
				}
				if (!over) {
					me = !me;
					computerAI();
				}
			}
		}
		// 悔棋
		backbtn.onclick = function (e) {
			if (!backAble) {
				return;
			}
			over = false;
			me = true;
			// resultTxt.innerHTML = 'emmmm，悔棋中';
			// 撤销悔棋功能可用
			returnbtn.className = returnbtn.className.replace(new RegExp("(\\s|^)unable(\\s|$)"), " ");
			// 我，悔棋
			chressBord[_nowi][_nowj] = 0; //我，已占位置 还原
			minusStep(_nowi, _nowj); //销毁棋子
			for (var k = 0; k < count; k++) {
				// 将可能赢的情况都减1
				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++) {
				// 将可能赢的情况都减1
				if (wins[_compi][_compj][k]) {
					computerWin[k]--;
					myWin[k] = _myWin[i]; //这个位置对方可能赢
				}
			}
			resultTxt.innerHTML = '--人机五子棋--';
			returnAble = true;
			backAble = false;
		}
		// 撤销悔棋
		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) {
					resultTxt.innerHTML = '恭喜，你赢了！';
					over = true;
				}
			}// 计算机撤销相应的悔棋
			chressBord[_compi][_compj] = 2; //计算机，已占位置
			oneStep(_compi, _compj, false);
			for (var k = 0; k < count; k++) {
				// 将可能赢的情况都减1
				if (wins[_compi][_compj][k]) {
					computerWin[k]++;
					_myWin[k] = myWin[k];
					myWin[k] = 6; //这个位置对方不可能赢
				}
				if (computerWin[k] == 5) {
					resultTxt.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) {
						resultTxt.innerHTML = '很遗憾，计算机赢了，继续加油哦！';
						over = true;
					}
				}
			}
			if (!over) {
				me = !me;
			}
			backAble = true;
			returnAble = false;
			var hasClass = new RegExp('unable').test(' ' + returnbtn.className + ' ');
			if (!hasClass) {
				returnbtn.className += ' ' + 'unable';
			}
		}
		//绘画棋盘
		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();
		}
		//销毁棋子
		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();
		}
	</script>
      <footer id="footer" role="contentinfo" style="top:100px;">
    <address>
        <div class="copyright" style="font-size: 13px;">
            Copyright&nbsp;©&nbsp;2018-2019&nbsp;<a href="https://www.itrhx.com/" target="_blank">TRHX'S BLOG</a>&nbsp;|&nbsp;
            <img src="https://cdn.jsdelivr.net/gh/TRHX/CDN-for-itrhx.com@3.0.4/images/icp.png" class="footer-icon">&nbsp;
            <a href="http://www.beian.miit.gov.cn/" target="_blank"> 鄂ICP备19003281号-3</a>&nbsp;|&nbsp;
            <img src="https://cdn.jsdelivr.net/gh/TRHX/CDN-for-itrhx.com@3.0.4/images/12377.png" alt=" 12377.png">
            <a href="http://www.12377.cn/" target="_blank">中国互联网违法和不良信息举报中心</a><br><br>
            推荐使用1920*1080分辨率、谷歌或者火狐浏览器浏览此页&nbsp;|&nbsp;
            <a href="https://itrhx.com/sitemap.xml" target="_blank">站点地图</a>&nbsp;|&nbsp;
            <script type="text/javascript" src="https://s23.cnzz.com/z_stat.php?id=1275909280&web_id=1275909280"></script>&nbsp;|&nbsp;
            <a href="https://www.itrhx.com/atom.xml" target="_blank">RSS订阅</a>&nbsp;|&nbsp;
            <a href="https://996.icu/" target="_blank">996.ICU</a>&nbsp;|&nbsp;
            <a href="https://www.itrhx.com/friends/" target="_blank">申请友链</a>&nbsp;|&nbsp;
            Powered By <a href="https://hexo.io/" target="_blank">Hexo</a>&nbsp;|&nbsp;
            Hosted By <a href="https://github.com/" target="_blank">GitHub Pages</a><br><br>
            部分资料来源于网络，版权属于其合法持有人，只供学习交流之用，非商务用途。如有侵犯您的权益，请及时告知删除。互动交流时请遵守理性，宽容，换位思考的原则。
        </div>
    </address>
</footer>
</body>
<script>
    document.onkeydown=function (e){
            var currKey=0,evt=e||window.event;
            currKey=evt.keyCode||evt.which||evt.charCode;
            if (currKey == 123) {
                window.event.cancelBubble = true;
                window.event.returnValue = false;
            }
        }
</script>
</html>
{% endraw %}