js五子棋1
大家应该都玩过五子棋,在一个15x15的棋盘上,黑白棋轮流执子,先五子连珠者胜利。
先放一张我的单子五子棋的图:
1.html代码部分
<body>
<table id="board" cellspacing="0px">
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</table>
<div id="msg">
<input id="set" type="text" value="黑方下" readonly="readonly"/>
<div id="cd">棋数:</div>
<div id="v1" class="val">0</div>
<div id="cd">回合:</div>
<div id="v2" class="val">0</div>
<button id="cz">重置</button>
</div>
</body>
2.CSS部分
<style type="text/css">
#board {
width: 600px;
height: 600px;
float: left;
position: absolute;
top: 0px;
left: 0px;
}
#board td {
padding: 0px; //默认1px
border: 0px;
width: 40px;
height: 40px;
}
#msg {
float: left;
width: 160px;
height: 600px;
background-color: #dcdcdc;
position: absolute;
top: 0px;
left: 600px;
}
#set {
padding: 0px;
float: left;
width: 158px;
height: 80px;
font-family: "微软雅黑";
font-size: 40px;
color: blue;
}
#cd {
text-align: center;
font-family: "宋体";
font-size: 28px;
float: left;
border: solid 1px black;
width: 88px;
height: 48px;
}
.val {
text-align: center;
font-size: 40px;
float: left;
border: solid 1px black;
width: 68px;
height: 48px;
}
#cz {
font-size: 40px;
width: 160px;
height: 70px;
}
.black {
background-image: url(img/黑.png);
}
.white {
background-image: url(img/白.png);
}
</style>
3.js部分(需要引入jquery)
(1)棋盘填色(交替填入浅绿(#33ff33)、深绿色(#00cc00))
var board = document.getElementById("board");
for(var i = 0; i < board.rows.length; i++) {
for(var j = 0; j < board.rows[i].cells.length; j++) {
var cell = board.rows[i].cells[j].bgColor;
if(i % 2 == 0) {
if(j % 2 == 0) {
board.rows[i].cells[j].bgColor = "#33ff33";
} else {
board.rows[i].cells[j].bgColor = "#00cc00";
}
} else {
if(j % 2 == 0) {
board.rows[i].cells[j].bgColor = "#00cc00";
} else {
board.rows[i].cells[j].bgColor = "#33ff33";
}
}
}
}
(2)给每个单元格td绑定点击事件
//点击一个单元格的事件
$("td").click(function() {
//当前棋盘上的总棋数
var qs = parseInt($("#v1").html());
//如果当前单元格为空的话,才允许下棋
if($(this).html() == "") {
//获取单元格的行和列(因为行和列是从0开始的,为了用起来方便+1)
var row = $(this).parent().index() + 1;
var column = $(this).index() + 1;
if(qs % 2 == 0) { //黑棋下
$(this).css("background-image", "url(../img/black.png)");
$(this).css("color", "black");
$(this).html("黑");
$("#set").val("白方下");
} else { //白棋下
$(this).css("background-image", "url(../img/white.png)");
$(this).css("color", "white");
$(this).html("白");
$("#set").val("黑方下");
}
// 棋数+1
qs += 1;
$("#v1").html(qs);
//回合数 = 棋数 除以 2向上取整(黑白各下一棋子为一回合)
$("#v2").html(Math.ceil(qs / 2));
//判断是否胜利
if(isWin(row, column)) {
//总数除2能整除,表示白棋子落子后胜利,否则黑棋胜利
if(qs % 2 == 0) {
alert("白方胜");
} else {
alert("黑方胜");
}
reSet();
}
}
});
(3)绑定重置按钮事件
//点击重置按钮的事件
$("#cz").click(function(){
reSet();
})
(4)js代码中用到的其他方法
//清空棋盘
function reSet() {
//获取棋盘的table
var board = document.getElementById("board");
//双层for循环清空每一个td的innerHtml和背景
for(var i = 0; i < 15; i++) {
for(var j = 0; j < 15; j++) {
board.rows[i].cells[j].innerHTML = "";
board.rows[i].cells[j].style.background = "";
}
}
//初始化右侧计分板
$("#v1").html("0");
$("#v2").html("0");
$("#set").val("黑方下");
}
//判断是否胜利的方法
function isWin(row, column) {
//如果四个方向有一个满足胜利,则为胜利
if(isRowWin(row, column) || isColWin(row, column) || isX1Win(row, column) || isX2Win(row, column)) {
return true;
} else {
return false;
}
}
//判断横方向是否胜利
function isRowWin(row, column) {
var sum = 1;
var c = getCell(row, column)
for(var l = column - 1; l > 0; l--) {
if(c == getCell(row, l)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
}
for(var r = column + 1; r <= 15; r++) {
if(c == getCell(row, r)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
} else {
return false;
}
}
//判断竖方向是否胜利
function isColWin(row, column) {
var sum = 1;
var c = getCell(row, column);
for(var t = row - 1; t > 0; t--) {
if(c == getCell(t, column)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
}
for(var b = row + 1; b <= 15; b++) {
if(c == getCell(b, column)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
} else {
return false;
}
}
//判断左斜方向是否胜利
function isX1Win(row, column) {
var sum = 1;
var cell = getCell(row, column)
for(var r = row - 1, c = column - 1; r > 0 && c > 0; r--, c--) {
if(cell == getCell(r, c)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
}
if(sum < 5)
for(var r = row + 1, c = column + 1; r <= 15 && c <= 15; r++, c++) {
if(cell == getCell(r, c)) {
sum += 1;
} else {
break;
}
}
if(sum >= 5) {
return true;
} else {
return false;
}
}
//判断右斜方向是否胜利
function isX2Win(row, column) {
var sum = 1;
var cell = getCell(row, column)
for(var r = row - 1, c = column + 1; r > 0 && c <= 15; r--, c++) {
if(cell == getCell(r, c)) {
sum += 1;
} else {
break;
}
}
if(sum == 5) {
return true;
}
for(var r = row + 1, c = column - 1; r <= 15 && c > 0; r++, c--) {
if(cell == getCell(r, c)) {
sum += 1;
} else {
break;
}
}
if(sum > 4) {
return true;
} else {
return false;
}
}
//获得某行某列单元格的值
function getCell(row, column) {
var board = document.getElementById("board");
return board.rows[row - 1].cells[column - 1].innerHTML;
}
4.完整代码看这里
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="user-scalable=no">
<title></title>
<style type="text/css">
#board
{
width: 600px;
height: 600px;
float: left;
position: absolute;
top: 0px;
left: 0px;
}
#board td
{
padding: 0px;//默认1px
border: 0px;
width: 40px;
height: 40px;
}
#msg
{
float: left;
width: 160px;
height: 600px;
background-color: #dcdcdc;
position: absolute;
top: 0px;
left: 600px;
}
#set
{
padding: 0px;
float: left;
width: 158px;
height: 80px;
font-family: "微软雅黑";
font-size: 40px;
color: blue;
}
#cd
{
text-align: center;
font-family: "宋体";
font-size: 28px;
float: left;
border: solid 1px black;
width: 88px;
height: 48px;
}
.val
{
text-align: center;
font-size: 40px;
float: left;
border: solid 1px black;
width: 68px;
height: 48px;
}
#cz
{
font-size: 40px;
width:160px;
height: 70px;
}
.black
{
background-image:url(img/黑.png);
}
.white
{
background-image:url(img/白.png);
}
</style>
<script src="../js/jquery-3.1.1.min.js">
</script>
</head>
<body>
<table id="board" cellspacing="0px">
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
</table>
<div id="msg">
<input id="set" type="text" value="黑方下" readonly="readonly"/>
<div id="cd">棋数:</div>
<div id="v1" class="val">0</div>
<div id="cd">回合:</div>
<div id="v2" class="val">0</div>
<button id="cz">重置</button>
</div>
</body>
<script type="text/javascript">
var board = document.getElementById("board");
for (var i = 0; i < board.rows.length; i++) {
for (var j = 0; j < board.rows[i].cells.length; j++) {
var cell = board.rows[i].cells[j].bgColor;
if(i%2==0) {
if(j%2==0) {
board.rows[i].cells[j].bgColor = "#33ff33";
} else {
board.rows[i].cells[j].bgColor = "#00cc00";
}
} else {
if(j%2==0) {
board.rows[i].cells[j].bgColor = "#00cc00";
} else {
board.rows[i].cells[j].bgColor = "#33ff33";
}
}
}
}
</script>
<script >
$(document).ready(function(){
//点击一个单元格的事件
$("td").click(function(){
//当前棋盘上的总棋数
var qs = parseInt($("#v1").html());
//如果当前单元格为空的话,才允许下棋
if($(this).html()=="") {
//获取单元格的行和列(因为行和列是从0开始的,为了用起来方便+1)
var row = $(this).parent().index()+1;
var column = $(this).index()+1;
if(qs%2==0) { //黑棋下
$(this).css("background-image","url(../img/black.png)");
$(this).css("color","black");
$(this).html("黑");
$("#set").val("白方下");
} else { //白棋下
$(this).css("background-image","url(../img/white.png)");
$(this).css("color","white");
$(this).html("白");
$("#set").val("黑方下");
}
// 棋数+1
qs += 1;
$("#v1").html(qs);
//回合数 = 棋数 除以 2向上取整(黑白各下一棋子为一回合)
$("#v2").html(Math.ceil(qs/2));
//判断是否胜利
if(isWin(row,column)) {
//总数除2能整除,表示白棋子落子后胜利,否则黑棋胜利
if(qs%2==0) {
alert("白方胜");
} else {
alert("黑方胜");
}
reSet();
}
}
});
//点击重置按钮的事件
$("#cz").click(function(){
reSet();
})
})
//清空棋盘
function reSet() {
//获取棋盘的table
var board = document.getElementById("board");
//双层for循环清空每一个td的innerHtml和背景
for (var i = 0; i < 15; i++) {
for (var j = 0; j < 15; j++) {
board.rows[i].cells[j].innerHTML="";
board.rows[i].cells[j].style.background="";
}
}
//初始化右侧计分板
$("#v1").html("0");
$("#v2").html("0");
$("#set").val("黑方下");
}
//判断是否胜利的方法
function isWin(row,column) {
//如果四个方向有一个满足胜利,则为胜利
if(isRowWin(row,column)||isColWin(row,column)||isX1Win(row,column)||isX2Win(row,column)) {
return true;
} else {
return false;
}
}
//判断横方向是否胜利
function isRowWin(row,column) {
var sum=1;
var c = getCell(row,column)
for(var l=column-1;l>0;l--) {
if(c==getCell(row,l)) {
sum +=1;
} else {
break;
}
}
if (sum >= 5) {
return true;
}
for(var r=column+1;r<=15;r++) {
if(c==getCell(row,r)) {
sum +=1;
} else {
break;
}
}
if(sum>=5) {
return true;
} else {
return false;
}
}
//判断竖方向是否胜利
function isColWin(row,column) {
var sum=1;
var c = getCell(row,column);
for(var t=row-1;t>0;t--) {
if(c==getCell(t,column)) {
sum +=1;
} else {
break;
}
}
if (sum >= 5) {
return true;
}
for(var b=row+1;b<=15;b++) {
if(c==getCell(b,column)) {
sum +=1;
} else {
break;
}
}
if(sum>=5) {
return true;
} else {
return false;
}
}
//判断左斜方向是否胜利
function isX1Win(row,column) {
var sum=1;
var cell = getCell(row,column)
for(var r=row-1,c=column-1;r>0&&c>0;r--,c--) {
if(cell==getCell(r,c)) {
sum +=1;
} else {
break;
}
}
if (sum >= 5) {
return true;
}
if(sum<5)
for(var r=row+1,c=column+1;r<=15&&c<=15;r++,c++) {
if(cell==getCell(r,c)) {
sum +=1;
} else {
break;
}
}
if(sum>=5) {
return true;
} else {
return false;
}
}
//判断右斜方向是否胜利
function isX2Win(row,column) {
var sum=1;
var cell = getCell(row,column)
for(var r=row-1,c=column+1;r>0&&c<=15;r--,c++) {
if(cell==getCell(r,c)) {
sum +=1;
} else {
break;
}
}
if (sum == 5) {
return true;
}
for(var r=row+1,c=column-1;r<=15&&c>0;r++,c--) {
if(cell==getCell(r,c)) {
sum +=1;
} else {
break;
}
}
if(sum>4) {
return true;
} else {
return false;
}
}
//获得某行某列单元格的值
function getCell(row,column) {
var board = document.getElementById("board");
return board.rows[row-1].cells[column-1].innerHTML;
}
//获取2者最小值
function getMin2(no1, no2) {
return (no1 < no2 ? no1 : no2);
}
//获取3者最小值
function getMin3(no1, no2, no3) {
return getMin2(getMin2(no1, no2), no3);
}
</script>
</html>
5.结语
不知道大家发现了没有,再最后一个黑子落下时,没有显示图片,而只是显示了一个“黑”字。而且用鼠标选中棋盘时,还能看到颜色值,简直low到不行。
这种直接用dom存储数据的方式是不美观的,下一篇博客将采用二维数组存储棋盘信息来优化五子棋算法。