private final synchronized void initInternalBook() { if (numBookMoves >= 0) return; // long t0 = System.currentTimeMillis(); bookMap = new HashMap<Long, List<BookEntry>>(); numBookMoves = 0; try { InputStream inStream = getClass().getResourceAsStream("/book.bin"); if (inStream == null) throw new IOException(); List<Byte> buf = new ArrayList<Byte>(8192); byte[] tmpBuf = new byte[1024]; while (true) { int len = inStream.read(tmpBuf); if (len <= 0) break; for (int i = 0; i < len; i++) buf.add(tmpBuf[i]); } inStream.close(); Position startPos = TextIO.readFEN(TextIO.startPosFEN); Position pos = new Position(startPos); UndoInfo ui = new UndoInfo(); int len = buf.size(); for (int i = 0; i < len; i += 2) { int b0 = buf.get(i); if (b0 < 0) b0 += 256; int b1 = buf.get(i + 1); if (b1 < 0) b1 += 256; int move = (b0 << 8) + b1; if (move == 0) { pos = new Position(startPos); } else { boolean bad = ((move >> 15) & 1) != 0; int prom = (move >> 12) & 7; Move m = new Move(move & 63, (move >> 6) & 63, promToPiece(prom, pos.whiteMove)); if (!bad) addToBook(pos, m); pos.makeMove(m, ui); } } } catch (ChessParseError ex) { throw new RuntimeException(); } catch (IOException ex) { System.out.println("Can't read opening book resource"); throw new RuntimeException(); } /* { long t1 = System.currentTimeMillis(); System.out.printf("Book moves:%d (parse time:%.3f)%n", numBookMoves, (t1 - t0) / 1000.0); } */ }
@Override protected int getYFromSq(int sq) { if (sq >= 0) { return Position.getY(sq); } else { int p = -2 - sq; if (landScape) { switch (p) { case Piece.WKING: case Piece.BKING: return 0; case Piece.WQUEEN: case Piece.BQUEEN: return 1; case Piece.WROOK: case Piece.BROOK: return 2; case Piece.WBISHOP: case Piece.BBISHOP: return 3; case Piece.WKNIGHT: case Piece.BKNIGHT: return 4; case Piece.WPAWN: case Piece.BPAWN: return 5; default: return 6; } } else { return Piece.isWhite(p) ? -1 : -2; } } }
/** Compute material difference for a position. */ public static MaterialDiff getMaterialDiff(Position pos) { StringBuilder whiteString = new StringBuilder(); StringBuilder blackString = new StringBuilder(); for (int p = Piece.WPAWN; p >= Piece.WKING; p--) { int diff = pos.nPieces(p) - pos.nPieces(Piece.swapColor(p)); while (diff < 0) { whiteString.append(Piece.toUniCode(Piece.swapColor(p))); diff++; } while (diff > 0) { blackString.append(Piece.toUniCode(p)); diff--; } } return new MaterialDiff(whiteString, blackString); }
/** Add a move to a position in the opening book. */ private final void addToBook(Position pos, Move moveToAdd) { List<BookEntry> ent = bookMap.get(pos.zobristHash()); if (ent == null) { ent = new ArrayList<BookEntry>(); bookMap.put(pos.zobristHash(), ent); } for (int i = 0; i < ent.size(); i++) { BookEntry be = ent.get(i); if (be.move.equals(moveToAdd)) { be.weight++; return; } } BookEntry be = new BookEntry(moveToAdd); ent.add(be); numBookMoves++; }
@Override protected int getSquare(int x, int y) { if ((y >= 0) && (x < 8)) { return Position.getSquare(x, y); } else { int p = extraPieces(x, y); return -p - 2; } }
@Override public List<BookEntry> getBookEntries(Position pos) { initInternalBook(); List<BookEntry> ents = bookMap.get(pos.zobristHash()); if (ents == null) return null; List<BookEntry> ret = new ArrayList<BookEntry>(); for (BookEntry be : ents) { BookEntry be2 = new BookEntry(be.move); be2.weight = Math.sqrt(be.weight) * 100 + 1; ret.add(be2); } return ret; }
@Override protected void drawExtraSquares(Canvas canvas) { int xMin = landScape ? 8 : 0; int xMax = landScape ? 10 : 8; int yMin = landScape ? 0 : -2; int yMax = landScape ? 8 : 0; for (int x = xMin; x < xMax; x++) { for (int y = yMin; y < yMax; y++) { final int xCrd = getXCrd(x); final int yCrd = getYCrd(y); Paint paint = Position.darkSquare(x, y) ? darkPaint : brightPaint; canvas.drawRect(xCrd, yCrd, xCrd + sqSize, yCrd + sqSize, paint); int p = extraPieces(x, y); drawPiece(canvas, xCrd, yCrd, p); } } }