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存储数据的方式是不美观的,下一篇博客将采用二维数组存储棋盘信息来优化五子棋算法。