def offencive_moves_rook(model, ply, phase): move = model.getMoveAtPly(ply - 1).move tcord = TCORD(move) board = model.getBoardAtPly(ply).board color = 1 - board.color opcolor = 1 - color # We also detect rook-to-open castlings if board.arBoard[tcord] == KING: if FLAG(move) == QUEEN_CASTLE: tcord = tcord + 1 elif FLAG(move) == KING_CASTLE: tcord = tcord - 1 if board.arBoard[tcord] != ROOK: return color = 1 - board.color opcolor = 1 - color pawns = board.boards[color][PAWN] oppawns = board.boards[opcolor][PAWN] ffile = fileBits[FILE(FCORD(move))] tfile = fileBits[FILE(tcord)] if ffile & pawns and not tfile & pawns and bin(pawns).count("1") >= 3: if not tfile & oppawns: yield _("moves a rook to an open file") else: yield _("moves an rook to a half-open file")
def state_destroysCastling(model, ply, phase): """ Does the move destroy the castling ability of the opponent """ # If the move is a castling, nobody will every care if the castling # possibilities has changed if FLAG(model.getMoveAtPly(ply - 1).move) in (QUEEN_CASTLE, KING_CASTLE): return oldcastling = model.getBoardAtPly(ply - 1).board.castling castling = model.getBoardAtPly(ply).board.castling if oldcastling & W_OOO and not castling & W_OOO: if oldcastling & W_OO and not castling & W_OO: yield 900 / phase, _("%s can no longer castle") % reprColor[WHITE] else: yield 400 / phase, _( "%s can no longer castle in queenside") % reprColor[WHITE] elif oldcastling & W_OO and not castling & W_OO: yield 500 / phase, _( "%s can no longer castle in kingside") % reprColor[WHITE] if oldcastling & B_OOO and not castling & B_OOO: if oldcastling & B_OO and not castling & B_OO: yield 900 / phase, _("%s can no longer castle") % reprColor[BLACK] else: yield 400 / phase, _( "%s can no longer castle in queenside") % reprColor[BLACK] elif oldcastling & B_OO and not castling & B_OO: yield 500 / phase, _( "%s can no longer castle in kingside") % reprColor[BLACK]
def attack_type(model, ply, phase): # We set bishop value down to knight value, as it is what most people expect bishopBackup = PIECE_VALUES[BISHOP] PIECE_VALUES[BISHOP] = PIECE_VALUES[KNIGHT] board = model.getBoardAtPly(ply).board oldboard = model.getBoardAtPly(ply - 1).board if ply - model.lowply >= 2: oldmove = model.getMoveAtPly(ply - 2).move oldboard3 = model.getBoardAtPly(ply - 2).board else: oldmove = None move = model.getMoveAtPly(ply - 1).move tcord = TCORD(move) if oldboard.arBoard[tcord] != EMPTY: if not (board.variant == FISCHERRANDOMCHESS and \ FLAG(move) in (KING_CASTLE, QUEEN_CASTLE)): if oldmove and oldboard3.arBoard[TCORD(oldmove)] != EMPTY and \ TCORD(oldmove) == tcord: yield _("takes back material") else: see = staticExchangeEvaluate(oldboard, move) if see < 0: yield _("sacrifies material") elif see == 0: yield _("exchanges material") elif see > 0: yield _("captures material") PIECE_VALUES[BISHOP] = bishopBackup
def move (self, move): assert self[move.cord0], "%s %s" % (move, self.asFen()) newBoard = self.clone() newBoard.board.applyMove (move.move) cord0, cord1 = move.cords flag = FLAG(move.move) # in frc there are unusual castling positions where # king will move on top of the castling rook, so... if flag in (KING_CASTLE, QUEEN_CASTLE): # don't put on the castling king yet king = newBoard[cord0] else: newBoard[cord1] = newBoard[cord0] newBoard[cord0] = None # move castling rook if self.color == WHITE: if flag == QUEEN_CASTLE: if self.board.ini_rooks[0][0] != D1: newBoard[Cord(D1)] = newBoard[Cord(self.board.ini_rooks[0][0])] newBoard[Cord(self.board.ini_rooks[0][0])] = None elif flag == KING_CASTLE: if self.board.ini_rooks[0][1] != F1: newBoard[Cord(F1)] = newBoard[Cord(self.board.ini_rooks[0][1])] newBoard[Cord(self.board.ini_rooks[0][1])] = None else: if flag == QUEEN_CASTLE: if self.board.ini_rooks[1][0] != D8: newBoard[Cord(D8)] = newBoard[Cord(self.board.ini_rooks[1][0])] newBoard[Cord(self.board.ini_rooks[1][0])] = None elif flag == KING_CASTLE: if self.board.ini_rooks[1][1] != F8: newBoard[Cord(F8)] = newBoard[Cord(self.board.ini_rooks[1][1])] newBoard[Cord(self.board.ini_rooks[1][1])] = None # put the castling king now if flag in (KING_CASTLE, QUEEN_CASTLE): if self.color == WHITE: if flag == QUEEN_CASTLE: newBoard[Cord(C1)] = king elif flag == KING_CASTLE: newBoard[Cord(G1)] = king else: if flag == QUEEN_CASTLE: newBoard[Cord(C8)] = king elif flag == KING_CASTLE: newBoard[Cord(G8)] = king if flag in PROMOTIONS: newBoard[cord1] = Piece(self.color, PROMOTE_PIECE(flag)) elif flag == ENPASSANT: newBoard[Cord(cord1.x, cord0.y)] = None return newBoard
def prefix_type(model, ply, phase): flag = FLAG(model.getMoveAtPly(ply - 1).move) if flag in PROMOTIONS: yield _("promotes a Pawn to a %s") % reprPiece[PROMOTE_PIECE(flag)] elif flag in (KING_CASTLE, QUEEN_CASTLE): yield _("castles")
def defencive_moves_tactic(model, ply, phase): # ------------------------------------------------------------------------ # # Test if we threat something, or at least put more pressure on it # # ------------------------------------------------------------------------ # # We set bishop value down to knight value, as it is what most people expect bishopBackup = PIECE_VALUES[BISHOP] PIECE_VALUES[BISHOP] = PIECE_VALUES[KNIGHT] board = model.getBoardAtPly(ply).board oldboard = model.getBoardAtPly(ply - 1).board move = model.getMoveAtPly(ply - 1).move fcord = FCORD(move) tcord = TCORD(move) found_threatens = [] found_increases = [] # What do we attack now? board.setColor(1 - board.color) for ncap in genCaptures(board): # getCaptures also generate promotions if FLAG(ncap) in PROMOTIONS: continue # We are only interested in the attacks of the piece we just moved if FCORD(ncap) != TCORD(move): continue # We don't want to move back if TCORD(ncap) == FCORD(move): continue # We don't thread the king. We check him! (in another function) if board.arBoard[TCORD(ncap)] == KING: continue # If we also was able to attack that cord last time, we don't care if validateMove(oldboard, newMove(FCORD(move), TCORD(ncap))): continue # Test if we threats our enemy, at least more than before see0 = staticExchangeEvaluate(oldboard, TCORD(ncap), 1 - oldboard.color) see1 = staticExchangeEvaluate(board, TCORD(ncap), 1 - oldboard.color) if see1 > see0: # If a new winning capture has been created if see1 > 0: # Find the easiest attack attacks = getAttacks(board, TCORD(ncap), board.color) v, cord = min((PIECE_VALUES[board.arBoard[fc]], fc) for fc in iterBits(attacks)) easiestAttack = newMove(cord, TCORD(ncap)) found_threatens.append(toSAN(board, easiestAttack, True)) # Even though we might not yet be strong enough, we might still # have strengthened another friendly attack else: found_increases.append(reprCord[TCORD(ncap)]) board.setColor(1 - board.color) # -------------------------------------------------------------------- # # Test if we defend a one of our pieces # # -------------------------------------------------------------------- # found_defends = [] # Test which pieces were under attack used = [] for ncap in genCaptures(board): # getCaptures also generate promotions if FLAG(ncap) in PROMOTIONS: continue # We don't want to know about the same cord more than once if TCORD(ncap) in used: continue used.append(TCORD(ncap)) # If the attack was poining on the piece we just moved, we ignore it if TCORD(ncap) == FCORD(move) or TCORD(ncap) == TCORD(move): continue # If we were already defending the piece, we don't send a new # message if defends(oldboard, FCORD(move), TCORD(ncap)): continue # If the attack was not strong, we ignore it see = staticExchangeEvaluate(oldboard, ncap) if see < 0: continue v = defends(board, TCORD(move), TCORD(ncap)) # If the defend didn't help, it doesn't matter. Like defending a # bishop, threatened by a pawn, with a queen. # But on the other hand - it might still be a defend... # newsee = staticExchangeEvaluate(board, ncap) # if newsee <= see: continue if v: found_defends.append(reprCord[TCORD(ncap)]) # ------------------------------------------------------------------------ # # Test if we are rescuing an otherwise exposed piece # # ------------------------------------------------------------------------ # # Rescuing is only an option, if our own move wasn't an attack if oldboard.arBoard[tcord] == EMPTY: see0 = staticExchangeEvaluate(oldboard, fcord, oldboard.color) see1 = staticExchangeEvaluate(board, tcord, oldboard.color) if see1 > see0 and see1 > 0: yield _("rescues a %s") % reprPiece[board.arBoard[tcord]].lower() if found_threatens: yield _("threatens to win material by %s") % join(found_threatens) if found_increases: yield _("increases the pressure on %s") % join(found_increases) if found_defends: yield _("defends %s") % join(found_defends) PIECE_VALUES[BISHOP] = bishopBackup