def attack_moves(self, square, color): moves = [] current = color first = A8 last = H1 if (current == -1): current = self.current_color if is_square(square): first = square last = square for i in range(first, last + 1): if is_not_square(i): i = i + 7 continue if self.colors[i] != current: continue piece = self.pieces[i] if piece == PAWN: for j in range(2, 4): square = i + PAWN_OFFSETS[current][j] if is_not_square(square): continue if self.colors[square] != current: moves.append(Move(self, current, i, square, CAPTURE)) else: for j in range(0, PIECE_OFFSET_SIZE[piece]): offset = PIECE_OFFSET[piece][j] square = i while True: square += offset if is_not_square(square): break if not self.pieces[square]: moves.append( Move(self, current, i, square, NORMAL)) else: if self.colors[square] == current: break moves.append( Move(self, current, i, square, CAPTURE)) break # Stop after first move for king and knight if (piece == KING or piece == KNIGHT): break return moves
def attacked(self, square, color): for i in range(A8, H1 + 1): if is_not_square(i): i = i + 7 continue if self.colors[i] != color: continue piece = self.pieces[i] diff = i - square diff_0x88 = 0x77 + diff if ATTACKS[diff_0x88] & (1 << SHIFTS[piece]): if piece == PAWN: if ((diff > 0 and color == WHITE) or (diff <= 0 and color == BLACK)): return True continue if piece == KING or piece == KNIGHT: return True offset = RAYS[diff_0x88] j = i + offset blocked = False while j != square: if self.pieces[j]: blocked = True break j += offset if not blocked: return True return False
def get_value(self): self.white_value = 0 self.black_value = 0 result = 0 for i in range(A8, H1 + 1): if is_not_square(i): i = i + 7 continue result += self.values[i] if self.colors[i] == WHITE: self.white_value += self.values[i] elif self.colors[i] == BLACK: self.black_value += -self.values[i] return result
def get_pieces(self): if self.hash != self.last_hash: pieces_list = [] for i in range(A8, H1 + 1): if is_not_square(i): i = i + 7 continue if (self.pieces[i] == PIECE_EMPTY or self.colors[i] == COLOR_EMPTY): continue pieces_list.append(Piece( name=NAMES[self.pieces[i]], position=p0x88_to_tuple(i), color="white" if self.colors[i] == WHITE else "black", )) self.pieces_list = pieces_list self.last_hash = self.hash return self.pieces_list
def generate_moves(self, legal, square, color): moves = [] current = color first = A8 last = H1 single = 0 if current == COLOR_EMPTY: current = self.current_color other = next_color(current) if is_square(square): first = square last = square single = 1 for i in range(first, last + 1): if is_not_square(i): i = i + 7 continue if self.colors[i] != current: continue piece = self.pieces[i] if piece == PAWN: # 1 step forward square = i + PAWN_OFFSETS[current][0] if not self.pieces[square]: moves.append(Move(self, current, i, square, NORMAL)) # 2 steps forward square = i + PAWN_OFFSETS[current][1] if (rank(i) == SECOND_RANK[current] and not self.pieces[square]): moves.append(Move(self, current, i, square, BIG_PAWN)) # Captures for j in range(2, 4): square = i + PAWN_OFFSETS[current][j] if is_not_square(square): continue if self.pieces[square] and self.colors[square] == other: moves.append(Move(self, current, i, square, CAPTURE)) elif square == self.en_passant_square: moves.append( Move(self, current, i, square, EN_PASSANT)) else: for j in range(0, PIECE_OFFSET_SIZE[piece]): offset = PIECE_OFFSET[piece][j] square = i while True: square += offset if is_not_square(square): break if not self.pieces[square]: moves.append( Move(self, current, i, square, NORMAL)) else: if self.colors[square] == current: break moves.append( Move(self, current, i, square, CAPTURE)) break # Stop after first for king and knight if (piece == KING or piece == KNIGHT): break # Castling if ((not single or last == self.kings[current]) and self.kings[current] != EMPTY): if self.castling[current] & KINGSIDE: origin = self.kings[current] dest = origin + E + E if (not self.pieces[origin + E] and not self.pieces[dest] and not self.attacked(origin, other) and not self.attacked(origin + E, other) and not self.attacked(dest, other)): moves.append(Move(self, current, origin, dest, KINGSIDE)) if self.castling[current] & QUEENSIDE: origin = self.kings[current] dest = origin + W + W if (not self.pieces[origin + W] and not self.pieces[origin + W + W] and not self.pieces[origin + W + W + W] and not self.pieces[dest] and not self.attacked(origin, other) and not self.attacked(origin + W, other) and not self.attacked(dest, other)): moves.append(Move(self, current, origin, dest, QUEENSIDE)) if not legal: return moves legal_moves = [] for move in moves: move.do(self) if not self.in_check(current): legal_moves.append(move) #else: # self.display() move.undo(self) return legal_moves