<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>华容道</title>
<style>
#checkerboard {
position: absolute;
top: 0;
left: 0;
width: 400px;
height: 500px;
border: 5px solid royalblue;
}
.piece {
position: absolute;
text-align: center;
color: white;
font-size: 45px;
}
.jiang {
width: 100px;
height: 200px;
line-height: 100px;
}
.zu {
width: 100px;
height: 100px;
line-height: 100px;
background-color: deeppink;
}
#caocao {
width: 200px;
height: 200px;
background-color: sandybrown;
line-height: 200px;
}
#guanyu {
width: 200px;
height: 100px;
background-color: violet;
line-height: 100px;
}
#machao {
background-color: yellow;
}
#huangzhong {
background-color: blue;
}
#zhaoyun {
background-color: chartreuse;
}
#zhangfei {
background-color: cornflowerblue;
}
</style>
</head>
<body>
<div id="checkerboard">
<div id="caocao" class="piece">曹 操</div>
<div id="guanyu" class="piece">关 羽</div>
<div id="machao" class="piece jiang">马 超</div>
<div id="huangzhong" class="piece jiang">黄 忠</div>
<div id="zhaoyun" class="piece jiang">赵 云</div>
<div id="zhangfei" class="piece jiang">张 飞</div>
<div id="zu1" class="piece zu">卒</div>
<div id="zu2" class="piece zu">卒</div>
<div id="zu3" class="piece zu">卒</div>
<div id="zu4" class="piece zu">卒</div>
</div>
<div style="position: absolute;left: 450px;top: 50px;">
<a href="javascript: void(0)" onclick="a1()">横刀立马</a>
<a href="javascript: void(0)" onclick="a2()">指挥若定</a>
<a href="javascript: void(0)" onclick="a3()">将拥曹营</a>
<a href="javascript: void(0)" onclick="a4()">齐头并进</a>
<a href="javascript: void(0)" onclick="a5()">兵分三路</a>
<a href="javascript: void(0)" onclick="a6()">雨声淅沥</a>
<a href="javascript: void(0)" onclick="a7()">左右步兵</a>
<a href="javascript: void(0)" onclick="a8()">桃花源中</a>
<a href="javascript: void(0)" onclick="a9()">小旋风</a>
<p>注意:求解时间较长请耐心等待</p>
<button onclick="start()">求最优解</button>
</div>
<script>
/* 定义变量 start */
// 保存不同棋子的ID
let mapping = ['caocao', 'guanyu', 'machao', 'huangzhong', 'zhaoyun', 'zhangfei', 'zu1', 'zu2', 'zu3', 'zu4'];
// 保存每个棋子左上角的坐标(先竖坐标后横坐标),默认 小旋风 开局
let position = [[1, 1], [0, 0], [0, 3], [2, 3], [3, 0], [3, 2], [0, 2], [3, 1], [1, 0], [2, 0]]; // 小旋风
// 保存棋盘各个方格的棋子分布状态 曹操0 关羽1 马超2 黄忠3 赵云4 张飞5 卒6789 空格-1
let checkerboard = [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]];
// 棋盘历史状态
let historyState = {};
// 最优解
let optimalSolution = null;
/* 定义变量 end */
/* 事件响应 start */
function a1() {
position = [[0, 1], [2, 1], [0, 0], [2, 0], [0, 3], [2, 3], [4, 0], [3, 1], [3, 2], [4, 3]];
renderingPiecePosition(position);
}
function a2() {
position = [[0, 1], [2, 1], [0, 0], [0, 3], [3, 0], [3, 3], [2, 0], [2, 3], [3, 1], [3, 2]];
renderingPiecePosition(position);
}
function a3() {
position = [[0, 1], [4, 0], [1, 0], [2, 1], [2, 2], [1, 3], [3, 0], [3, 3], [4, 2], [4, 3]];
renderingPiecePosition(position);
}
function a4() {
position = [[0, 1], [3, 1], [0, 0], [0, 3], [3, 0], [3, 3], [2, 0], [2, 1], [2, 2], [2, 3]];
renderingPiecePosition(position);
}
function a5() {
position = [[0, 1], [2, 1], [1, 0], [3, 0], [1, 3], [3, 3], [0, 0], [0, 3], [3, 1], [3, 2]];
renderingPiecePosition(position);
}
function a6() {
position = [[0, 1], [2, 1], [0, 0], [2, 0], [2, 3], [3, 2], [0, 3], [1, 3], [4, 0], [4, 3]];
renderingPiecePosition(position);
}
function a7() {
position = [[0, 1], [4, 1], [2, 0], [2, 1], [2, 2], [2, 3], [0, 0], [1, 0], [0, 3], [1, 3]];
renderingPiecePosition(position);
}
function a8() {
position = [[0, 1], [4, 1], [1, 0], [2, 1], [2, 2], [1, 3], [0, 0], [0, 3], [3, 0], [3, 3]];
renderingPiecePosition(position);
}
function a9() {
position = [[1, 1], [0, 0], [0, 3], [2, 3], [3, 0], [3, 2], [0, 2], [3, 1], [1, 0], [2, 0]];
renderingPiecePosition(position);
}
function start() {
createCheckerboardState();
let temp = getCompareState(checkerboard);
let o = historyState[temp[0]] = {};
o = o[temp[1]] = {};
o = o[temp[2]] = {};
o[temp[3]] = true;
setTimeout(() => {
console.time();
let value = getStateCopy(checkerboard);
let space = [];
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 4; ++j) {
if (value[i][j] == -1) {
space.push([i, j]);
}
}
}
BFS({value: value, next: [], space: space});
console.log('最优解:', optimalSolution);
console.timeEnd();
alert('点击确定自动演示最优解');
let _optimalSolution = [];
for (let i = optimalSolution.length - 1; i >= 0; --i) {
_optimalSolution.push(createPiecePosition(optimalSolution[i]));
}
let x = 0;
let js = setInterval(() => {
renderingPiecePosition(_optimalSolution[x]);
if (x == _optimalSolution.length - 1) {
clearInterval(js);
setTimeout(() => {
a9();
checkerboard = [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]];
historyState = {};
optimalSolution = null;
alert('演示完毕');
}, 1000);
}
++x;
}, 1000);
}, 10);
}
/* 事件响应 end */
a9();
/* 核心代码 start */
function renderingPiecePosition(position) { // 根据每个棋子左上角的坐标来把棋子渲染到对应的位置
for (let i = 0; i < 10; ++i) {
let e = document.getElementById(mapping[i]);
e.style.top = position[i][0] * 100 + 'px';
e.style.left = position[i][1] * 100 + 'px';
}
}
function createPiecePosition(cState) { // 根据棋盘状态生成每个棋子左上角坐标
let pos = [];
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 4; ++j) {
if (pos[cState[i][j]] == void 0) {
pos[cState[i][j]] = [i, j];
}
}
}
return pos;
}
function createCheckerboardState() { // 根据棋子左上角坐标生成棋盘状态
checkerboard[position[0][0]][position[0][1]] = 0;
checkerboard[position[0][0]][position[0][1] + 1] = 0;
checkerboard[position[0][0] + 1][position[0][1]] = 0;
checkerboard[position[0][0] + 1][position[0][1] + 1] = 0;
checkerboard[position[1][0]][position[1][1]] = 1;
checkerboard[position[1][0]][position[1][1] + 1] = 1;
checkerboard[position[2][0]][position[2][1]] = 2;
checkerboard[position[2][0] + 1][position[2][1]] = 2;
checkerboard[position[3][0]][position[3][1]] = 3;
checkerboard[position[3][0] + 1][position[3][1]] = 3;
checkerboard[position[4][0]][position[4][1]] = 4;
checkerboard[position[4][0] + 1][position[4][1]] = 4;
checkerboard[position[5][0]][position[5][1]] = 5;
checkerboard[position[5][0] + 1][position[5][1]] = 5;
checkerboard[position[6][0]][position[6][1]] = 6;
checkerboard[position[7][0]][position[7][1]] = 7;
checkerboard[position[8][0]][position[8][1]] = 8;
checkerboard[position[9][0]][position[9][1]] = 9;
}
function getStateCopy(_arr) { // 返回一个棋盘状态的复制
let arr = [[-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1], [-1, -1, -1, -1]];
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 4; ++j) {
arr[i][j] = _arr[i][j];
}
}
return arr;
}
function getCompareState(arr) { // 接收棋盘状态 返回比较状态
let _arr = [];
for (let i = 0; i < 5; ++i) {
for (let j = 0; j < 4; ++j) {
if (_arr[arr[i][j]] == void 0) {
_arr[arr[i][j]] = {
y: i,
x: j
};
}
}
}
let a1 = _arr.slice(2, 6);
let a2 = _arr.slice(6, 10);
let f1 = (a, b) => {
return a.y - b.y;
};
let f2 = (a, b) => {
return a.x - b.x;
};
a1.sort(f1);
a1.sort(f2);
a2.sort(f1);
a2.sort(f2);
let result = [];
result.push('$' + _arr[0].x + '$' + _arr[0].y);
result.push('$' + _arr[1].x + '$' + _arr[1].y);
let s = '';
for (let i = 0; i < 4; ++i) {
s = s + '$' + a1[i].x + '$' + a1[i].y;
}
result.push(s);
s = '';
for (let i = 0; i < 4; ++i) {
s = s + '$' + a2[i].x + '$' + a2[i].y;
}
result.push(s);
return result;
}
function isPush(arr) { // 是否应该加入历史记录
let o = null;
if (historyState[arr[0]]) {
o = historyState[arr[0]];
if (o[arr[1]]) {
o = o[arr[1]];
if (o[arr[2]]) {
o = o[arr[2]];
if (o[arr[3]]) {
return false;
} else {
o[arr[3]] = true;
}
} else {
o = o[arr[2]] = {};
o[arr[3]] = true;
}
} else {
o = o[arr[1]] = {};
o = o[arr[2]] = {};
o[arr[3]] = true;
}
} else {
o = historyState[arr[0]] = {};
o = o[arr[1]] = {};
o = o[arr[2]] = {};
o[arr[3]] = true;
}
return true;
}
function BFS(obj){
let x = 1;
let list = [obj],
listTemp = [];
while(list.length != 0){
for(let i = 0, len = list.length; i < len; ++i){
if (list[i].value[4][1] == 0 && list[i].value[4][2] == 0) {
let t = list[i];
let path = [];
while (t) { // 回溯
path.push(t.value);
t = t.top;
}
optimalSolution = path;
console.log('共计:' + x + '个棋盘状态');
return void 0;
} else {
listTemp = [...listTemp, ...createNext(list[i])];
}
}
list = listTemp;
x += list.length;
listTemp = [];
}
}
function createNext(o) { // 根据当前棋盘状态生成下一步所有的可能性并排除和以前重复的棋盘状态
let list = [];
let space = [];
let s1 = o.space[0];
let s2 = o.space[1];
let arr = null;
let _push = (arr) => {
let _arr = getCompareState(arr);
if (isPush(_arr)) {
if (space[0][0] > space[1][0]) {
space = [space[1], space[0]];
} else if (space[1][0] == space[0][0]) {
if (space[0][1] > space[1][1]) {
space = [space[1], space[0]];
}
} else {}
list.push({
value: arr,
top: o,
space: space
});
space = [];
}
};
if (s1[0] == s2[0] && Math.abs(s1[1] - s2[1]) == 1) { // 连续两个空格横着
if (o.value[s1[0] - 1] != void 0) { // 上面可以向下移
if (o.value[s1[0] - 1][s1[1]] == 0 && o.value[s2[0] - 1][s2[1]] == 0) { // 曹操往下移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 0;
arr[s1[0] - 2][s1[1]] = arr[s2[0] - 2][s2[1]] = -1;
space.length = 0;
space.push([s1[0] - 2, s1[1]], [s2[0] - 2, s2[1]]);
_push(arr);
} else if (o.value[s1[0] - 1][s1[1]] == 1 && o.value[s2[0] - 1][s2[1]] == 1) { // 关羽往下移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 1;
arr[s1[0] - 1][s1[1]] = arr[s2[0] - 1][s2[1]] = -1;
space.length = 0;
space.push([s1[0] - 1, s1[1]], [s2[0] - 1, s2[1]]);
_push(arr);
} else { // 小兵或者四将向下移
let f = (pos, _pos) => {
if (o.value[pos[0] - 1][pos[1]] >= 6 && o.value[pos[0] - 1][pos[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0] - 1][pos[1]];
arr[pos[0] - 1][pos[1]] = -1;
space.length = 0;
space.push([pos[0] - 1, pos[1]], _pos);
_push(arr);
} else if (o.value[pos[0] - 1][pos[1]] >= 2 && o.value[pos[0] - 1][pos[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0] - 1][pos[1]];
arr[pos[0] - 2][pos[1]] = -1;
space.length = 0;
space.push([pos[0] - 2, pos[1]], _pos);
_push(arr);
} else {}
};
f(s1, s2);
f(s2, s1);
}
}
if (o.value[s1[0] + 1] != void 0) { // 下面可以往上移
if (o.value[s1[0] + 1][s1[1]] == 0 && o.value[s2[0] + 1][s2[1]] == 0) { // 曹操往上移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 0;
arr[s1[0] + 2][s1[1]] = arr[s2[0] + 2][s2[1]] = -1;
space.length = 0;
space.push([s1[0] + 2, s1[1]], [s2[0] + 2, s2[1]]);
_push(arr);
} else if (o.value[s1[0] + 1][s1[1]] == 1 && o.value[s2[0] + 1][s2[1]] == 1) { // 关羽往上移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 1;
arr[s1[0] + 1][s1[1]] = arr[s2[0] + 1][s2[1]] = -1;
space.length = 0;
space.push([s1[0] + 1, s1[1]], [s2[0] + 1, s2[1]]);
_push(arr);
} else { // 小兵或者四将向上移
let f = (pos, _pos) => {
if (o.value[pos[0] + 1][pos[1]] >= 6 && o.value[pos[0] + 1][pos[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0] + 1][pos[1]];
arr[pos[0] + 1][pos[1]] = -1;
space.length = 0;
space.push([pos[0] + 1, pos[1]], _pos);
_push(arr);
} else if (o.value[pos[0] + 1][pos[1]] >= 2 && o.value[pos[0] + 1][pos[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0] + 1][pos[1]];
arr[pos[0] + 2][pos[1]] = -1;
space.length = 0;
space.push([pos[0] + 2, pos[1]], _pos);
_push(arr);
} else {}
};
f(s1, s2);
f(s2, s1);
}
}
if (o.value[s1[0]][s1[1] - 1] != void 0) { // 左边的可以向右移
if (o.value[s1[0]][s1[1] - 1] >= 6 && o.value[s1[0]][s1[1] - 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s1[0]][s1[1] - 1];
arr[s1[0]][s1[1] - 1] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 1], s2);
_push(arr);
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s1[0]][s1[1] - 1];
arr[s1[0]][s1[1] - 1] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 1], s1);
_push(arr);
} else if (o.value[s1[0]][s1[1] - 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = 1;
arr[s1[0]][s1[1] - 2] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 2], s2);
_push(arr);
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 1;
arr[s1[0]][s1[1] - 1] = arr[s1[0]][s1[1] - 2] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 1], [s1[0], s1[1] - 2]);
_push(arr);
} else {}
}
if (o.value[s2[0]][s2[1] + 1] != void 0) { // 右边的可以向左移
if (o.value[s2[0]][s2[1] + 1] >= 6 && o.value[s2[0]][s2[1] + 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s2[0]][s2[1] + 1];
arr[s2[0]][s2[1] + 1] = -1;
space.length = 0;
space.push([s2[0], s2[1] + 1], s1);
_push(arr);
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1] + 1];
arr[s2[0]][s2[1] + 1] = -1;
space.length = 0;
space.push([s2[0], s2[1] + 1], s2);
_push(arr);
} else if (o.value[s2[0]][s2[1] + 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = 1;
arr[s2[0]][s2[1] + 2] = -1;
space.length = 0;
space.push([s2[0], s2[1] + 2], s1);
_push(arr);
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 1;
arr[s2[0]][s2[1] + 1] = arr[s2[0]][s2[1] + 2] = -1;
space.length = 0;
space.push([s2[0], s2[1] + 1], [s2[0], s2[1] + 2]);
_push(arr);
} else {}
}
} else if (s1[1] == s2[1] && Math.abs(s1[0] - s2[0]) == 1) { // 连续两个空格竖着
if (o.value[s1[0] - 1] != void 0) { // 上面可以往下移
if (o.value[s1[0] - 1][s1[1]] >= 6 && o.value[s1[0] - 1][s1[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s1[0] - 1][s1[1]];
arr[s1[0] - 1][s1[1]] = -1;
space.length = 0;
space.push([s1[0] - 1, s1[1]], s2);
_push(arr);
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s1[0] - 1][s1[1]];
arr[s1[0] - 1][s1[1]] = -1;
space.length = 0;
space.push([s1[0] - 1, s1[1]], s1);
_push(arr);
} else if (o.value[s1[0] - 1][s1[1]] >= 2 && o.value[s1[0] - 1][s1[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s1[0] - 1][s1[1]];
arr[s1[0] - 2][s1[1]] = -1;
space.length = 0;
space.push([s1[0] - 2, s1[1]], s2);
_push(arr);
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s1[0]][s1[1]] = arr[s1[0] - 1][s1[1]];
arr[s1[0] - 1][s1[1]] = arr[s1[0] - 2][s1[1]] = -1;
space.length = 0;
space.push([s1[0] - 1, s1[1]], [s1[0] - 2, s1[1]]);
_push(arr);
} else {}
}
if (o.value[s2[0] + 1] != void 0) { // 下面可以往上移
if (o.value[s2[0] + 1][s2[1]] >= 6 && o.value[s2[0] + 1][s2[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s2[0] + 1][s2[1]];
arr[s2[0] + 1][s2[1]] = -1;
space.length = 0;
space.push([s2[0] + 1, s2[1]], s1);
_push(arr);
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0] + 1][s2[1]];
arr[s2[0] + 1][s2[1]] = -1;
space.length = 0;
space.push([s2[0] + 1, s2[1]], s2);
_push(arr);
} else if (o.value[s2[0] + 1][s2[1]] >= 2 && o.value[s2[0] + 1][s2[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s2[0] + 1][s2[1]];
arr[s2[0] + 2][s2[1]] = -1;
space.length = 0;
space.push([s2[0] + 2, s2[1]], s1);
_push(arr);
arr = getStateCopy(o.value);
arr[s2[0]][s2[1]] = arr[s1[0]][s1[1]] = arr[s2[0] + 1][s2[1]];
arr[s2[0] + 1][s2[1]] = arr[s2[0] + 2][s2[1]] = -1;
space.length = 0;
space.push([s2[0] + 1, s2[1]], [s2[0] + 2, s2[1]]);
_push(arr);
} else {}
}
if (o.value[s1[0]][s1[1] - 1] != void 0) { // 左边可以往右边移
if (o.value[s1[0]][s1[1] - 1] == 0 && o.value[s2[0]][s2[1] - 1] == 0) { // 曹操往右移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 0;
arr[s1[0]][s1[1] - 2] = arr[s2[0]][s2[1] - 2] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 2], [s2[0], s2[1] - 2]);
_push(arr);
} else if (o.value[s1[0]][s1[1] - 1] >= 2 && o.value[s2[0]][s2[1] - 1] <= 5 && o.value[s1[0]][s1[1] - 1] == o.value[s2[0]][s2[1] - 1]) { // 四将往右移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = arr[s1[0]][s1[1] - 1];
arr[s1[0]][s1[1] - 1] = arr[s2[0]][s2[1] - 1] = -1;
space.length = 0;
space.push([s1[0], s1[1] - 1], [s2[0], s2[1] - 1]);
_push(arr);
} else { // 小兵或者关羽向右移
let f = (pos, _pos) => {
if (o.value[pos[0]][pos[1] - 1] >= 6 && o.value[pos[0]][pos[1] - 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0]][pos[1] - 1];
arr[pos[0]][pos[1] - 1] = -1;
space.length = 0;
space.push([pos[0], pos[1] - 1], _pos);
_push(arr);
} else if (o.value[pos[0]][pos[1] - 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0]][pos[1] - 1];
arr[pos[0]][pos[1] - 2] = -1;
space.length = 0;
space.push([pos[0], pos[1] - 2], _pos);
_push(arr);
} else {}
};
f(s1, s2);
f(s2, s1);
}
}
if (o.value[s1[0]][s1[1] + 1] != void 0) { // 右边可以往左边移
if (o.value[s1[0]][s1[1] + 1] == 0 && o.value[s2[0]][s2[1] + 1] == 0) { // 曹操往左移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = 0;
arr[s1[0]][s1[1] + 2] = arr[s2[0]][s2[1] + 2] = -1;
space.length = 0;
space.push([s1[0], s1[1] + 2], [s2[0], s2[1] + 2]);
_push(arr);
} else if (o.value[s1[0]][s1[1] + 1] >= 2 && o.value[s2[0]][s2[1] + 1] <= 5 && o.value[s1[0]][s1[1] + 1] == o.value[s2[0]][s2[1] + 1]) { // 四将往左移
arr = getStateCopy(o.value);
arr[s1[0]][s1[1]] = arr[s2[0]][s2[1]] = arr[s1[0]][s1[1] + 1];
arr[s1[0]][s1[1] + 1] = arr[s2[0]][s2[1] + 1] = -1;
space.length = 0;
space.push([s1[0], s1[1] + 1], [s2[0], s2[1] + 1]);
_push(arr);
} else { // 小兵或者关羽向左移
let f = (pos, _pos) => {
if (o.value[pos[0]][pos[1] + 1] >= 6 && o.value[pos[0]][pos[1] + 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0]][pos[1] + 1];
arr[pos[0]][pos[1] + 1] = -1;
space.length = 0;
space.push([pos[0], pos[1] + 1], _pos);
_push(arr);
} else if (o.value[pos[0]][pos[1] + 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[pos[0]][pos[1]] = arr[pos[0]][pos[1] + 1];
arr[pos[0]][pos[1] + 2] = -1;
space.length = 0;
space.push([pos[0], pos[1] + 2], _pos);
_push(arr);
} else {}
};
f(s1, s2);
f(s2, s1);
}
}
} else { // 两个空格不相邻
let f = (s, _s) => {
if (o.value[s[0] - 1] != void 0) { // 上边的可以向下移动
if (o.value[s[0] - 1][s[1]] >= 6 && o.value[s[0] - 1][s[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0] - 1][s[1]];
arr[s[0] - 1][s[1]] = -1;
space.length = 0;
space.push([s[0] - 1, s[1]], _s);
_push(arr);
} else if (o.value[s[0] - 1][s[1]] >= 2 && o.value[s[0] - 1][s[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0] - 1][s[1]];
arr[s[0] - 2][s[1]] = -1;
space.length = 0;
space.push([s[0] - 2, s[1]], _s);
_push(arr);
} else {}
}
if (o.value[s[0] + 1] != void 0) { // 下边的可以向上移动
if (o.value[s[0] + 1][s[1]] >= 6 && o.value[s[0] + 1][s[1]] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0] + 1][s[1]];
arr[s[0] + 1][s[1]] = -1;
space.length = 0;
space.push([s[0] + 1, s[1]], _s);
_push(arr);
} else if (o.value[s[0] + 1][s[1]] >= 2 && o.value[s[0] + 1][s[1]] <= 5) { // 四将
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0] + 1][s[1]];
arr[s[0] + 2][s[1]] = -1;
space.length = 0;
space.push([s[0] + 2, s[1]], _s);
_push(arr);
} else {}
}
if (o.value[s[0]][s[1] - 1] != void 0) { // 左边的可以向右移动
if (o.value[s[0]][s[1] - 1] >= 6 && o.value[s[0]][s[1] - 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0]][s[1] - 1];
arr[s[0]][s[1] - 1] = -1;
space.length = 0;
space.push([s[0], s[1] - 1], _s);
_push(arr);
} else if (o.value[s[0]][s[1] - 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0]][s[1] - 1];
arr[s[0]][s[1] - 2] = -1;
space.length = 0;
space.push([s[0], s[1] - 2], _s);
_push(arr);
} else {}
}
if (o.value[s[0]][s[1] + 1] != void 0) { // 右边的可以向左移动
if (o.value[s[0]][s[1] + 1] >= 6 && o.value[s[0]][s[1] + 1] <= 9) { // 小兵
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0]][s[1] + 1];
arr[s[0]][s[1] + 1] = -1;
space.length = 0;
space.push([s[0], s[1] + 1], _s);
_push(arr);
} else if (o.value[s[0]][s[1] + 1] == 1) { // 关羽
arr = getStateCopy(o.value);
arr[s[0]][s[1]] = arr[s[0]][s[1] + 1];
arr[s[0]][s[1] + 2] = -1;
space.length = 0;
space.push([s[0], s[1] + 2], _s);
_push(arr);
} else {}
}
};
f(s1, s2);
f(s2, s1);
}
return list;
}
/* 核心代码 end */
</script>
</body>
</html>