棋盘是一个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;
}
}

解决方案 »

  1.   

    下棋,如果碰到“将军”得要做一个提醒。
    这里的算法是把“将”当成其他棋子反向移动来判断,可以减少计算次数。
    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;
    }
      

  2.   

    Up
    学习
    Lz出作品只散50分,好少见啊!~
      

  3.   

    完整的脚本参考:
    http://www.renrousousuo.com/Scripts/ChineseChess.js
      

  4.   

    Demo参考:
    http://www.renrousousuo.com/Scripts/ChineseChess.html
      

  5.   

    清洁工能把WEB斗地主的代码共享下么
      

  6.   

    xue xi  zhong  ...
      

  7.   

    我发现DEMO里的把对方主帅杀死后
    还可以继续下呢?
      

  8.   

    楼主!向你学习啊!我把你demo下到本地,自己架不起来,这是怎么回事?
      

  9.   

    js前端+c#后端
    前端逻辑判断只是减少错误提交,真正的逻辑判断还得放到后端,否则太容易被外挂了。
      

  10.   

    还是的啊!我都下来仍然不能用!
    大哥楼主,对这个非常感兴趣!
    我看你里面用到prototype没看到导prototype.js,还有css
      

  11.   

    很强大以后CSDN搞联赛吧阴毛纺织厂杯
      

  12.   

    强,学到不少
    自荐一个在线填词页面,JS的后台,CSS界面,主要功能是诗词格律提示、格律检查等,适合对诗词感冒的朋友,同时欢迎CSDN的朋友在技术上指正:)
    网址:http://www.shicijiayuan.com贴个图: