棋盘是一个9*10的矩阵,Javascript没有直接的二维数组,就用一维来表示
坐标和数值下标的公式:position = y * 9 + x;棋谱回放演示:
http://www.renrousousuo.com/Review/ChineseChess.aspx?id=-1
初始的棋盘布局是一样的,定义个数组常量:
1为“将” 2为“士” 3为“象”...
整数为红子、负数为黑子
var CChessConsts = {
classes: {
"0": "space"
,"1": "red1", "2": "red2", "3": "red3", "4": "red4", "5": "red5", "6": "red6", "7": "red7"
,"-1": "black1", "-2": "black2", "-3": "black3", "-4": "black4", "-5": "black5", "-6": "black6", "-7": "black7"
}
, initBorad: [
-5, -4, -3, -2, -1, -2, -3, -4, -5
, 00, 00, 00, 00, 00, 00, 00, 00, 00
, 00, -6, 00, 00, 00, 00, 00, -6, 00
, -7, 00, -7, 00, -7, 00, -7, 00, -7
, 00, 00, 00, 00, 00, 00, 00, 00, 00
, 00, 00, 00, 00, 00, 00, 00, 00, 00
, +7, 00, +7, 00, +7, 00, +7, 00, +7
, 00, +6, 00, 00, 00, 00, 00, +6, 00
, 00, 00, 00, 00, 00, 00, 00, 00, 00
, +5, +4, +3, +2, +1, +2, +3, +4, +5
]
};
每个棋盘格子是一个td,通过改变背景图来显示不同的状态
棋盘和棋子的样式表:
.div_desktop {width:459px;height:538px;}
.div_desktop input {width:65px;position:absolute;}
.div_desktop .input_username {border:none 0;background:transparent;left:70px;width:100px;font-weight:bold;}
.div_desktop .input_rank {border:none 0;background:transparent;width:70px;font-weight:bold;}
.div_player {position:relative;}.table_board{width:459px;height:510px;background:url(/Images/chinesechess_board.gif)}
.table_board td{width:51px;height:51px;text-align:center;line-height:34px;}.chess{background:url(/Images/chinesechess_corner.gif);}
.space{background:none;}
.red1{background-position:0 0;}
.red2{background-position:-50px 0;}
.red3{background-position:-100px 0;}
.red4{background-position:-150px 0;}
.red5{background-position:-200px 0;}
.red6{background-position:-250px 0;}
.red7{background-position:-300px 0;}
.black1{background-position:0 -50px;}
.black2{background-position:-50px -50px;}
.black3{background-position:-100px -50px;}
.black4{background-position:-150px -50px;}
.black5{background-position:-200px -50px;}
.black6{background-position:-250px -50px;}
.black7{background-position:-300px -50px;}
.redJiang{background-position:-200px -100px;}
.blackJiang{background-position:-250px -100px;}.cur_drag{cursor:pointer;}
.div_selection{width:50px;height:50px;background:url(/Images/chinesechess_corner.gif) no-repeat 0 -100px;}
.div_from{width:50px;height:50px;background:url(/Images/chinesechess_corner.gif) no-repeat -50px -100px;}
.div_to{width:50px;height:50px;background:url(/Images/chinesechess_corner.gif) no-repeat -50px -100px;}
.cur_kill{cursor:url(/Images/kill.cur),auto;}
.cur_move{cursor:url(/Images/footprint.cur),auto;}.div_manual{width:300px;height:510px;border:1px solid #75c6d9;overflow:scroll;}棋子能移动的位置是在用户选中棋子时计算,给可移动的位置加一些特殊效果,有不错的用户体验。(本程序中通过改变鼠标指针图案来表示)计算棋子能移动的位置:
ChineseChess.prototype.updateMovepoints = function() {
this.movepoints = {};
if (this.selection < 0) return;
if (this.echoPlace != this.currPlayer) return;
var chess = this.types[this.selection];
var x = this.selection % 9;
var y = Math.floor(this.selection / 9);
var offset = [{ x: +1, y: 00 }, { x: -1, y: 00 }, { x: 00, y: +1 }, { x: 00, y: -1 }];
var offsetX = [{ x: +1, y: +1 }, { x: -1, y: -1 }, { x: +1, y: -1 }, { x: -1, y: +1 }];
var offset8 = [
{ x: +2, y: -1 }
, { x: +2, y: +1 }
, { x: -2, y: -1 }
, { x: -2, y: +1 }
, { x: +1, y: +2 }
, { x: -1, y: +2 }
, { x: -1, y: -2 }
, { x: +1, y: -2 }
];
var position;
var mx, my, i;
switch (Math.abs(chess)) {
case 1: // 帅
for (i = 0; i < offset.length; i++) {
mx = x + offset[i].x;
my = y + offset[i].y;
if (mx < 3 || mx > 5 || my < 0 || my >= 10) continue;
if (chess > 0 && my < 7) continue;
if (chess < 0 && my > 2) continue;
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
}
}
// 见面
i = chess > 0 ? 3 : 2;
mx = x + offset[i].x;
my = y + offset[i].y;
while (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] != 0) {
if (this.types[position] == -chess)
this.movepoints[position] = "kill";
break;
}
mx += offset[i].x;
my += offset[i].y;
}
break;
case 2: // 士
for (i = 0; i < offsetX.length; i++) {
mx = x + offsetX[i].x;
my = y + offsetX[i].y;
if (mx < 3 || mx > 5 || my < 0 || my >= 10) continue;
if (chess > 0 && my < 7) continue;
if (chess < 0 && my > 2) continue;
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
}
}
break;
case 3: // 象
for (i = 0; i < offsetX.length; i++) {
mx = x + offsetX[i].x;
my = y + offsetX[i].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
if (this.types[my * 9 + mx] != 0) continue; // 中间有棋子
mx += offsetX[i].x;
my += offsetX[i].y;
if (mx < 0 || mx > 9) continue;
if (chess > 0 && my < 5) continue;
if (chess < 0 && my > 4) continue;
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
}
}
break;
case 4: // 马
for (i = 0; i < offset8.length; i++) {
var check = Math.floor(i / 2);
mx = x + offset[check].x;
my = y + offset[check].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
if (this.types[my * 9 + mx] != 0) continue; // 中间有棋子
mx = x + offset8[i].x;
my = y + offset8[i].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
}
}
break;
case 5: // 車
for (i = 0; i < offset.length; i++) {
mx = x + offset[i].x;
my = y + offset[i].y;
while (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
break;
}
mx += offset[i].x;
my += offset[i].y;
}
}
break;
case 6: // 炮
for (i = 0; i < offset.length; i++) {
mx = x + offset[i].x;
my = y + offset[i].y;
var kill = false;
while (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] == 0) {
if (!kill) this.movepoints[position] = "move";
} else {
if (kill) {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
break;
}
kill = true;
}
mx += offset[i].x;
my += offset[i].y;
}
}
break;
case 7: // 兵
for (i = 0; i < offset.length; i++) {
if (chess > 0 && (offset[i].y > 0 || y > 4 && offset[i].x != 0)) continue;
if (chess < 0 && (offset[i].y < 0 || y < 5 && offset[i].x != 0)) continue;
mx = x + offset[i].x;
my = y + offset[i].y;
if (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] == 0) {
this.movepoints[position] = "move";
} else {
if (sign(this.types[position]) != sign(chess))
this.movepoints[position] = "kill";
}
}
}
break;
}
}
解决方案 »
- 鼠标离开菜单渐渐消失的效果
- 阿里巴巴的这种效果是怎么做到的?
- 寻一个JS效果,问题内详
- 求 获取 数据库的值 使用 jquery 来实现 动态级联 的案例
- 我用js写了一些正则表达式,但是发现在大部分机器上现实正常,但是在少部分机器上显示出错,以下即为我写的正则表达式:
- 请问如果检查java虚拟机是否已经安装?
- 问:如何给表单赋值!
- 如何把动态生成的行也显示出来?
- 如何通过frames[i]这样的方式访问iframe内的页面?
- 一个很挑战的JavaScript的问题!!!!!!!!!!!!!
- 求助——当html语言放在javascript语句中如何改写,单引号和双引号所引起的问题
- 小贝请教,一个页面有很多滑动门,如何共用JS,谢谢。
这里的算法是把“将”当成其他棋子反向移动来判断,可以减少计算次数。
ChineseChess.prototype.TryJiang = function(place) {
var start = place == 0 ? 7 : 0;
var step = place == 0 ? -1 : +1;
var offset = [{ x: +1, y: 00 }, { x: -1, y: 00 }, { x: 00, y: +1 }, { x: 00, y: -1 }];
var offsetX = [{ x: +1, y: +1 }, { x: -1, y: -1 }, { x: +1, y: -1 }, { x: -1, y: +1 }];
var offset8 = [
{ x: +2, y: +1 }
, { x: +1, y: +2 }
, { x: -2, y: -1 }
, { x: -1, y: -2 }
, { x: +2, y: -1 }
, { x: +1, y: -2 }
, { x: -2, y: +1 }
, { x: -1, y: +2 }
];
var position;
var mx, my, i; for (var x = 3; x <= 5; x++)
for (var y = start; y <= start + 2; y++) {
if (Math.abs(this.types[y * 9 + x]) == 1) {
// 1 帅 是否将对面
my = y;
mx = x;
while (my >= 0 && my <= 9) {
position = my * 9 + mx;
if (this.types[position] != 0) {
if (this.types[position] == 1 * step)
return true;
break;
}
my += step;
}
// 4 马
for (i = 0; i < offset8.length; i++) {
var check = Math.floor(i / 2);
mx = x + offsetX[check].x;
my = y + offsetX[check].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
if (this.types[my * 9 + mx] != 0) continue; // 中间有棋子
mx = x + offset8[i].x;
my = y + offset8[i].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
position = my * 9 + mx;
if (this.types[position] == 4 * step)
return true;
} // 5 車
for (i = 0; i < offset.length; i++) {
mx = x + offset[i].x;
my = y + offset[i].y;
while (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] != 0) {
if (this.types[position] == 5 * step)
return true;
break;
}
mx += offset[i].x;
my += offset[i].y;
}
} // 6 炮
for (i = 0; i < offset.length; i++) {
mx = x + offset[i].x;
my = y + offset[i].y;
var kill = false;
while (mx >= 0 && mx < 9 && my >= 0 && my < 10) {
position = my * 9 + mx;
if (this.types[position] != 0) {
if (kill) {
if (this.types[position] == 6 * step)
return true;
break;
}
kill = true;
}
mx += offset[i].x;
my += offset[i].y;
}
} // 7 兵
for (i = 0; i < offset.length; i++) {
if (offset[i].y == -step) continue;
mx = x + offset[i].x;
my = y + offset[i].y;
if (mx < 0 || mx >= 9 || my < 0 || my >= 10) continue;
position = my * 9 + mx;
if (this.types[position] == 7 * step)
return true;
}
}
}
return false;
}
学习
Lz出作品只散50分,好少见啊!~
http://www.renrousousuo.com/Scripts/ChineseChess.js
http://www.renrousousuo.com/Scripts/ChineseChess.html
还可以继续下呢?
前端逻辑判断只是减少错误提交,真正的逻辑判断还得放到后端,否则太容易被外挂了。
大哥楼主,对这个非常感兴趣!
我看你里面用到prototype没看到导prototype.js,还有css
自荐一个在线填词页面,JS的后台,CSS界面,主要功能是诗词格律提示、格律检查等,适合对诗词感冒的朋友,同时欢迎CSDN的朋友在技术上指正:)
网址:http://www.shicijiayuan.com贴个图: