def evalTrappedBishops (board, color): """ Check for bishops trapped at A2/H2/A7/H7 """ _bitPosArray = bitPosArray wbishops = board.boards[WHITE][BISHOP] bbishops = board.boards[BLACK][BISHOP] wpawns = board.boards[WHITE][PAWN] bpawns = board.boards[BLACK][PAWN] score = 0 if bbishops: if bbishops & _bitPosArray[A2] and wpawns & _bitPosArray[B3]: see = staticExchangeEvaluate(board, newMove(A2,B3)) if see < 0: score -= see if bbishops & _bitPosArray[H2] and wpawns & _bitPosArray[G3]: see = staticExchangeEvaluate(board, newMove(H2,G3)) if see < 0: score -= see if wbishops: if wbishops & _bitPosArray[A7] and bpawns & _bitPosArray[B6]: see = staticExchangeEvaluate(board, newMove(A7,B6)) if see < 0: score += see if wbishops & _bitPosArray[H7] and bpawns & _bitPosArray[G6]: see = staticExchangeEvaluate(board, newMove(H7,G6)) if see < 0: score += see return score if color == WHITE else -score
def evalTrappedBishops (board, color, phase): """ Check for bishops trapped at A2/H2/A7/H7 """ opcolor = 1-color opbishops = board.boards[opcolor][BISHOP] pawns = board.boards[color][PAWN] score = 0 # Don't waste time if not opbishops: return 0 if color == WHITE: if opbishops & bitPosArray[A2] and pawns & bitPosArray[B3]: see = staticExchangeEvaluate(board, newMove(A2,B3)) if see < 0: score += see if opbishops & bitPosArray[H2] and pawns & bitPosArray[G3]: see = staticExchangeEvaluate(board, newMove(H2,G3)) if see < 0: score += see else: if opbishops & bitPosArray[A7] and pawns & bitPosArray[B6]: see = staticExchangeEvaluate(board, newMove(A7,B6)) if see < 0: score += see if opbishops & bitPosArray[H7] and pawns & bitPosArray[G6]: see = staticExchangeEvaluate(board, newMove(H7,G6)) if see < 0: score += see return score
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 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 tip_mobility(model, ply, phase): board = model.getBoardAtPly(ply).board colorBackup = board.color # People need a chance to get developed #if model.ply < 16: # return board.setColor(WHITE) wmoves = len([move for move in genAllMoves(board) if \ KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and \ bitPosArray[TCORD(move)] & brank48[WHITE] and \ staticExchangeEvaluate(board, move) >= 0]) board.setColor(BLACK) bmoves = len([move for move in genAllMoves(board) if \ KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and \ bitPosArray[TCORD(move)] & brank48[BLACK] and \ staticExchangeEvaluate(board, move) >= 0]) board.setColor(colorBackup) #print wmoves, bmoves, phase #wb = board.boards[WHITE] #print float(wmoves)/bitLength(wb[KNIGHT]|wb[BISHOP]|wb[ROOK]|wb[QUEEN]) #bb = board.boards[WHITE] #print float(bmoves)/bitLength(bb[KNIGHT]|bb[BISHOP]|bb[ROOK]|bb[QUEEN]) if wmoves - phase >= (bmoves + 1) * 7: yield wmoves - bmoves, _("Black has a rather cramped position") elif wmoves - phase >= (bmoves + 1) * 3: yield wmoves - bmoves, _("Black has a slightly cramped position") elif bmoves - phase >= (wmoves + 1) * 7: yield wmoves - bmoves, _("White has a rather cramped position") elif bmoves - phase >= (wmoves + 1) * 3: yield wmoves - bmoves, _("White has a slightly cramped position")
def tip_mobility (model, phase): board = model.boards[-1].board colorBackup = board.color # People need a chance to get developed #if model.ply < 16: # return board.setColor(WHITE) wmoves = len([move for move in genAllMoves(board) if \ KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and \ bitPosArray[TCORD(move)] & brank48[WHITE] and \ staticExchangeEvaluate(board, move) >= 0]) board.setColor(BLACK) bmoves = len([move for move in genAllMoves(board) if \ KNIGHT <= board.arBoard[FCORD(move)] <= QUEEN and \ bitPosArray[TCORD(move)] & brank48[BLACK] and \ staticExchangeEvaluate(board, move) >= 0]) board.setColor(colorBackup) #print wmoves, bmoves, phase #wb = board.boards[WHITE] #print float(wmoves)/bitLength(wb[KNIGHT]|wb[BISHOP]|wb[ROOK]|wb[QUEEN]) #bb = board.boards[WHITE] #print float(bmoves)/bitLength(bb[KNIGHT]|bb[BISHOP]|bb[ROOK]|bb[QUEEN]) if wmoves-phase >= (bmoves+1)*7: yield wmoves-bmoves, _("Black has a rather cramped position") elif wmoves-phase >= (bmoves+1)*3: yield wmoves-bmoves, _("Black has a slightly cramped position") elif bmoves-phase >= (wmoves+1)*7: yield wmoves-bmoves, _("White has a rather cramped position") elif bmoves-phase >= (wmoves+1)*3: yield wmoves-bmoves, _("White has a slightly cramped position")
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) piece = board.arBoard[tcord] 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
def attack_type (model, 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.boards[-1].board oldboard = model.boards[-2].board if len(model.moves) > 1: oldmove = model.moves[-2].move oldboard3 = model.boards[-3].board else: oldmove = None move = model.moves[-1].move tcord = TCORD(move) if oldboard.arBoard[tcord] != EMPTY: 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 _("exchanges material") elif see > 0: yield _("captures material") elif see < 0: yield _("sacrifies material") # ------------------------------------------------------------------------ # # Test if we threats something, or at least puts more preassure on it # # ------------------------------------------------------------------------ # # 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 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 # We will always attack first with the lowest valued piece. # Where is it? lowest = None cord = None attacks = getAttacks (board, TCORD(ncap), board.color) for fcord in iterBits(attacks): v = PIECE_VALUES[board.arBoard[fcord]] if lowest == None or v < lowest: lowest = v cord = fcord assert cord != None, "How can there not be any attacks, when ncap exists? %s" % toString(attacks) easiestAttack = newMove(cord, TCORD(ncap)) # Now test if we threats our enemy, or they are too strong see = staticExchangeEvaluate(board, easiestAttack) if see > 0: # If a new winning capture has been created yield _("threatens to win material %s") % toSAN(board,easiestAttack, True) elif bitLength(attacks) > 1: # Even though we might not yet be strong enough, we might still # have strengthened another friendly attack yield _("increases the pressure on %s") % reprCord[TCORD(ncap)] board.setColor(1-board.color) # ------------------------------------------------------------------------ # # Test if we defend a one of our pieces # # ------------------------------------------------------------------------ # # 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 oldboard.setColor(1-oldboard.color) see = staticExchangeEvaluate(oldboard, ncap) oldboard.setColor(1-oldboard.color) 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: yield _("defends %s") % reprCord[TCORD(ncap)] PIECE_VALUES[BISHOP] = bishopBackup
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) piece = board.arBoard[tcord] 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