<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{padding:0 ;margin: 0;}
html,body{width: 100%;height: 100%;}
canvas{margin: 0 auto;display: block;}
</style>
</head>
<body>
<canvas id="chess">不支持canvas</canvas>
<script src="./myChess.js" type="text/javascript" charset="utf-8"></script>
<!--<script src="js/chessPiece.js" type="text/javascript" charset="utf-8"></script>-->
<script type="text/javascript">
var chess = new Chess("chess");
</script>
</body>
</html>
class Chess{
constructor(canvasId){
this.canvas = document.getElementById(canvasId);
this.ctx = this.canvas.getContext("2d");
this.initCanvas();
this.resetData();
}
// 重置數據,再來一局
resetData(){
this.redBottom = true; // 紅方在下邊(這個屬性可以用來給不同的用戶顯示不同的棋盤)
this.toMove = {};
this.active = "red"; // 當前走棋方
this.bottomColor = "red"; // 紅方在下邊
this.chessSteps = []; // 走棋記錄
this.initChessBoard();
this.initComposition();
this.drawPieces();
}
// 切換走棋方
exchange(){
this.active = this.active == 'red' ? 'black' : 'red';
// this.reverseChess();
}
// 反轉棋局數組
reverseChess() {
this.composition = this.deepReverse(this.composition);
}
// 渲染棋盤和棋子
renderUi() {
//清除之前的畫布
this.ctx.clearRect(0, 0, this.width, this.height);
this.initChessBoard();
this.drawPieces();
}
// 輸贏判斷
getVictor() {
var flag = false;
for(let i = 0, len = this.composition.length; i < len; i++){
for(let j = 0, len1 = this.composition[i].length; j < len1; j++){
// if(){
//
// }
}
}
}
// 初始化canvas並綁定點擊事件
initCanvas(){
// var bodys = document.documentElement || document.body;
var body = document.body;
// console.log("%O",body);
var h = body.clientHeight;
var w = body.clientWidth;
if(h>w){
this.cellWidth = w / 10;
}else{
this.cellWidth = h / 11;
}
this.width = this.cellWidth * 10;
this.height = this.cellWidth * 11;
this.canvas.width = this.width;
this.canvas.height = this.height;
// 綁定點擊事件
this.canvas.addEventListener("click",(e)=>{
var offset = this.canvas.getBoundingClientRect();
var x = Math.round((e.clientX - offset.left - this.cellWidth) / this.cellWidth);
var y = Math.round((e.clientY - offset.top - this.cellWidth) / this.cellWidth);
// console.log(x, y, "點擊位置");
// 走棋
if(x>=0 && x<=8 && y<=9 && y>=0){
this.goStep(y, x);
console.log(this.chessSteps);
}else{
console.log("點在其他地方,沒在棋局中");
}
},false);
}
// 初始化棋盤
initChessBoard(){
//設置全局屬性
var padding = 2;
var borderWidth = 5;
var borderColor = "#333";
var bgColor = "#a6753a";
var lineColor = "#333";
var fontColor = bgColor;
var bgWidth = this.cellWidth - borderWidth - padding;
// 畫邊框
this.ctx.strokeStyle = bgColor;
this.ctx.lineWidth = bgWidth*2;
this.ctx.lineJoin = "miter";
this.ctx.beginPath();
this.ctx.moveTo(0,0);
this.ctx.lineTo(this.width,0);
this.ctx.lineTo(this.width,this.height);
this.ctx.lineTo(0,this.height);
this.ctx.closePath();
this.ctx.stroke();
// 畫外邊線
this.ctx.strokeStyle = borderColor;
this.ctx.lineWidth = borderWidth;
this.ctx.lineJoin = "miter";
this.ctx.beginPath();
this.ctx.moveTo(0+bgWidth,0+bgWidth);
this.ctx.lineTo(0+this.width-bgWidth,0+bgWidth);
this.ctx.lineTo(this.width-bgWidth,this.height-bgWidth);
this.ctx.lineTo(0+bgWidth,this.height-bgWidth);
this.ctx.stroke();
this.ctx.save();
this.ctx.translate(this.cellWidth,this.cellWidth);
this.ctx.beginPath();
// 畫橫線
for(let i = 0; i < 10; i++){
this.ctx.moveTo(0,this.cellWidth*i);
this.ctx.lineTo(this.cellWidth*8, this.cellWidth*i);
}
// 畫縱線
for(let i = 0; i < 9; i++){
this.ctx.moveTo(this.cellWidth*i, 0);
this.ctx.lineTo(this.cellWidth*i, this.cellWidth*4);
this.ctx.moveTo(this.cellWidth*i, this.cellWidth*5);
this.ctx.lineTo(this.cellWidth*i, this.cellWidth*9);
}
// 鏈接斷線
this.ctx.moveTo(0, this.cellWidth*4);
this.ctx.lineTo(0, this.cellWidth*5);
this.ctx.moveTo(this.cellWidth*8, this.cellWidth*4);
this.ctx.lineTo(this.cellWidth*8, this.cellWidth*5);
this.ctx.strokeStyle = lineColor;
this.ctx.lineWidth = 1;
this.ctx.stroke();
// 寫(楚河、漢界)漢字
this.ctx.font = `${this.cellWidth*0.75}px 方正舒體`; // 隸書 方正舒體
this.ctx.fillStyle = fontColor;
this.ctx.textBaseline = "middle";
this.ctx.textAlign = "center";
this.ctx.fillText("楚",this.cellWidth*1.5, this.cellWidth*4.5);
this.ctx.fillText("河",this.cellWidth*2.5, this.cellWidth*4.5);
this.ctx.fillText("漢",this.cellWidth*5.5, this.cellWidth*4.5);
this.ctx.fillText("界",this.cellWidth*6.5, this.cellWidth*4.5);
// 畫炮位
var paoArr = [{x:1,y:2},{x:7,y:2},{x:7,y:7},{x:1,y:7}];
for(let i=0, len=paoArr.length; i<len; i++){
this.markP(paoArr[i].x,paoArr[i].y);
}
// 畫兵和卒位
var bingArr = [];
for(let i=0; i<9; i+=2){
bingArr.push({x:i, y:3});
bingArr.push({x:i, y:6});
}
// 畫皇宮
this.ctx.beginPath();
this.ctx.moveTo(this.cellWidth*3, 0);
this.ctx.lineTo(this.cellWidth*5, this.cellWidth*2);
this.ctx.moveTo(this.cellWidth*5, 0);
this.ctx.lineTo(this.cellWidth*3, this.cellWidth*2);
this.ctx.moveTo(this.cellWidth*3, this.cellWidth*9);
this.ctx.lineTo(this.cellWidth*5, this.cellWidth*7);
this.ctx.moveTo(this.cellWidth*5, this.cellWidth*9);
this.ctx.lineTo(this.cellWidth*3, this.cellWidth*7);
this.ctx.stroke();
for(let i=0, len=bingArr.length; i<len; i++){
this.markP(bingArr[i].x,bingArr[i].y);
}
this.ctx.restore();
}
// 方向數字化
nd(direction){
var res = {h:0,v:0}; // h horizontal v vertical
switch(direction){
case "r":
res.h = 1;
res.v = 0;
break;
case "rd":
res.h = 1;
res.v = 1;
break;
case "d":
res.h = 0;
res.v = 1;
break;
case "ld":
res.h = -1;
res.v = 1;
break;
case "l":
res.h = -1;
res.v = 0;
break;
case "lt":
res.h = -1;
res.v = -1;
break;
case "t":
res.h = 0;
res.v = -1;
break;
case "rt":
res.h = 1;
res.v = -1;
break;
default: console.error("方向輸入有誤");
}
return res;
}
markP(x,y){ // 標出上下左右
var arr = [];
if(x === 0){
arr = ["rt","rd"];
}else if(x === 8){
arr = ["lt","ld"];
}else{
arr = ["lt","rt","rd","ld"];
}
var padding = this.cellWidth/10;
var length = this.cellWidth/5
for(let i=0;i<arr.length;i++){
this.mark(x, y, arr[i], padding, length);
}
}
// 四個標記中的一個
mark(x, y, direction, padding, length){
var d = this.nd(direction);
var h = d.h;
var v = d.v;
this.ctx.beginPath();
this.ctx.moveTo(this.cellWidth*x+h*(padding+length), this.cellWidth*y+v*padding);
this.ctx.lineTo(this.cellWidth*x+h*padding, this.cellWidth*y+v*padding);
this.ctx.lineTo(this.cellWidth*x+h*padding, this.cellWidth*y+v*(padding+length));
this.ctx.stroke();
}
// 初始化棋局
initComposition(){
var origin = [
["車","馬","象","士","將","士","象","馬","車"],
["","","","","","","","",""],
["","炮","","","","","","炮",""],
["卒","","卒","","卒","","卒","","卒"],
["","","","","","","","",""],
["","","","","","","","",""],
["兵","","兵","","兵","","兵","","兵"],
["","砲","","","","","","砲",""],
["","","","","","","","",""],
["車","馬","相","仕","帥","仕","相","馬","車"]
];
this.composition = [];
for(let i = 0, len = origin.length; i<len; i++){
this.composition[i] = [];
for(let j=0,len1=origin[i].length; j<len1; j++){
if(origin[i][j] == ""){
this.composition[i][j] = null;
}else{
if(i<=4){ // 黑方
this.composition[i][j] = {color:"black",text:origin[i][j]};
}else{ // 紅方
this.composition[i][j] = {color:"red",text:origin[i][j]};
}
}
}
}
console.log(this.composition);
}
// 畫所有的棋子
drawPieces(){
for(let i=0, len=this.composition.length; i<len; i++){
for(let j=0, len1=this.composition[i].length; j<len1; j++){
if(this.composition[i][j]){
// this.composition[i][j].drawOnePiece();
this.drawOnePiece(j,i,this.composition[i][j].text,this.composition[i][j].color)
}
}
}
}
// 畫一個棋子
drawOnePiece(x,y,text,color){
var r = this.cellWidth * 0.45;
var xx = this.cellWidth * x + this.cellWidth;
var yy = this.cellWidth * y + this.cellWidth;
var bgColor = "black";//"#eab885";
this.ctx.save();
let radgrad = this.ctx.createRadialGradient(xx,yy,r,xx,yy,r*0.8);
radgrad.addColorStop(0,"#de9555");
radgrad.addColorStop(0.75,"#de9555");
radgrad.addColorStop(1,"#eab885");
this.ctx.fillStyle = radgrad;
this.ctx.beginPath();
this.ctx.arc(xx, yy,r,0,Math.PI*2);
this.ctx.shadowOffsetX = 3;
this.ctx.shadowOffsetY = 3;
this.ctx.shadowBlur = 1;
this.ctx.shadowColor = "rgba(53,29,4,0.7)";
this.ctx.fill();
this.ctx.restore();
this.ctx.font = `${r*2*0.75}px 隸書`; // 隸書 方正舒體
this.ctx.fillStyle = color;
this.ctx.textBaseline = "middle";
this.ctx.textAlign = "center";
this.ctx.fillText(text,xx,yy);
}
// hightLight(x,y){
//
// }
goStep(x, y){
// 已經選擇了——1.換一個;(2.移動;3.吃子;)4.亂走;
// 沒有選擇——1.選一個;2.亂選;
if(Object.keys(this.toMove).length){
if(this.composition[x] && this.composition[x][y] && this.composition[x][y].color == this.active){ // 選擇我方的棋子
this.chooseToMove(x, y);
}else{// 選擇敵方的棋子
if(this.inRange(x, y)){ // 吃子
this.move(x, y);
}else{ // 亂選
console.log("還沒有輪到你走棋");
}
}
}else{
if(this.composition[x] && this.composition[x][y] && this.composition[x][y].color == this.active){ // 選擇我方的棋子
this.chooseToMove(x, y);
}
}
// 點在棋子上——選擇、吃子、亂點
// 點在空位置上——移動、亂移動
/*if(this.composition[x][y]){ // 注意,這里的x和y的順序沒有寫錯
if(this.composition[x] && this.composition[x][y].color == this.active){ // 選擇我方的棋子
this.chooseToMove(x, y);
}else{// 選擇敵方的棋子
if(this.inRange(x, y)){ // 吃子
this.move(x, y);
}else{ // 亂選
console.log("還沒有輪到你走棋");
}
}
}else{
if(this.inRange(x, y)){ // 移動到空位置
this.move(x, y);
}else{ // 亂移動
console.warn("好好走");
}
}*/
}
// 已選擇棋子是否可以移動
oneCanMove() {
if(this.moveRange.length) {
return true;
} else {
return false;
}
}
// 選擇移動的棋子
chooseToMove(x, y) {
this.renderUi();
this.getMoveRange(x, y);
this.hint();
this.toMove = {};
if(this.oneCanMove()) {
this.toMove.x = x;
this.toMove.y = y;
this.toMove.data = this.composition[x][y];
//this.highLight();
} else {
this.clearChoose();
console.warn("這個棋子不可以移動");
}
// console.log(this.toMove, "選擇后的要移動的棋子")
}
// 判斷移動的最終位置是否在移動范圍內
inRange(x, y) {
var flag = false;
for(let i = 0, len = this.moveRange.length; i < len; i++) {
if(x == this.moveRange[i].x && y == this.moveRange[i].y) {
flag = true;
break;
}
}
return flag;
}
// 是否為敵方 或 空 走棋用的判斷
isEnemyOrEmpty(x, y, color){
if(this.composition[x] && this.composition[x][y] === null){
return true;
}else{
if(this.composition[x] && this.composition[x][y] && this.composition[x][y].color != color){
return true;
}else{
return false;
}
}
}
// 顯示可以走的位置
hint(){
//console.log(this.moveRange,"移動范圍")
for(let i=0, len = this.moveRange.length; i<len; i++){
this.drawHint(this.moveRange[i].x,this.moveRange[i].y);
}
}
// 畫一個提示點
drawHint(x,y){
this.ctx.beginPath();
var cx = this.cellWidth * y + this.cellWidth;
var cy = this.cellWidth * x + this.cellWidth;
this.ctx.arc(cx, cy, this.cellWidth*0.1, 0, Math.PI*2);
this.ctx.fillStyle = "#e73480";
this.ctx.fill();
}
// 是否為空判斷
isEmpty(x, y) {
if(this.composition[x] && this.composition[x][y] === null) {
return true;
}else {
return false;
}
}
// 是否為敵判斷
isEnemy(x, y, color) {
if(this.composition[x] && this.composition[x][y] && this.composition[x][y].color != color) {
return true;
}else {
return false;
}
}
// 已選擇棋子的移動范圍 參數:棋子在棋局中的位置
getMoveRange(x,y){ //
this.moveRange = [];
var moveRange = [];
var color = this.composition[x] && this.composition[x][y].color;
var darr; // 需要判斷的移動方向
switch(this.composition[x][y].text){
case "車":
case "車":
for(let j = 1; j<y+1; j++){
if(this.isEmpty(x, y-j)){
moveRange.push({x: x, y: y-j});
}else{
if(this.isEnemy(x, y-j, color)) {
moveRange.push({x: x, y: y-j});
}
break;
}
}
for(let j = 1; j<x+1; j++){
if(this.isEmpty(x-j, y)){
moveRange.push({x: x-j, y: y});
}else{
if(this.isEnemy(x-j, y, color)) {
moveRange.push({x: x-j, y: y});
}
break;
}
}
for(let j = 1; j<9-y; j++){
if(this.isEmpty(x, y+j)){
moveRange.push({x: x, y: y+j});
}else{
if(this.isEnemy(x, y+j, color)) {
moveRange.push({x: x, y: y+j});
}
break;
}
}
for(let j = 1; j<10-x; j++){
if(this.isEmpty(x+j, y)){
moveRange.push({x: x+j, y: y});
}else{
if(this.isEnemy(x+j, y, color)) {
moveRange.push({x: x+j, y: y});
}
break;
}
}
break;
case "馬":
case "馬":
if(this.isEnemyOrEmpty(x+1, y+2, color)){
if(this.composition[x] && this.composition[x][y+1] === null){
moveRange.push({x: x+1, y: y+2});
}
}
if(this.isEnemyOrEmpty(x+1, y-2, color)){
if(this.composition[x] && this.composition[x][y-1] === null){
moveRange.push({x: x+1, y: y-2});
}
}
if(this.isEnemyOrEmpty(x+2, y+1, color)){
if(this.composition[x+1] && this.composition[x+1][y] === null){
moveRange.push({x: x+2, y: y+1});
}
}
if(this.isEnemyOrEmpty(x+2, y-1, color)){
if(this.composition[x+1] && this.composition[x+1][y] === null){
moveRange.push({x: x+2, y: y-1});
}
}
if(this.isEnemyOrEmpty(x-2, y+1, color)){
if(this.composition[x-1] && this.composition[x-1][y] === null){
moveRange.push({x: x-2, y: y+1});
}
}
if(this.isEnemyOrEmpty(x-2, y-1, color)){
if(this.composition[x-1] && this.composition[x-1][y] === null){
moveRange.push({x: x-2, y: y-1});
}
}
if(this.isEnemyOrEmpty(x-1, y+2, color)){
if(this.composition[x] && this.composition[x][y+1] === null){
moveRange.push({x: x-1, y: y+2});
}
}
if(this.isEnemyOrEmpty(x-1, y-2, color)){
if(this.composition[x] && this.composition[x][y-1] === null){
moveRange.push({x: x-1, y: y-2});
}
}
break;
case "象":
case "相":
var rowlow, rowup, collow = 0, colup = 8; // 行和列的判斷上下限
if(x > 4) { // 下方一邊
rowlow = 5;
rowup = 9;
}else { // 上方一邊
rowlow = 0;
rowup = 4;
}
if(x-2 >= rowlow && y-2 >= collow){
if(this.isEnemyOrEmpty(x-2, y-2, color)){
if(this.composition[x-1] && this.composition[x-1][y-1] === null){
moveRange.push({x: x-2, y: y-2});
}
}
}
if(x-2 >= rowlow && y+2 <= colup){
if(this.isEnemyOrEmpty(x-2, y+2, color)){
if(this.composition[x-1] && this.composition[x-1][y+1] === null){
moveRange.push({x: x-2, y: y+2});
}
}
}
if(x+2 <= rowup && y-2 >= collow){
if(this.isEnemyOrEmpty(x+2, y-2, color)){
if(this.composition[x+1] && this.composition[x+1][y-1] === null){
moveRange.push({x: x+2, y: y-2});
}
}
}
if(x+2 <= rowup && y+2 <= colup){
if(this.isEnemyOrEmpty(x+2, y+2, color)){
if(this.composition[x+1] && this.composition[x+1][y+1] === null){
moveRange.push({x: x+2, y: y+2});
}
}
}
break;
case "仕":
case "士":
var rowlow, rowup, collow = 3, colup = 5; // 行和列的判斷上下限
if(x > 4) { // 下方一邊
rowlow = 7;
rowup = 9;
}else { // 上方一邊
rowlow = 0;
rowup = 2;
}
if(this.isEnemyOrEmpty(x-1, y-1, color)){
if(x-1 >= rowlow && y-1 >= collow){
moveRange.push({x: x-1, y: y-1});
}
}
if(this.isEnemyOrEmpty(x-1, y+1, color)){
if(x-1 >= rowlow && y+1 <= colup){
moveRange.push({x: x-1, y: y+1});
}
}
if(this.isEnemyOrEmpty(x+1, y-1, color)){
if(x+1 <= rowup && y-1 >= collow){
moveRange.push({x: x+1, y: y-1});
}
}
if(this.isEnemyOrEmpty(x+1, y+1, color)){
if(x+1 <= rowup && y+1 <= colup){
moveRange.push({x: x+1, y: y+1});
}
}
break;
case "將":
case "帥":
case "帥":
var rowlow, rowup, collow = 3, colup = 5; // 行和列的判斷上下限
if(x > 4) { // 下方一邊
rowlow = 7;
rowup = 9;
}else { // 上方一邊
rowlow = 0;
rowup = 2;
}
if(this.isEnemyOrEmpty(x-1, y, color)){
if(x-1 >= rowlow){ // 老將不越上邊界
moveRange.push({x: x-1, y: y});
}
}
if(this.isEnemyOrEmpty(x+1, y, color)){
if(x+1 <= rowup){ // 老將不越下邊界
moveRange.push({x: x+1, y: y});
}
}
if(this.isEnemyOrEmpty(x, y-1, color)){
if(y-1 >= collow){ // 老將不越左邊界
moveRange.push({x: x, y: y-1});
}
}
if(this.isEnemyOrEmpty(x, y+1, color)){
if(y+1 <= colup){ // 老將不越右邊界
moveRange.push({x: x, y: y+1});
}
}
break;
case "炮":
case "砲":
var count = 0;
// 上方
count = 0;
for(let j = 1; j<y+1; j++){
if(this.composition[x][y-j] === null){
if(count === 0){
moveRange.push({x: x, y: y-j});
}
}else if(this.composition[x][y-j].color){
count++;
if(count === 2 && this.composition[x][y-j].color != color){
moveRange.push({x: x, y: y-j});
}
}
if(count >= 2){
break;
}
}
// 下
count = 0;
for(let j = 1; j<9-y; j++){
if(this.composition[x][y+j] === null){
if(count === 0){
moveRange.push({x: x, y: y+j});
}
}else if(this.composition[x][y+j].color){
count++;
if(count === 2 && this.composition[x][y+j].color != color){
moveRange.push({x: x, y: y+j});
}
}
if(count >= 2){
break;
}
}
// 左
count = 0;
for(let j = 1; j<x+1; j++){
if(this.composition[x-j][y] === null){
if(count === 0){
moveRange.push({x: x-j, y: y});
}
}else if(this.composition[x-j][y].color){
count++;
if(count === 2 && this.composition[x-j][y].color != color){
moveRange.push({x: x-j, y: y});
}
}
if(count >= 2){
break;
}
}
// 右
count = 0;
for(let j = 1; j<10-x; j++){
if(this.composition[x+j][y] === null){
if(count === 0){
moveRange.push({x: x+j, y: y});
}
}else if(this.composition[x+j][y].color){
count++;
if(count === 2 && this.composition[x+j][y].color != color){
moveRange.push({x: x+j, y: y});
}
}
if(count >= 2){
break;
}
}
break;
case "兵":
case "卒":
if(this.bottomColor == color){
if(x >= 5){// 過河前
if(this.isEnemyOrEmpty(x-1, y, color)){
moveRange.push({x: x-1, y: y});
}
}else{// 過河后
if(this.isEnemyOrEmpty(x-1, y, color)){
moveRange.push({x: x-1, y: y});
}
if(this.isEnemyOrEmpty(x, y-1, color)){
moveRange.push({x: x, y: y-1});
}
if(this.isEnemyOrEmpty(x, y+1, color)){
moveRange.push({x: x, y: y+1});
}
}
}else{
if(x <= 4){// 過河前
if(this.isEnemyOrEmpty(x+1, y, color)){
moveRange.push({x: x+1, y: y});
}
}else{// 過河后
if(this.isEnemyOrEmpty(x+1, y, color)){
moveRange.push({x: x+1, y: y});
}
if(this.isEnemyOrEmpty(x, y-1, color)){
moveRange.push({x: x, y: y-1});
}
if(this.isEnemyOrEmpty(x, y+1, color)){
moveRange.push({x: x, y: y+1});
}
}
}
break;
default: console.warn("兵種(%s)不認識",this.composition[x][y].text);
}
this.moveRange = moveRange;
return moveRange;
}
// 移動 1.選擇需要移動的棋子 2.點擊推薦的可以移動的位置 3.之前的位置賦值為空,結束的位置賦值為當前棋子
move(x, y) {
this.composition[x][y] = this.toMove.data;
this.composition[this.toMove.x][this.toMove.y] = null;
console.log("%c%s", "fontsize: 20px; color:"+ this.active +";", this.chessManual(this.toMove.x, this.toMove.y, x, y, this.toMove.data.text, this.toMove.data.color));
this.chessSteps.push({
step:this.chessManual(this.toMove.x, this.toMove.y, x, y, this.toMove.data.text, this.toMove.data.color),
qijv:this.deepClone(this.composition),
});
//console.log("移動棋子:%o",this.composition[x][y]);
this.exchange();
this.clearChoose();
this.renderUi();
}
// 清除選中的棋子
clearChoose() {
delete this.toMove.x;
delete this.toMove.y;
delete this.toMove.data;
}
// 生成棋譜 // x增大為進減小為退
chessManual(x0, y0, x1, y1, text, color) { // 馬 士 象需要特殊處理
// console.log(text, color, this.bottomColor);
var res = "";
var dx = x1 - x0;
if(color == this.bottomColor){
switch(text) {
case "車":
case "車":
case "炮":
case "砲":
case "將":
case "帥":
case "帥":
case "兵":
case "卒":
if (dx < 0) {
res = text + this.translateNum(9 - y0) + "進" + this.translateNum(-dx);
}else if (dx == 0) {
res = text + this.translateNum(9 - y0) + "平" + this.translateNum(9 - y1);
}else {
res = text + this.translateNum(9 - y0) + "退" + this.translateNum(dx);
}
break;
case "馬":
case "馬":
case "士":
case "仕":
case "象":
case "相":
if (dx < 0) {
res = text + this.translateNum(9 - y0) + "進" + this.translateNum(9 - y1);
}else {
res = text + this.translateNum(9 - y0) + "退" + this.translateNum(9 - y1);
}
break;
default: console.warn("棋子%s無法識別",text);
}
}else{
switch(text) {
case "車":
case "車":
case "炮":
case "砲":
case "將":
case "帥":
case "帥":
case "兵":
case "卒":
if (dx < 0) {
res = text + this.translateNum(y0 + 1) + "退" + this.translateNum(-dx);
}else if (dx == 0) {
res = text + this.translateNum(y0 + 1) + "平" + this.translateNum(y1 + 1);
}else {
res = text + this.translateNum(y0 + 1) + "進" + this.translateNum(dx);
}
break;
case "馬":
case "馬":
case "士":
case "仕":
case "象":
case "相":
if (dx < 0) {
res = text + this.translateNum(y0 + 1) + "退" + this.translateNum(y1 + 1);
}else {
res = text + this.translateNum(y0 + 1) + "進" + this.translateNum(y1 + 1);
}
break;
default: console.warn("棋子%s無法識別",text);
}
}
return res;
}
// 將數組轉換成漢字
translateNum(num) {
var res = "";
switch(num){
case 0: res = "零"; break;
case 1: res = "一"; break;
case 2: res = "二"; break;
case 3: res = "三"; break;
case 4: res = "四"; break;
case 5: res = "五"; break;
case 6: res = "六"; break;
case 7: res = "七"; break;
case 8: res = "八"; break;
case 9: res = "九"; break;
default: console.warn("請輸入0-9的一個整數");
}
return res;
}
// 深度反轉數組
deepReverse(arr){
if(arr instanceof Array) {
var copy = this.deepClone(arr);
var reverse = copy.reverse();
for(var i = 0, len = reverse.length; i < len; i++) {
if(reverse[i] instanceof Array){
reverse[i] = this.deepReverse(reverse[i]);
}
}
return reverse;
}
throw new Error("此函數只能反轉數組");
}
// 深拷貝
deepClone(values) {
var copy;
// Handle the 3 simple types, and null or undefined
if(null == values || "object" != typeof values) return values;
// Handle Date
if(values instanceof Date) {
copy = new Date();
copy.setTime(values.getTime());
return copy;
}
// Handle Array
if(values instanceof Array) {
copy = [];
for(var i = 0, len = values.length; i < len; i++) {
copy[i] = this.deepClone(values[i]);
}
return copy;
}
// Handle Object
if(values instanceof Object) {
copy = {};
for(var attr in values) {
if(values.hasOwnProperty(attr)) copy[attr] = this.deepClone(values[attr]);
}
return copy;
}
throw new Error("Unable to copy values! Its type isn't supported.");
}
}

