版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81978903
/** 苏拉克尔塔游戏
* 思路:
* 1.棋盘设置:使用HTML5的canvas标签绘制整个棋盘
* 2.点击事件:当页面被点击时,获取点击的x,y像素点,根据此像素点进行判断,再在合适位置绘制黑红棋子,棋子均是使用canvas绘制的
* 3.保存落子记录:将数据存入一个二维数组,x和y表是落子坐标,1为白棋,2为黑棋,0代表此处无棋子,只有没有棋子的才能落子
* 4.判断输赢:每次落子后以此坐标分别向左右,上下,右下,右上进行判断,设参数count,遇到同色棋子+1,遇到空格或不同色棋子终止,当count=5时,游戏结束
* 20180823
*/
完整项目源码已经开源:https://github.com/xiugangzhang/SularaGame
项目在线预览地址:
http://htmlpreview.github.io/?https://github.com/xiugangzhang/SularaGame/blob/master/SularaGame.html
主要功能:
1.棋盘棋子的初始化
2.走棋规则的实现
3.输赢的判定
4.自动走棋的实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SuraKarta Game</title>
</head>
<body onload="startLoad()" style="padding:0px;margin:0px">
<canvas width="700" id="canvas" onmousedown="play(event)" height="600">
</canvas>
<div style=" border: solid 2px purple;
display: block;
position:absolute;
left:750px;
top:50px;
width: 100px;
height: 500px;
text-align: center;
margin:auto;
line-height: 45px;">
<input type="button" value="START" id="begin" onclick="isNewGame()"/>
<input type="button" value="STOP" id="replay" onclick="isExitGame()"/>
</div>
</body>
<script type="text/javascript">
/** 苏拉克尔塔游戏
* 思路:
* 1.棋盘设置:使用HTML5的canvas标签绘制整个棋盘
* 2.点击事件:当页面被点击时,获取点击的x,y像素点,根据此像素点进行判断,再在合适位置绘制黑红棋子,棋子均是使用canvas绘制的
* 3.保存落子记录:将数据存入一个二维数组,x和y表是落子坐标,1为白棋,2为黑棋,0代表此处无棋子,只有没有棋子的才能落子
* 4.判断输赢:每次落子后以此坐标分别向左右,上下,右下,右上进行判断,设参数count,遇到同色棋子+1,遇到空格或不同色棋子终止,当count=5时,游戏结束
* 20180823
*/
/**全局参数初始化
*
*/
var canvas; //html5画布
var context;
var isRed = false; //设置是否该轮到白棋,黑棋先手
var winner = ''; //赢家初始化为空
var step = 225;//总步数
// 记录棋盘的位置坐标
var chessData = new Array(6); //二维数组存储棋盘落子信息,初始化数组chessData值为0即此处没有棋子,1为红棋,2为黑棋
for (var x = 0; x < 6; x++) {
chessData[x] = new Array(6);
for (var y = 0; y < 6; y++) {
chessData[x][y] = 0;
}
}
/**每次打开网页加载棋盘和相关游戏信息
*
*/
function startLoad() {
drawRect();
// 会加载游戏上一局保存的记录
//loadGame();
}
/**棋盘样式信息
*
*/
function drawRect() {
/*//创建棋盘背景
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.fillStyle = '#FFFFFF';
context.fillRect(0, 0, 1024, 768);
//标题
context.fillStyle = '#00f';
context.font = '20px Consols';
context.strokeText('SuraKarta Game Board', 750, 150);
context.strokeRect(745, 120, 230, 250);*/
//新游戏
context.strokeRect(790, 180, 120, 30);
context.fillStyle = '#00f';
context.font = '25px Consols';
context.strokeText('START', 809, 205);
//结束游戏
context.strokeRect(790, 250, 120, 30);
context.fillStyle = '#00f';
context.font = '25px Consols';
context.strokeText('STOP', 812, 275);
//游戏说明
/*context.fillStyle = '#00f';
context.font = '15px Arial';
context.strokeText('游戏规则:玩家执黑色', 780, 200);
context.strokeText('棋子先手,电脑执白色棋子', 750, 220);
context.strokeText('后手,任何一方形成五子连', 750, 240);
context.strokeText('珠,游戏终止。', 750, 260);*/
//棋盘纵横线
for (var i = 1; i < 7; i++) {
if (i == 1 || i == 6) {
context.lineWidth = 8;
context.strokeStyle = '#FEFE02';
} else if (i == 2 || i == 5) {
context.lineWidth = 8;
context.strokeStyle = '#02CFFF';
} else {
context.lineWidth = 8;
context.strokeStyle = '#028202';
}
context.beginPath();
context.moveTo(57 * i + 160, 150);
context.lineTo(57 * i + 160, 437);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(216, 57 * i + 94);
context.lineTo(501, 57 * i + 94);
context.closePath();
context.stroke();
}
// 圆弧的绘制
//弧度是以x轴正方向为基准、进行顺时针旋转的角度来计算
// true 表示逆时针, false表示顺时针
var x = 0;
var y = 0;
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#02CFFF';
context.arc(217, 151, 57, 0, getRads(90), true);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#028202';
context.arc(217, 151, 57 * 2, 0, getRads(90), true);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#02CFFF';
context.arc(502, 150, 57, getRads(90), getRads(180), true);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#028202';
context.arc(502, 150, 57 * 2, getRads(90), getRads(180), true);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#02CFFF';
context.arc(217, 436, 57, getRads(0), getRads(270), false);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#028202';
context.arc(217, 436, 57 * 2, getRads(0), getRads(270), false);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#02CFFF';
context.arc(503, 436, 57, getRads(-90), getRads(180), false);
context.stroke();
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#028202';
context.arc(503, 436, 57 * 2, getRads(-90), getRads(180), false);
context.stroke();
}
// 重绘棋盘
function update() {
context.clearRect(0, 0, 700, 600);
drawRect();
}
/**加载游戏记录
* 通过cookie查询是否存在游戏记录,有则加载
*/
function loadGame() {
var we = getCookie("red");
console.log("获取白色棋子的cookie" + we);
loadChessByCookie("white", we);
var bk = getCookie("black");
console.log("获取黑色棋子的cookie" + bk);
loadChessByCookie("black", bk);
winner = getCookie("winner"); //如果没有winner的cookie存在的话此处winner的值会被设为null
//判断是否该电脑走
// var temp=getCookie("isRed");
// if(temp!=null){
// if(temp=="true"){
// AIplay();
// }
// }
}
/**分割cookie中获取的字符串,从而加载棋子
* @param {[type]} color [description]
* @param {[type]} record [description]
* @return {[type]} [description]
*/
function loadChessByCookie(color, record) {
if (record == null) {
console.log(color + "棋子没有游戏记录");
} else {
var a = record.split(";");
console.log(color + "第一次分割字符串:" + a)
for (var i = 0; i < a.length; i++) {
var b = a[i].split(",");
console.log("第" + (i + 1) + "个" + color + "棋子坐标:" + parseInt(b[0]) + "," + parseInt(b[1]));
chess(color, b[0], b[1]);
}
}
}
/** 落子
* @param {[type]} turn [description]
* @param {[type]} x [description]
* @param {[type]} y [description]
* @return {[type]} [description]
*/
function drawChess(color, x, y) { //参数为,棋(1为白棋,2为黑棋),数组位置
if (x >= 0 && x < 6 && y >= 0 && y < 6) {
if (color == "red") {
chess("red", x, y);
} else if (color == "black") {
chess("black", x, y);
} else if (color == "blue" && isSelected) {
chess("blue", x, y);
}
}
/*if (--step == 0) {
winner = "和局";
setCookie("winner", winner);
alert(winner);
}*/
}
/**绘制棋子,每次绘制棋子的时候刷新cookie信息
*
*/
function chess(color, x, y) {
if (x > 6 || y > 6 || x < 0 || y < 0 || x == 6 || y == 6){
return;
}
context.fillStyle = color;
context.beginPath();
// 绘制棋子(注意要把棋子的初始位置复位)
context.arc(x * 56 + 217, y * 56 + 150, 20, 0, Math.PI * 2, true);
context.closePath();
context.fill();
if (color == "red") {
console.log("电脑在" + x + "," + y + "画了个红棋");
// 1为红棋子
chessData[x][y] = 1;
} else if (color == "black") {
// 2为黑棋子
console.log("电脑在" + x + "," + y + "画了个黑棋");
chessData[x][y] = 2;
}
/*var a = getCookie(color);
if (a != null) {
delCookie(color);
setCookie(color, a + ";" + x + "," + y, 30);
} else {
setCookie(color, x + "," + y, 30);
}*/
}
/**鼠标点击事件
* 在这里开始完成棋子的博弈操作
* @param {[type]} e [description]
* @return {[type]} [description]
*/
function play(e) { //鼠标点击时发生
var color;
var e = e || event;
console.log("(e.x, e.y) = " + "(" + e.clientX + ", " + e.clientY + ")");
// 用这个棋盘的初始位置为坐标的原点(217, 150)
var px = e.clientX - 217;
var py = e.clientY - 150;
console.log("(px, py) = " + "(" + px + ", " + py + ")");
// 棋子的大小
var x = parseInt(px / 57);
var y = parseInt(py / 57);
console.log("(x, y) = " + "(" + x + ", " + y + ")");
//isNewGame(e.clientX, e.clientY); //是否点击了newgame
//isExitGame(e.clientX, e.clientY); //是否点击了exitGame
// 划定棋盘的位置范围
if (px < 0 || py < 0 || x > 5 || y > 5) { //鼠标点击棋盘外的区域不响应
return;
}
//chess('red', 2, 3);
doCheck(x, y);
}
// 检查鼠标当前点击的位置上有没有棋子
var isSelected = false;
var selectedX = -1;
var selectedY = -1;
var movetoX =-1;
var movetoY =-1;
// 选中的棋子ID
//var selectedChess;
var chessId = 1;
var col;
var row;
for (var i=0; i<24; i++){
drawChessById(i);
}
var stone = new Array(24);
function drawChessById(id, x, y) {
/*
// 黑色
if (id == "00"){
chess("red", 0, 0);
}if (id == "10"){
}if (id == "20"){
}if (id == "30"){
}if (id == "40"){
}if (id == "50"){
}if (id == "01"){
}if (id == "11"){
}if (id == "21"){
}if (id == "31"){
}if (id == "41"){
}if (id == "51"){
}
// 红色
if (id == "04"){
}if (id == "14"){
}if (id == "24"){
}if (id == "34"){
}if (id == "44"){
}if (id == "54"){
}if (id == "05"){
}if (id == "15"){
}if (id == "25"){
}if (id == "35"){
}if (id == "45"){
}if (id == "55"){
}*/
//
//chess(stone[id], x, y);
}
// 记录选中的棋子的ID
function doCheck(x, y) {
if (winner != '' && winner != null) { //已经结束的游戏只能点击new game
//alert(winner);
//return;
}
// 判断是黑棋子还是红棋子(注意在判断的时候要使用双等号, 不要使用一个等号哈)
var chessColor;
// 红色棋子被选中
// 每次点击一次, 都要把键盘的所有棋子重新绘制一次, 而不是去覆盖
// 判断点击的位置有没有棋子被选中
if (chessData[x][y] != 0) {
//alert("有棋子");
isSelected = true;
} else {
alert("没有棋子");
isSelected = false;
}
//chess("blue", 1, 2);
// 如果有棋子被选中了
if (isSelected) {
// 开始绘制棋子
chessColor = "blue";
// 把选中的棋子的坐标记录下来
selectedX = x;
selectedY = y;
if (chessData[x][y] == 1) {
/*alert("你选择的是红色棋子" + "这个棋子的ID是" + selectedX
+ selectedY);*/
chessId = selectedX+","+selectedY;
alert("chessId="+chessId);
}
else {
/*alert("你选择的是黑色棋子" + "这个棋子的ID是" + selectedX + selectedY);*/
chessId = selectedX+","+selectedY;
alert("chessId="+chessId);
}
// 重新绘制
//drawRedAndBlackChess(chessColor, selectedX, selectedY);
// 棋盘上面任意位置有棋子被选中就变颜色
update();
// 棋子选中的位置变颜色
if (chessData[selectedX][selectedY] != 0) {
chess("blue", selectedX, selectedY);
// 记录这个选中的棋子的id
var id = selectedX + "" + selectedY;
alert("ID" + id);
// 只要这个棋子选中了
drawRedAndBlackChess("blue", selectedX, selectedY);
}
}
// 第一次选择了棋子, 第二次点击其他位置
if (!isSelected){
alert("开始移动");
// 记录鼠标将要移动到的位置
movetoX = x;
movetoY = y;
//移动棋子到新的位置
//alert("movetoX, movetoY"+x+", "+y);
// 强制加载当前的文档
//location.reload();
// 移动当前的棋子(开始重绘)
//update();
// 移动棋子
chessMove(selectedX, selectedY, movetoX, movetoY);
//drawRedAndBlackChess(chessColor, selectedX, selectedY);
}
}
// 根据棋子的ID来绘制棋子
/*var row;
var col;
var type;
var arr = new Array(24);
function drawChessById(id) {
var chess = arr[id];
// 根据行列号来
}*/
// 对绘制好的棋子赋值id
var arr = new Array(24);
function getChessidByRowCol(row, col) {
for(var i=0; i<6; i++){
for (var j=0; j<6; j++){
//alert();
arr.push();
}
}
}
// 移动棋子(源位置移动到目标位置)
function chessMove(selectedX, selectedY, movetoX, movetoY) {
//alert(selectedX+" "+selectedY+","+movetoX+" "+movetoY);
// 从源位置移动到目标位置
// 红色棋子在移动
// 原来的位置不画
//update();
if (chessData[selectedX][selectedY] == 1) {
alert("SeID"+selectedX+selectedY+"选择的"+chessId);
update();
//location.reload();
//alert("红色");
// 红色棋子移动到的位置
chess("red", movetoX, movetoY);
// 绘制红色棋子(移动的位置不用画, 其他的位置都要画出来)
// 这个是在最下面两行绘制的红色棋子的方式
for (var j = 0; j < 6; j++) {
for (var i = 4; i < 6; i++) {
// 开始绘制更新后的红色棋子
if (j == selectedX && i == selectedY) {
// 这个位置就是那个之前移动棋子的位置
continue;
} else {
chess("red", j, i);
}
}
}
/*for (var i=0; i<6; i++){
for (var j=0; j<6; j++){
if (j == selectedX && i == selectedY){
//chess("red", selectedX, selectedY);
continue;
}
chess("red", selectedX, selectedY);
}
}*/
for (var j = 0; j < 6; j++) {
for (var i = 0; i < 2; i++) {
chess("black", j, i);
}
}
}
// 黑色棋子在移动
if (chessData[selectedX][selectedY] == 2) {
// 绘制红色棋子(移动的位置不用画, 其他的位置都要画出来)
for (var j = 0; j < 6; j++) {
for (var i = 4; i < 6; i++) {
chess("red", j, i);
}
}
//alert("黑色");
// 绘制黑色棋子
//alert("chess move");
chess("black", movetoX, movetoY);
for (var j = 0; j < 6; j++) {
for (var i = 0; i < 2; i++) {
// 把选中的棋子设为蓝色
// 除了原来的位置不画出来,其他位置都要画
if (selectedX == j && selectedY == i) {
// 原来的这个位置不画出来
continue;
}
chess("black", j, i);
}
}
}
}
/**新游戏按钮
*
*/
function isNewGame(x, y) {
if (confirm("Arr you sure to play new game now?")) {
update();
// 从新摆棋子
drawRedAndBlackChess();
//chess("red", 1, 2);
//chess("black", 2, 2);
// 创建24个棋子对象
/*for (var i=0; i<24; i++){
drawChessById(i, x, y);
}*/
}
}
// 主要用于绘制24个棋子
function drawRedAndBlackChess(chesscolor, x, y) {
// 绘制黑色棋子12 个
for (var j = 0; j < 6; j++) {
for (var i = 0; i < 2; i++) {
// 把选中的棋子设为蓝色
if (isSelected && j == x && i == y) {
//alert("isSelected && j==x && i==y");
//chess(chesscolor, j, i);
}
else {
chess("black", j, i);
}
}
}
// 绘制红色棋子 12个
for (var j = 0; j < 6; j++) {
for (var i = 4; i < 6; i++) {
if (isSelected && j == x && i == y) {
//alert("isSelected && j==x && i==y");
//chess(chesscolor, j, i);
} else {
chess("red", j, i);
}
}
}
}
// 退出游戏
function isExitGame(x, y) {
if (confirm("Are you sure to exit game now?")) {
//退出游戏
window.close();
}
}
/**判断此局游戏是否已有结果
* 每次落子判断游戏是否胜利
*
*/
function isWin(color, x, y) {
console.log("判断" + color + "(" + x + "," + y + ")是否胜利");
var temp = 2; //默认为黑色
if (color == "white") {
temp = 1;
} //白色
console.log("temp=" + temp);
lrCount(temp, x, y);
tbCount(temp, x, y);
rtCount(temp, x, y);
rbCount(temp, x, y);
}
function lrCount(temp, x, y) {
var line = new Array(4);
var count = 0;
for (var i = x; i >= 0; i--) {
line[0] = i;
line[1] = y;
if (chessData[i][y] == temp) {
++count;
} else {
i = -1;
}
}
for (var i = x; i <= 6; i++) {
line[2] = i;
line[3] = y;
if (chessData[i][y] == temp) {
++count;
} else {
i = 100;
}
}
success(line[0], line[1], line[2], line[3], temp, --count);
}
function tbCount(temp, x, y) {
var line = new Array(4);
var count = 0;
for (var i = y; i >= 0; i--) {
line[0] = x;
line[1] = i;
if (chessData[x][i] == temp) {
++count;
} else {
i = -1;
}
}
for (var i = y; i <= 14; i++) {
line[2] = x;
line[3] = i;
if (chessData[x][i] == temp) {
++count;
} else {
i = 100;
}
}
success(line[0], line[1], line[2], line[3], temp, --count);
}
function rtCount(temp, x, y) {
var line = new Array(4);
var count = 0;
for (var i = x, j = y; i <= 14 && j >= 0;) {
line[0] = i;
line[1] = j;
if (chessData[i][j] == temp) {
++count;
} else {
i = 100;
}
i++;
j--;
}
for (var i = x, j = y; i >= 0 && j <= 14;) {
line[2] = i;
line[3] = j;
if (chessData[i][j] == temp) {
++count;
} else {
i = -1;
}
i--;
j++;
}
success(line[0], line[1], line[2], line[3], temp, --count);
}
function rbCount(temp, x, y) {
//右下斜判断
var line = new Array(4);
var count = 0;
for (var i = x, j = y; i >= 0 && j >= 0;) {
line[0] = i;
line[1] = j;
if (chessData[i][j] == temp) {
++count;
} else {
i = -1;
}
i--;
j--;
}
for (var i = x, j = y; i <= 14 && j <= 14;) {
line[2] = i;
line[3] = j;
if (chessData[i][j] == temp) {
++count;
} else {
i = 100;
}
i++;
j++;
}
success(line[0], line[1], line[2], line[3], temp, --count);
}
/**判断是否胜利及胜利之后的操作
* @param {[type]} turn [description]
* @param {[type]} count [description]
* @return {[type]} [description]
*/
function success(a, b, c, d, temp, count) {
if (count == 5) { //因为落子点重复计算了一次
console.log("此局游戏结束啦");
console.log("(" + a + "," + b + ")" + "到" + "(" + c + "," + d + ")");
context.beginPath();
context.lineWidth = 5;
context.strokeStyle = 'purple';
context.moveTo(40 * a + 180, 40 * b + 80);
context.lineTo(40 * c + 180, 40 * d + 80);
context.closePath();
context.stroke();
winner = "黑棋胜利!";
if (temp == 1) {
winner = "白棋胜利!";
}
setCookie("winner", winner);
alert(winner);
}
}
/**使用cookie保存棋盘信息,防止不小心关闭网页
* @param {[type]} name [description]
* @param {[type]} value [description]
* @param {[type]} time [description]
*/
function setCookie(name, value, time) {
var exp = new Date();
exp.setTime(exp.getTime() + time * 24 * 60 * 60 * 1000);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
}
/**获取cookie,初始化棋盘
*cookie
*/
function getCookie(name) {
var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
if (arr = document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
/**删除cookie
*
*/
function delCookie(name) {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = getCookie(name);
if (cval != null)
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
}
/**
* 禁止页面滚动事件
* @return {[type]} [description]
*/
var pageScroll = 0;
window.onscroll = function () {
pageScroll++;
scrollTo(0, 0);
if (pageScroll > 100) { //每当玩家滚动页面滚动条100次提醒
pageScroll = 0;
}
}
/**
* 工具函数
*/
function getRads(degrees) {
return (Math.PI * degrees) / 180;
}
function getDegrees(rads) {
return (rads * 180) / Math.PI;
}
</script>
</html>