开发所用技术
前端的话我选用vue-cli 3.0 + ts + pug + stylus
象棋的话肯定是俩个人玩的,俩个人的话就存在了及时更新,所以会加入websocket
后端的话我选用egg.js 数据库用的mysql 把每个棋的位置记录保存, 方便俩人在线上对战
思路
第一步分析棋盘大小
先上一张我在vscode上弄的草图 我们可以从图中看出 象棋是9*11的一个长方形
// 先生成一个9*10的棋盘
const RedChessArray = [];
for (let i = 0; i < 10; i++) {
const xArr = [];
for (let i = 0; i < 9; i++) {
xArr.push({chessName: '', playerPower: '', act: false})
}
RedChessArray.push(xArr)
}
// 然后我们在数组的中间插入楚河汉界
RedChessArray.splice(5, 0, [{chessName: '楚河汉界', playerPower:'', act: false }]);
好了 大功告成 现在应该9*11的棋盘就生成了
const RedChessArrays = RedChessArray;
// 目前在撸规则期,暂时还没写api 所以先用写死的json
const RedChessJson = [{
player: 'cat',
playerPower: 'red',
chess: [{chessName: '帅', x: 0, y: 0},
{chessName: '帅', x: 0, y: 4},
{chessName: '士', x: 0, y: 3},
{chessName: '士', x: 0, y: 5},
{chessName: '相', x: 0, y: 2},
{chessName: '相', x: 0, y: 6},
{chessName: '马', x: 0, y: 1},
{chessName: '马', x: 0, y: 7},
{chessName: '车', x: 0, y: 0},
{chessName: '车', x: 0, y: 8},
{chessName: '炮', x: 2, y: 1},
{chessName: '炮', x: 2, y: 7},
{chessName: '兵', x: 3, y: 0},
{chessName: '兵', x: 3, y: 2},
{chessName: '兵', x: 3, y: 4},
{chessName: '兵', x: 3, y: 6},
{chessName: '兵', x: 3, y: 8}
]
},{
player: 'dog',
playerPower: 'blue',
chess: [{chessName: '将', x: 10, y: 4},
{chessName: '士', x: 10, y: 3},
{chessName: '士', x: 10, y: 5},
{chessName: '象', x: 10, y: 2},
{chessName: '象', x: 10, y: 6},
{chessName: '马', x: 10, y: 1},
{chessName: '马', x: 10, y: 7},
{chessName: '车', x: 10, y: 0},
{chessName: '车', x: 10, y: 8},
{chessName: '炮', x: 8, y: 1},
{chessName: '炮', x: 8, y: 7},
{chessName: '卒', x: 7, y: 0},
{chessName: '卒', x: 7, y: 2},
{chessName: '卒', x: 7, y: 4},
{chessName: '卒', x: 7, y: 6},
{chessName: '卒', x: 7, y: 8},
]
}]
// 循环数组把棋子遍历到棋盘数组中
RedChessJson.map(item => {
item.chess.map(chessItem => {
const obj = RedChessArrays[chessItem['x']][chessItem['y']]
obj.chessName = chessItem.chessName
obj.playerPower = item.playerPower
})
})
console.log('RedChessArrays=', RedChessArrays);
// 把遍历好的棋盘赋值到vue 变量里 这块要在data声明一个RedChessArray
this.RedChessArray = RedChessArrays;
在这里棋盘就完成了 开始撸每个棋子的规则
第二步象棋每个棋子的规则
| 棋子名(chessName) | 移动规则 | 攻击规则 |
|---|---|---|
| 炮 | 炮的落下点必须在抬起点的y轴或x轴且抬起点到落下点中间不能有棋子 | 抬起点与落下点中间必须有一个棋子且落下点必须为敌方棋子 |
| 兵 | 每次落下点减去抬起点只能等于1;在河界內落下点的x轴与抬起点的x轴必须一样;y轴必须小于抬起点; | 落下点必须为敌方棋子 |
| 将 | 明天再撸 | 落下点必须为敌方棋子 |
| 士 | 明天再撸 | 落下点必须为敌方棋子 |
| 象 | 明天再撸 | 落下点必须为敌方棋子 |
| 马 | 明天再撸 | 落下点必须为敌方棋子 |
| 车 | 明天再撸 | 落下点必须为敌方棋子 |
今天就先撸一个炮的规则判断 其他明天再撸
/**
* 点击棋子
*/
clickChess(item = {act: false, chessName: '', playerPower: ''}, x = 0, y = 0) {
item.act = true;
if (!this.currentObj.chessName) {
this.currentObj = {...item};
this.currentX = x;
this.currentY = y;
console.log(this.currentX, this.currentY);
} else {
// 已经按下 判断第二次点击坐标
console.log('第二次', item)
// 算法判断通过
const isTrue = this.isTesting(x, y);
if(isTrue) {
item.act = true;
item.chessName = this.currentObj.chessName;
item.playerPower = this.currentObj.playerPower;
this.RedChessArray[this.currentX][this.currentY] = {chessName: '', playerPower: '', act: false}
// clear currentObj
this.currentObj = {act: false, chessName: "", playerPower: ""}
} else {
console.log('规格不否')
}
}
}
/**
* 检测落棋规则是否正确
* return true/false
*/
isTesting(x = 0, y = 0) {
let isTrue = true;
if (x === this.currentX && y === this.currentY) {
console.log('没用挪动棋子');
return false;
}
switch (this.currentObj.chessName) {
case '炮':
console.log('x=', x, this.currentX);
console.log('y=', y, this.currentY);
if (x !== this.currentX && y !== this.currentY) {
isTrue = false;
} else {
if (x === this.currentX) {
for (const item of this.RedChessArray) {
// console.log('item', item);
let [bigY, smallY] = [0, 0];
this.currentY > y ? (bigY = this.currentY) && (smallY = y) : (bigY = y) && (smallY = this.currentY)
console.log(smallY, bigY);
for (let i = smallY; i < bigY; i++) {
console.log('item[i]', item[i], i);
// console.log(item[i].chessName);
if (item[i].chessName != '') {
console.log('移动路上有棋子,规则不否');
isTrue = false;
}
}
}
}
}
}
break;
default:
break;
}
return isTrue;
}
码字不易,动动小手点个赞~~~
等最后开发完毕 我会将前后端代码放到GitHub上 欢迎大家star
五一放假我先撸代码着, 五一过后更新一波大的!