import { _decorator } from "cc"; const { ccclass } = _decorator; @ccclass("ChessPos") export default class ChessPos { clearBoard = function() { this.sdPlayer = 0; this.squares = []; //这就是一维棋局数组。 for (var sq = 0; sq < 256; sq ++) { this.squares.push(0); } this.zobristKey = this.zobristLock = 0; this.vlWhite = this.vlBlack = 0; }; mvList:any[] = [] pcList:any[] = [] keyList:any[] = [] chkList:any[] = [] squares:any[] = [] distance:number = 0 vlWhite:number = 0 vlBlack:number = 0 zobristKey:number = 0 zobristLock:number = 0 sdPlayer:number = 0 setIrrev() { this.mvList = [0]; this.pcList = [0]; this.keyList = [0]; this.chkList = [this.checked()]; this.distance = 0; } // 如果bDel为false,则将棋子pc添加进棋局中的sp位置;如果bDel为true,则删除sp位置的棋子。 private addPiece(sq, pc, bDel) { var pcAdjust; this.squares[sq] = bDel ? 0 : pc; if(pc<8){ console.log("addPiece error",pc) } if (pc < 16) { pcAdjust = pc - 8; this.vlWhite += bDel ? -PIECE_VALUE[pcAdjust][sq] : PIECE_VALUE[pcAdjust][sq]; } else { pcAdjust = pc - 16; this.vlBlack += bDel ? -PIECE_VALUE[pcAdjust][SQUARE_FLIP(sq)] : PIECE_VALUE[pcAdjust][SQUARE_FLIP(sq)]; pcAdjust += 7; } this.zobristKey ^= PreGen_zobristKeyTable[pcAdjust][sq]; this.zobristLock ^= PreGen_zobristLockTable[pcAdjust][sq]; } public pushMvList(mv){ // var sqSrc = SRC(mv); // var sqDst = DST(mv); this.mvList.push(mv); this.distance ++; } private movePiece(mv) { var sqSrc = SRC(mv); var sqDst = DST(mv); var pc = this.squares[sqDst]; this.pcList.push(pc); if (pc > 0) { this.addPiece(sqDst, pc, DEL_PIECE); } pc = this.squares[sqSrc]; if(pc==0){ console.log("pc error == ",this.squares,sqDst) }else{ this.addPiece(sqSrc, pc, DEL_PIECE); this.addPiece(sqDst, pc, ADD_PIECE); } this.mvList.push(mv); } private undoMovePiece() { var mv = this.mvList.pop(); var sqSrc = SRC(mv); var sqDst = DST(mv); var pc = this.squares[sqDst]; this.addPiece(sqDst, pc, DEL_PIECE); this.addPiece(sqSrc, pc, ADD_PIECE); pc = this.pcList.pop(); if (pc > 0) { this.addPiece(sqDst, pc, ADD_PIECE); } } public changeSide() { this.sdPlayer = 1 - this.sdPlayer; this.zobristKey ^= PreGen_zobristKeyPlayer; this.zobristLock ^= PreGen_zobristLockPlayer; } public makeMove(mv) { var zobristKey = this.zobristKey; this.movePiece(mv); // 检查走棋是否被将军。如果是,说明这是在送死,撤销走棋并返回false。 if (this.checked()) { this.undoMovePiece(); // 撤销棋子移动 return false; } this.keyList.push(zobristKey); this.changeSide(); this.chkList.push(this.checked()); this.distance ++; return true; } public undoMakeMove() { this.distance --; this.chkList.pop(); this.changeSide(); this.keyList.pop(); this.undoMovePiece(); } public nullMove() { this.mvList.push(0); this.pcList.push(0); this.keyList.push(this.zobristKey); this.changeSide(); this.chkList.push(false); this.distance ++; } public undoNullMove() { this.distance --; this.chkList.pop(); this.changeSide(); this.keyList.pop(); this.pcList.pop(); this.mvList.pop(); } //通过FEN串初始化棋局,也就是将参数fen表示的棋局,转化为一维棋局数组squares表示的棋局。 public fromFen(fen) { this.clearBoard(); var y = RANK_TOP; var x = FILE_LEFT; var index = 0; if (index == fen.length) { this.setIrrev(); return; } var c = fen.charAt(index); while (c != " ") { if (c == "/") { x = FILE_LEFT; y ++; if (y > RANK_BOTTOM) { break; } } else if (c >= "1" && c <= "9") { x += (ASC(c) - ASC("0")); } else if (c >= "A" && c <= "Z") { if (x <= FILE_RIGHT) { var pt = CHAR_TO_PIECE(c); if (pt >= 0) { this.addPiece(COORD_XY(x, y), pt + 8,null); } x ++; } } else if (c >= "a" && c <= "z") { if (x <= FILE_RIGHT) { var pt = CHAR_TO_PIECE(CHR(ASC(c) + ASC("A") - ASC("a"))); if (pt >= 0) { this.addPiece(COORD_XY(x, y), pt + 16,null); } x ++; } } index ++; if (index == fen.length) { this.setIrrev(); return; } c = fen.charAt(index); } index ++; if (index == fen.length) { this.setIrrev(); return; } if (this.sdPlayer == (fen.charAt(index) == "b" ? 0 : 1)) { this.changeSide(); } this.setIrrev(); } public toFen() { var fen = ""; for (var y = RANK_TOP; y <= RANK_BOTTOM; y ++) { var k = 0; for (var x = FILE_LEFT; x <= FILE_RIGHT; x ++) { var pc = this.squares[COORD_XY(x, y)]; if (pc > 0) { if (k > 0) { fen += CHR(ASC("0") + k); k = 0; } fen += FEN_PIECE.charAt(pc); } else { k ++; } } if (k > 0) { fen += CHR(ASC("0") + k); } fen += "/"; } return fen.substring(0, fen.length - 1) + (this.sdPlayer == 0 ? " w" : " b"); } public generateMoves(vls) { var mvs = []; var pcSelfSide = SIDE_TAG(this.sdPlayer); var pcOppSide = OPP_SIDE_TAG(this.sdPlayer); for (var sqSrc = 0; sqSrc < 256; sqSrc ++) { var pcSrc = this.squares[sqSrc]; if ((pcSrc & pcSelfSide) == 0) { continue; } switch (pcSrc - pcSelfSide) { case PIECE_KING: for (var i = 0; i < 4; i ++) { var sqDst = sqSrc + KING_DELTA[i]; if (!IN_FORT(sqDst)) { continue; } var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 5)); } } break; case PIECE_ADVISOR: for (var i = 0; i < 4; i ++) { var sqDst = sqSrc + ADVISOR_DELTA[i]; if (!IN_FORT(sqDst)) { continue; } var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 1)); } } break; case PIECE_BISHOP: for (var i = 0; i < 4; i ++) { var sqDst = sqSrc + ADVISOR_DELTA[i]; if (!(IN_BOARD(sqDst) && HOME_HALF(sqDst, this.sdPlayer) && this.squares[sqDst] == 0)) { continue; } sqDst += ADVISOR_DELTA[i]; var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 1)); } } break; case PIECE_KNIGHT: for (var i = 0; i < 4; i ++) { var sqDst = sqSrc + KING_DELTA[i]; if (this.squares[sqDst] > 0) { continue; } for (var j = 0; j < 2; j ++) { sqDst = sqSrc + KNIGHT_DELTA[i][j]; if (!IN_BOARD(sqDst)) { continue; } var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 1)); } } } break; case PIECE_ROOK: for (var i = 0; i < 4; i ++) { var delta = KING_DELTA[i]; var sqDst = sqSrc + delta; while (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (pcDst == 0) { if (vls == null) { mvs.push(MOVE(sqSrc, sqDst)); } } else { if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); if (vls != null) { vls.push(MVV_LVA(pcDst, 4)); } } break; } sqDst += delta; } } break; case PIECE_CANNON: for (var i = 0; i < 4; i ++) { var delta = KING_DELTA[i]; var sqDst = sqSrc + delta; while (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (pcDst == 0) { if (vls == null) { mvs.push(MOVE(sqSrc, sqDst)); } } else { break; } sqDst += delta; } sqDst += delta; while (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (pcDst > 0) { if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); if (vls != null) { vls.push(MVV_LVA(pcDst, 4)); } } break; } sqDst += delta; } } break; case PIECE_PAWN: var sqDst = SQUARE_FORWARD(sqSrc, this.sdPlayer); if (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 2)); } } if (AWAY_HALF(sqSrc, this.sdPlayer)) { for (var delta = -1; delta <= 1; delta += 2) { sqDst = sqSrc + delta; if (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (vls == null) { if ((pcDst & pcSelfSide) == 0) { mvs.push(MOVE(sqSrc, sqDst)); } } else if ((pcDst & pcOppSide) != 0) { mvs.push(MOVE(sqSrc, sqDst)); vls.push(MVV_LVA(pcDst, 2)); } } } } break; } } return mvs; } public findAllCanMove(sq){ var sqSrc = sq; var pcSrc = this.squares[sqSrc]; var temp_array = []; var pcSelfSide = SIDE_TAG(this.sdPlayer); var pcOppSide = OPP_SIDE_TAG(this.sdPlayer); if ((pcSrc & pcSelfSide) == 0) { return temp_array; } switch (pcSrc - pcSelfSide) { case PIECE_KING: //寻找当前将所有可以走的路 { var des_array = [] des_array.push(sqSrc - 16) des_array.push(sqSrc - 1) des_array.push(sqSrc + 16) des_array.push(sqSrc + 1) for(var i=0;i 0) { if (pcDst == pcOppSide + PIECE_ROOK || pcDst == pcOppSide + PIECE_KING) { return true; } break; } sqDst += delta; } sqDst += delta; while (IN_BOARD(sqDst)) { var pcDst = this.squares[sqDst]; if (pcDst > 0) { if (pcDst == pcOppSide + PIECE_CANNON) { return true; } break; } sqDst += delta; } } return false; } return false; } isMate() { var mvs = this.generateMoves(null); for (var i = 0; i < mvs.length; i ++) { if (this.makeMove(mvs[i])) { this.undoMakeMove(); return false; } } return true; } mateValue() { return this.distance - MATE_VALUE; } banValue() { return this.distance - BAN_VALUE; } drawValue() { return (this.distance & 1) == 0 ? -DRAW_VALUE : DRAW_VALUE; } evaluate() { var vl = (this.sdPlayer == 0 ? this.vlWhite - this.vlBlack : this.vlBlack - this.vlWhite) + ADVANCED_VALUE; return vl == this.drawValue() ? vl - 1 : vl; } nullOkay() { return (this.sdPlayer == 0 ? this.vlWhite : this.vlBlack) > NULL_OKAY_MARGIN; } nullSafe() { return (this.sdPlayer == 0 ? this.vlWhite : this.vlBlack) > NULL_SAFE_MARGIN; } inCheck() { return this.chkList[this.chkList.length - 1]; } captured() { return this.pcList[this.pcList.length - 1] > 0; } repValue(vlRep) { var vlReturn = ((vlRep & 2) == 0 ? 0 : this.banValue()) + ((vlRep & 4) == 0 ? 0 : -this.banValue()); return vlReturn == 0 ? this.drawValue() : vlReturn; } repStatus(recur_) { var recur = recur_; var selfSide = false; var perpCheck = true; var oppPerpCheck = true; var index = this.mvList.length - 1; while (this.mvList[index] > 0 && this.pcList[index] == 0) { if (selfSide) { perpCheck = perpCheck && this.chkList[index]; if (this.keyList[index] == this.zobristKey) { recur --; if (recur == 0) { return 1 + (perpCheck ? 2 : 0) + (oppPerpCheck ? 4 : 0); } } } else { oppPerpCheck = oppPerpCheck && this.chkList[index]; } selfSide = !selfSide; index --; } return 0; } mirror() { var pos = new ChessPos(); pos.clearBoard(); for (var sq = 0; sq < 256; sq ++) { var pc = this.squares[sq]; if (pc > 0) { pos.addPiece(MIRROR_SQUARE(sq), pc,null); } } if (this.sdPlayer == 1) { pos.changeSide(); } return pos; } bookMove() { return 0; // if (typeof BOOK_DAT != "object" || BOOK_DAT.length == 0) { // return 0; // } // var mirror = false; // var lock = this.zobristLock >>> 1; // Convert into Unsigned // var index = binarySearch(BOOK_DAT, lock); // if (index < 0) { // mirror = true; // lock = this.mirror().zobristLock >>> 1; // Convert into Unsigned // index = binarySearch(BOOK_DAT, lock); // } // if (index < 0) { // return 0; // } // index --; // while (index >= 0 && BOOK_DAT[index][0] == lock) { // index --; // } // var mvs = [], vls = []; // var value = 0; // index ++; // while (index < BOOK_DAT.length && BOOK_DAT[index][0] == lock) { // var mv = BOOK_DAT[index][1]; // mv = (mirror ? MIRROR_MOVE(mv) : mv); // if (this.legalMove(mv)) { // mvs.push(mv); // var vl = BOOK_DAT[index][2]; // vls.push(vl); // value += vl; // } // index ++; // } // if (value == 0) { // return 0; // } // value = Math.floor(Math.random() * value); // for (index = 0; index < mvs.length; index ++) { // value -= vls[index]; // if (value < 0) { // break; // } // } // return mvs[index]; } historyIndex(mv) { return ((this.squares[SRC(mv)] - 8) << 8) + DST(mv); } } function binarySearch(vlss, vl) { var low = 0; var high = vlss.length - 1; while (low <= high) { var mid = (low + high) >> 1; if (vlss[mid][0] < vl) { low = mid + 1; } else if (vlss[mid][0] > vl) { high = mid - 1; } else { return mid; } } return -1; } var MATE_VALUE = 10000; var BAN_VALUE = MATE_VALUE - 100; var WIN_VALUE = MATE_VALUE - 200; var NULL_SAFE_MARGIN = 400; var NULL_OKAY_MARGIN = 200; var DRAW_VALUE = 20; var ADVANCED_VALUE = 3; /** !#en This is a KING. !#zh 这是一个 將 */ var PIECE_KING = 0; /** !#en This is a ADVISOR. !#zh 这是一个 士 */ var PIECE_ADVISOR = 1; /** !#en This is a BISHOP. !#zh 这是一个 象 */ var PIECE_BISHOP = 2; /** !#en This is a KNIGHT. !#zh 这是一个 馬 */ var PIECE_KNIGHT = 3; /** !#en This is a ROOK. !#zh 这是一个 车 */ var PIECE_ROOK = 4;// 车 /** !#en This is a CANNON. !#zh 这是一个 炮 */ var PIECE_CANNON = 5; /** !#en This is a PAWN. !#zh 这是一个 卒 */ var PIECE_PAWN = 6; var RANK_TOP = 3; var RANK_BOTTOM = 12; var FILE_LEFT = 3; var FILE_RIGHT = 11; var ADD_PIECE = false; var DEL_PIECE = true; /** !#en This is a init board 16*16 size. !#zh 这是一个初始棋盤的大小 在程序中,棋局被表示为大小为256的一维数组,一半棋盘位于0到127,另一半位于128到255。 128的二进制是1000 0000,右起第八位是1。128到255这些数的二进制,右起第8位都是1;0到127这些数的二进制,右起第8位都是0。 */ var IN_BOARD_ = [ /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //15 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //47 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* 127 */ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,/* 255 */ ]; var IN_FORT_ = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; var LEGAL_SPAN = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; var KNIGHT_PIN_ = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-16, 0,-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; var KING_DELTA = [-16, -1, 1, 16]; var ADVISOR_DELTA = [-17, -15, 15, 17]; var KNIGHT_DELTA = [[-33, -31], [-18, 14], [-14, 18], [31, 33]]; var KNIGHT_CHECK_DELTA = [[-33, -18], [-31, -14], [14, 31], [18, 33]]; var MVV_VALUE = [50, 10, 10, 30, 40, 30, 20, 0]; var PIECE_VALUE = [ [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 11, 13, 11, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 19, 24, 34, 42, 44, 42, 34, 24, 19, 0, 0, 0, 0, 0, 0, 0, 19, 24, 32, 37, 37, 37, 32, 24, 19, 0, 0, 0, 0, 0, 0, 0, 19, 23, 27, 29, 30, 29, 27, 23, 19, 0, 0, 0, 0, 0, 0, 0, 14, 18, 20, 27, 29, 27, 20, 18, 14, 0, 0, 0, 0, 0, 0, 0, 7, 0, 13, 0, 16, 0, 13, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 15, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 15, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 20, 23, 20, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 0, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 20, 23, 20, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 0, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 90, 90, 96, 90, 96, 90, 90, 90, 0, 0, 0, 0, 0, 0, 0, 90, 96,103, 97, 94, 97,103, 96, 90, 0, 0, 0, 0, 0, 0, 0, 92, 98, 99,103, 99,103, 99, 98, 92, 0, 0, 0, 0, 0, 0, 0, 93,108,100,107,100,107,100,108, 93, 0, 0, 0, 0, 0, 0, 0, 90,100, 99,103,104,103, 99,100, 90, 0, 0, 0, 0, 0, 0, 0, 90, 98,101,102,103,102,101, 98, 90, 0, 0, 0, 0, 0, 0, 0, 92, 94, 98, 95, 98, 95, 98, 94, 92, 0, 0, 0, 0, 0, 0, 0, 93, 92, 94, 95, 92, 95, 94, 92, 93, 0, 0, 0, 0, 0, 0, 0, 85, 90, 92, 93, 78, 93, 92, 90, 85, 0, 0, 0, 0, 0, 0, 0, 88, 85, 90, 88, 90, 88, 90, 85, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,206,208,207,213,214,213,207,208,206, 0, 0, 0, 0, 0, 0, 0,206,212,209,216,233,216,209,212,206, 0, 0, 0, 0, 0, 0, 0,206,208,207,214,216,214,207,208,206, 0, 0, 0, 0, 0, 0, 0,206,213,213,216,216,216,213,213,206, 0, 0, 0, 0, 0, 0, 0,208,211,211,214,215,214,211,211,208, 0, 0, 0, 0, 0, 0, 0,208,212,212,214,215,214,212,212,208, 0, 0, 0, 0, 0, 0, 0,204,209,204,212,214,212,204,209,204, 0, 0, 0, 0, 0, 0, 0,198,208,204,212,212,212,204,208,198, 0, 0, 0, 0, 0, 0, 0,200,208,206,212,200,212,206,208,200, 0, 0, 0, 0, 0, 0, 0,194,206,204,212,200,212,204,206,194, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,100,100, 96, 91, 90, 91, 96,100,100, 0, 0, 0, 0, 0, 0, 0, 98, 98, 96, 92, 89, 92, 96, 98, 98, 0, 0, 0, 0, 0, 0, 0, 97, 97, 96, 91, 92, 91, 96, 97, 97, 0, 0, 0, 0, 0, 0, 0, 96, 99, 99, 98,100, 98, 99, 99, 96, 0, 0, 0, 0, 0, 0, 0, 96, 96, 96, 96,100, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 95, 96, 99, 96,100, 96, 99, 96, 95, 0, 0, 0, 0, 0, 0, 0, 96, 96, 96, 96, 96, 96, 96, 96, 96, 0, 0, 0, 0, 0, 0, 0, 97, 96,100, 99,101, 99,100, 96, 97, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 98, 98, 98, 98, 97, 96, 0, 0, 0, 0, 0, 0, 0, 96, 96, 97, 99, 99, 99, 97, 96, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 11, 13, 11, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 19, 24, 34, 42, 44, 42, 34, 24, 19, 0, 0, 0, 0, 0, 0, 0, 19, 24, 32, 37, 37, 37, 32, 24, 19, 0, 0, 0, 0, 0, 0, 0, 19, 23, 27, 29, 30, 29, 27, 23, 19, 0, 0, 0, 0, 0, 0, 0, 14, 18, 20, 27, 29, 27, 20, 18, 14, 0, 0, 0, 0, 0, 0, 0, 7, 0, 13, 0, 16, 0, 13, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 15, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 15, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], ]; function IN_BOARD(sq) { return IN_BOARD_[sq] != 0; } function IN_FORT(sq) { return IN_FORT_[sq] != 0; } function RANK_Y(sq) { return sq >> 4; } function FILE_X(sq) { return sq & 15; } // 将二维矩阵转换为一维矩阵 function COORD_XY(x, y) { return x + (y << 4); } function SQUARE_FLIP(sq) { return 254 - sq; } function FILE_FLIP(x) { return 14 - x; } function RANK_FLIP(y) { return 15 - y; } function MIRROR_SQUARE(sq) { return COORD_XY(FILE_FLIP(FILE_X(sq)), RANK_Y(sq)); } function SQUARE_FORWARD(sq, sd) { return sq - 16 + (sd << 5); } function KING_SPAN(sqSrc, sqDst) { return LEGAL_SPAN[sqDst - sqSrc + 256] == 1; } function ADVISOR_SPAN(sqSrc, sqDst) { return LEGAL_SPAN[sqDst - sqSrc + 256] == 2; } function BISHOP_SPAN(sqSrc, sqDst) { return LEGAL_SPAN[sqDst - sqSrc + 256] == 3; } function BISHOP_PIN(sqSrc, sqDst) { return (sqSrc + sqDst) >> 1; } function KNIGHT_PIN(sqSrc, sqDst) { return sqSrc + KNIGHT_PIN_[sqDst - sqSrc + 256]; } function HOME_HALF(sq, sd) { return (sq & 0x80) != (sd << 7); } function AWAY_HALF(sq, sd) { return (sq & 0x80) == (sd << 7); } // 如果从起点sqSrc到终点sqDst没有过河,则返回true;否则返回false function SAME_HALF(sqSrc, sqDst) { return ((sqSrc ^ sqDst) & 0x80) == 0; } function SAME_RANK(sqSrc, sqDst) { return ((sqSrc ^ sqDst) & 0xf0) == 0; } function SAME_FILE(sqSrc, sqDst) { return ((sqSrc ^ sqDst) & 0x0f) == 0; } function SIDE_TAG(sd) { return 8 + (sd << 3); } function OPP_SIDE_TAG(sd) { return 16 - (sd << 3); } function SRC(mv) { return mv & 255; } function DST(mv) { return mv >> 8; } function MOVE(sqSrc, sqDst) { return sqSrc + (sqDst << 8); } function MIRROR_MOVE(mv) { return MOVE(MIRROR_SQUARE(SRC(mv)), MIRROR_SQUARE(DST(mv))); } function MVV_LVA(pc, lva) { return MVV_VALUE[pc & 7] - lva; } function CHR(n) { return String.fromCharCode(n); } function ASC(c) { return c.charCodeAt(0); } var FEN_PIECE = " KABNRCP kabnrcp "; function CHAR_TO_PIECE(c) { switch (c) { case "K": return PIECE_KING; // 将 case "A": return PIECE_ADVISOR; // 士 case "B": case "E": return PIECE_BISHOP; // 象 case "H": case "N": return PIECE_KNIGHT; // 马 case "R": return PIECE_ROOK; // 车 case "C": return PIECE_CANNON; // 炮 case "P": return PIECE_PAWN; //卒 default: return -1; } } function RC4(key) { this.x = this.y = 0; this.state = []; for (var i = 0; i < 256; i ++) { this.state.push(i); } var j = 0; for (var i = 0; i < 256; i ++) { j = (j + this.state[i] + key[i % key.length]) & 0xff; this.swap(i, j); } } RC4.prototype.swap = function(i, j) { var t = this.state[i]; this.state[i] = this.state[j]; this.state[j] = t; } RC4.prototype.nextByte = function() { this.x = (this.x + 1) & 0xff; this.y = (this.y + this.state[this.x]) & 0xff; this.swap(this.x, this.y); var t = (this.state[this.x] + this.state[this.y]) & 0xff; return this.state[t]; } RC4.prototype.nextLong = function() { var n0 = this.nextByte(); var n1 = this.nextByte(); var n2 = this.nextByte(); var n3 = this.nextByte(); return n0 + (n1 << 8) + (n2 << 16) + ((n3 << 24) & 0xffffffff); } var PreGen_zobristKeyPlayer, PreGen_zobristLockPlayer; var PreGen_zobristKeyTable = [], PreGen_zobristLockTable = []; var rc4 = new RC4([0]); PreGen_zobristKeyPlayer = rc4.nextLong(); rc4.nextLong(); PreGen_zobristLockPlayer = rc4.nextLong(); for (var i = 0; i < 14; i ++) { var keys = []; var locks = []; for (var j = 0; j < 256; j ++) { keys.push(rc4.nextLong()); rc4.nextLong(); locks.push(rc4.nextLong()); } PreGen_zobristKeyTable.push(keys); PreGen_zobristLockTable.push(locks); } // function Position() { // // sdPlayer, zobristKey, zobristLock, vlWhite, vlBlack, distance; // // squares, mvList, pcList, keyList, chkList; // } //module.exports = Position;