public int searchTree(final int levelsToTop, int alpha, final int beta) { if (board.isDraw()) { return scorer.drawValue(); } if (levelsToTop == iterativeDepth) { return scorer.staticScore(board); } final MoveContainer moves = moveContainers[levelsToTop]; final BoardHashEntry hashEntry = hashTable.get(board.getHashCode()); prioritizeHashEntry(hashEntry, moves); board.makeNullMove(); board.generateValidMoves(moves); if (moves.isEmpty()) { return scorer.endOfGameValue(board.isInCheck(), levelsToTop); } for (int m = 0; m < moves.size(); m++) { final Move move = moves.get(m); board.makeMove(move); final int childScore = -searchTree(levelsToTop + 1, -beta, -alpha); board.undoMove(); if (childScore > alpha) { // narrowing alpha beta window alpha = childScore; movePath.markMove(levelsToTop, iterativeDepth, m); if (alpha >= beta) { // pruned! break; } } } unprioritizeHashEntry(hashEntry, moves); hashTable.set( board.getHashCode(), alpha, 0, movePath.getRaw(levelsToTop), board.getMoveNumber(), BoardHashEntry.ValueBounds.PV); return alpha; }
@Override public MovePath search( final Board board, final int depth, final int startAlpha, final int startBeta) { this.iterativeDepth = depth; this.board = board; final int score = searchTree(0, startAlpha, startBeta); movePath.setScore(score); movePath.setDepth(iterativeDepth); EngineUtil.verifyPV(movePath, board, hashTable); return movePath; }
@Override public Field move( Moveable moveable, SetterOfPosition setterOfPosition, MovePath movePath, ResourceHolder resourceHolder) throws FieldsNotConnectedException, MoveNotPossibleException, NotEnoughResourceException { if (canMove(moveable, movePath, resourceHolder)) { resourceHolder.pay(movePath.cost().asPayment()); setterOfPosition.setPosition(movePath.getTarget()); return movePath.getTarget(); } else if (!resourceHolder.canPay(movePath.cost().asPayment())) { throw new NotEnoughResourceException( resourceHolder.get(MovePoint.class), movePath.cost().getAmount()); } else { throw new MoveNotPossibleException(); } }
@Override public MovePath iterativeSearch( final Board board, final int maxLevel, final int startAlpha, final int startBeta) { this.board = board; for (int i = 1; i <= maxLevel; i++) { search(board, i); if (movePath.getEndBoardCondition() == BoardCondition.CHECKMATE) { break; } } return movePath; }
@Override public boolean canMove(Moveable moveable, MovePath movePath, ResourceHolder resourceHolder) { if (moveable == null || movePath == null || resourceHolder == null) { return false; } Moveable testMoveable = moveable.cloneMoveable(); ResourceHolder testResourceHolder = resourceHolder.cloneResourceHolder(); boolean canMove = true; for (Field field : movePath.getPathFields()) { try { testMoveable.move(field, testResourceHolder); } catch (Exception e) { canMove = false; break; } } return canMove; }