def __init__(self): print() print("Welcome to M_Chess") print('Multiplayer chess') print() print('Player 1 takes the white pieces') print("White pieces are the ones on the lower part with single letters") print() print("Player 2 takes the black pieces") print("Black pieces are the ones on the upper part with periods by the side") print() self.bd = Board() self.board = self.bd.board self.bd.print_board() self.move_bot = Move(self.board) count = 0 player = "" while True: i = 0 if count == 0 or count % 2 == 0: i = 1 else: i = 2 inp,player = self.get_input(i) p,y = self.check_input(inp) while not p: inp,player = self.get_input(i) p,y = self.check_input(inp) move = self.move(p,y,player) while not move: inp,player = self.get_input(i) p,y = self.check_input(inp) move = self.move(p,y,player) self.bd.print_board() count += 1
def record_valid_move(self): center = (14, 2) dest = (13, 2) piece = Piece(center, self.board.get_footprint(center), 'W') move = Move(piece, 'W', self.board.get_copy(), center, dest) self.assertTrue(move.record())
def test_place_on_top(self): board = Board() board.rings[0][0] = Board.Player.white move = Move(board, (0, 0)) self.assertFalse(move.is_valid()) self.assertNotIn(move, Move.get_valid_moves(board))
def buy_card(self, pile): if (pile is None): self.moves.append(Move(self.buying_power(), Card(0, 0, 0))) else: new_card = pile.remove_card() self.moves.append(Move(self.buying_power(), new_card)) self.discard.append(new_card)
def move(self, departure=None, arrival=None): if departure == None : departure = self.selected_case if arrival == None : arrival = self.selected_case_2 new_move = Move( departure, arrival, self.special_moves_authorization[:], captured = not self.is_case_empty(arrival) ) if self.is_special_move(departure, arrival) : self.special_move_features(departure, arrival, new_move) board = self.board self.reset_selected_cases() board[arrival].get_captured() self.update_special_moves_authorization(departure, arrival) board[departure], board[arrival] = board[arrival], board[departure] piece = board[arrival] if piece.name == "pawn" and piece.color == Color.WHITE and arrival <= 7 : piece.get_promoted() new_move.promotion = True elif piece.name == "pawn" and piece.color == Color.BLACK and arrival >= 56: piece.get_promoted() new_move.promotion = True self.turn = Color.BLACK if self.turn == Color.WHITE else Color.WHITE self.moves_played.append(new_move) if self.is_king_checked(piece.color) : self.cancel_last_move() return False return True
def unsafe_moves(game): """Return banned moves to neighbour positions (walls and other snakes).""" banned_moves = [] head = game.me.head() neighbours = [{ 'd': head.up(), 'm': Move(UP, 0, 'unsafe') }, { 'd': head.down(), 'm': Move(DOWN, 0, 'unsafe') }, { 'd': head.left(), 'm': Move(LEFT, 0, 'unsafe') }, { 'd': head.right(), 'm': Move(RIGHT, 0, 'unsafe') }] # If neighbour move is unsafe, add to banned moves for n in neighbours: if game.is_unsafe(n['d']): banned_moves.append(n['m']) return banned_moves
def way_out(game): """Return potential moves that are surrounded by 3 or more unsafe things.""" moves = [] head = game.me.head() neighbours = [{ 'd': head.up(), 'm': Move(UP, 0.6, 'unsafe') }, { 'd': head.down(), 'm': Move(DOWN, 0.6, 'unsafe') }, { 'd': head.left(), 'm': Move(LEFT, 0.6, 'unsafe') }, { 'd': head.right(), 'm': Move(RIGHT, 0.6, 'unsafe') }] # Loop through possible moves for c in neighbours: side_sum = 0 if game.is_unsafe(c['d']): continue # Check the neighbours of potential moves for n in c['d'].neighbours(False): if game.is_unsafe(n) and not game.is_wall(n): side_sum += 1 if side_sum >= 3: moves.append(c['m']) return moves
def critical_flood(game): banned_moves = [] head = game.me.head() neighbours = [{ 'd': head.up(), 'm': Move(UP, 0, 'flood unsafe') }, { 'd': head.down(), 'm': Move(DOWN, 0, 'flood unsafe') }, { 'd': head.left(), 'm': Move(LEFT, 0, 'flood unsafe') }, { 'd': head.right(), 'm': Move(RIGHT, 0, 'flood unsafe') }] for n in neighbours: if game.is_unsafe(n['d']): continue area = utils.flood_fill(game, n['d']) # print(n['m'].direction + ' - ' + str(area) + ' | ' + str(game.me.length())) if game.me.length() > area: banned_moves.append(n['m']) return banned_moves
def get_largest_area(game): head = game.me.head() neighbours = [{ 'd': head.up(), 'm': Move(UP, 0, 'flood unsafe') }, { 'd': head.down(), 'm': Move(DOWN, 0, 'flood unsafe') }, { 'd': head.left(), 'm': Move(LEFT, 0, 'flood unsafe') }, { 'd': head.right(), 'm': Move(RIGHT, 0, 'flood unsafe') }] max_area = -1 max_move = neighbours[0] for n in neighbours: if game.is_unsafe(n['d']): continue area = utils.flood_fill(game, n['d']) # print(n['m'].direction + ' - ' + str(area) + ' | ' + str(game.me.length())) if area > max_area: max_area = area max_move = n['m'] return max_move
def test_make_move(): board = Board() move = Move(board) board.array[3][2] = "w" board.array[3][1] = "w" move.make_move(3, 0, 'b') assert board.array[3][2] == board.array[3][1] == board.array[3][0] == "b"
def create_duplicate(self, unit): if unit.duplication_unit == MELEE_UNIT: return MeleeUnit( *Move.transform(unit.x, unit.y, unit.stasis_direction)) else: return WorkerUnit( *Move.transform(unit.x, unit.y, unit.stasis_direction))
def get_en_passant(self, moves, row_no, col_no): col_right = col_no + 1 col_left = col_no - 1 if self.movelog: last_move = self.movelog[-1] if last_move.piece_moved[1] == "P": # index 1 for piecetype, not colour if self.white_move: if row_no == 3: # Check location of pawn to be moved if last_move.startRow == 1 and last_move.endRow == 3: # Check start en end of last move if last_move.endCol == col_right: moves.append( Move(self.board, (row_no, col_no), (row_no - 1, col_right), captured_row=last_move.endRow, captured_col=last_move.endCol) ) elif last_move.endCol == col_left: moves.append( Move(self.board, (row_no, col_no), (row_no - 1, col_left), captured_row=last_move.endRow, captured_col=last_move.endCol) ) else: # Black move if row_no == 5: if last_move.startRow == 1 and last_move.endRow == 5: if last_move.endCol == col_right: moves.append( Move(self.board, (row_no, col_no), (row_no + 1, col_right), captured_row=last_move.endRow, captured_col=last_move.endCol) ) elif last_move.endCol == col_left: moves.append( Move(self.board, (row_no, col_no), (row_no + 1, col_left), captured_row=last_move.endRow, captured_col=last_move.endCol) ) return moves
def test___ne__(self): source = Square('a1') target = Square('a2') promotion = 'q' move1 = Move(source, target) move2 = Move(source, target) self.assertEqual(False, move1.__ne__(move2))
def next(self): raw_entry = self.next_raw() source_x = ((raw_entry[1] >> 6) & 077) & 0x7 source_y = (((raw_entry[1] >> 6) & 077) >> 3) & 0x7 target_x = (raw_entry[1] & 077) & 0x7 target_y = ((raw_entry[1] & 077) >> 3) & 0x7 promote = (raw_entry[1] >> 12) & 0x7 move = Move( source=Square.from_x_and_y(source_x, source_y), target=Square.from_x_and_y(target_x, target_y), promotion="nbrq"[promote + 1] if promote else None) # Replace the non standard castling moves. if move.uci == "e1h1": move = Move.from_uci("e1g1") elif move.uci == "e1a1": move = Move.from_uci("e1c1") elif move.uci == "e8h8": move = Move.from_uci("e8g8") elif move.uci == "e8a8": move = Move.from_uci("e8c8") return { "position_hash": raw_entry[0], "move": move, "weight": raw_entry[2], "learn": raw_entry[3] }
def __init__(self, rect, speed, tileset, level, maxHealth, **kwargs): super().__init__(rect=rect, dirRule=lambda: { -1: Direction.Left, 0: None, 1: Direction.Right, }[self.move.getDir(x=True)], idName="enemy", baseHealth=maxHealth, **kwargs) self.collision = Collision(self, level, "enemy") self.move = Move(self, speed, self.collision) self.gravity = GravityLine(self, 2, h=level.map.h // 2) self._ai = AI(self) def _isMoving(): return self.move.getSpeed(x=True) != 0 def _hDir(): return self.move.getDir(x=True) def _vDir(): return {False: -1, True: 1}[self.gravity.positiveDir()] image = Files.loadImage(tileset) self._display = Display(image, self, Animation(image, 11, _isMoving, _hDir, _vDir), True)
def main(argv): b = BoardState() b.initialize_from_file("../data/test_init.json") ''' for i in range(b.DEFAULT_BOARD_SIZE): for j in range(b.DEFAULT_BOARD_SIZE): print("({}, {}) -> {}".format(i, j, b._board[i][j])) ''' for player in [BoardState.Player.WHITE, BoardState.Player.BLACK]: b._next_player = player total_moves = len(b.get_all_legal_moves()) print("Player {}, {} possible moves.".format(player, total_moves)) b.print_board() # Check captures moves = list() moves.append(Move(Coord(0, 3), Coord(2, 3), BoardState.Player.BLACK)) moves.append(Move(Coord(4, 4), Coord(2, 4), BoardState.Player.WHITE)) moves.append(Move(Coord(3, 0), Coord(3, 3), BoardState.Player.BLACK)) moves.append(Move(Coord(5, 4), Coord(4, 4), BoardState.Player.WHITE)) moves.append(Move(Coord(3, 3), Coord(3, 4), BoardState.Player.BLACK)) for move in moves: print("") print("--------------------------------------------------------") print("") # print(str(move)) b.process_move(move) b.print_board()
def available_moves(self, player): """Yields all available moves for a given player. Args: player: Player to get available moves for. Yields: All available moves for a given player. """ pieces = 0 if player == Player.white: pieces = self._white_pieces elif player == Player.black: pieces = self._black_pieces else: raise ValueError("Only white and black players can move") max_width, max_height = self.WIDTH - 1, self.HEIGHT - 1 for x in range(self.WIDTH): for y in range(self.HEIGHT): index = x + y * self.WIDTH if (pieces >> index) & 1: if x != 0 and self.get(x - 1, y) == Player.none: yield Move(x, y, Direction.west) if x != max_width and self.get(x + 1, y) == Player.none: yield Move(x, y, Direction.east) if y != 0 and self.get(x, y - 1) == Player.none: yield Move(x, y, Direction.north) if y != max_height and self.get(x, y + 1) == Player.none: yield Move(x, y, Direction.south)
def _get_moves(self): player = self.to_move squares = self.squares valid_indices = WHITE_IDX if player == WHITE else BLACK_IDX moves = [] for i in self.valid_squares: for j in valid_indices: dest = i + j if squares[i] & player and squares[i] & MAN and squares[ dest] & FREE: sq1 = [i, player | MAN, FREE] if (player == BLACK and i >= 39) or (player == WHITE and i <= 15): sq2 = [dest, FREE, player | KING] else: sq2 = [dest, FREE, player | MAN] moves.append(Move([sq1, sq2])) for j in KING_IDX: dest = i + j if squares[i] & player and squares[i] & KING and squares[ dest] & FREE: sq1 = [i, player | KING, FREE] sq2 = [dest, FREE, player | KING] moves.append(Move([sq1, sq2])) return moves
def _extend_capture(self, valid_moves, captures, add_sq_func, visited): player = self.to_move enemy = self.enemy squares = self.squares final_captures = [] while captures: c = captures.pop() new_captures = [] for j in valid_moves: capture = c.affected_squares[:] last_pos = capture[-1][0] mid = last_pos + j dest = last_pos + j * 2 if ((last_pos, mid, dest) not in visited and (dest, mid, last_pos) not in visited and squares[mid] & enemy and squares[dest] & FREE): sq2, sq3 = add_sq_func(player, squares, mid, dest, last_pos) capture[-1][2] = FREE capture.extend([sq2, sq3]) visited.add((last_pos, mid, dest)) new_captures.append(Move(capture)) if new_captures: captures.extend(new_captures) else: final_captures.append(Move(capture)) return final_captures
def move(self, move: Move) -> None: vial_from: Vial = self.vials[move.get_from_index()] if vial_from.is_empty(): raise Exception('Move failed, vial {} is empty'.format( move.get_from_index())) vial_to: Vial = self.vials[move.get_to_index()] if vial_to.is_full(): raise Exception('Move failed, vial {} is full'.format( move.get_to_index())) if not vial_from.is_empty() and not vial_to.is_empty( ) and vial_from.peek() != vial_to.peek(): raise Exception( f"Move failed, vial {move.get_from_index()} and vial {move.get_to_index()} don't have the same colors on top" ) vials = [vial_from, vial_to] for vial in vials: self.weight -= vial.get_weight() color: Color = vial_from.pop() vial_to.push(color) for vial in vials: self.weight += vial.get_weight() if not vial_from.is_empty() and not vial_to.is_full( ) and vial_from.peek() == vial_to.peek(): self.move(move) else: self.moves.append(move)
def check_if_moves_available(self): """Checks if there are any legal moves that the side to move can make.""" piece_list = list( filter(lambda x: x.colour == self.board.side_to_move, self.board.piece_list)) destinations = {} for i, row in enumerate(self.board.array): for j, square in enumerate(row): if square: if square.colour != self.board.side_to_move: destinations[(i, j)] = True else: destinations[(i, j)] = False for piece in piece_list: for place, capture in destinations.items(): promotion = None if (piece.symbol == "p") and (place[0] == ( 7 if piece.colour == Colour.WHITE else 0)): promotion = Queen move = Move(piece.symbol, type(piece), piece.colour, piece.position, place, is_capture=capture, promotion=promotion) if move.check_move(self.board): return True return False
def __init__(self, level, speed, tileset, **kwargs): super().__init__(dirRule=lambda: { -1: Direction.Left, 0: None, 1: Direction.Right }[self.move.getDir(x=True)], **kwargs) self.collision = Collision(self, level) self.move = Move(self, speed, collision=self.collision) self._gravity = GravityLine(self, 2, h=level.map.h // 2) self.jumping = Jumping(self.move, self._gravity, 2) self._input = Input(inputStream=self.getInputStream()) self.applyInputSettings() self._damageTimer = MinTimeEventStream(duration=2) self._damageTimer.subscribe("self", self._takeDmg, autoInit=False) def _isMoving(): return self.move.getSpeed(x=True) != 0 def _hDir(): return self.move.getDir(x=True) def _vDir(): return {False: -1, True: 1}[self._gravity.positiveDir()] image = Files.loadImage(tileset) self._display = Display(image, self, Animation(image, 11, _isMoving, _hDir, _vDir), True) self._weapon = Weapon(level, anchor=self, offsetFunc=lambda: ((5 * self.getIntDir()), 0), inputStream=self.getInputStream())
def make_move(self, currentCenter, newCenter): """ Parameters: currCenterInput (string): the center of the piece the player wishes to move. Format should match <row letter, column number> e.g. 'a19', 'm4', etc. Must fall within 18x18 area of play. newCenterInput (string): the center of the piece the player wishes to move. Same rules as for above parameter. Returns: True if move was made successfully, False if not. """ if self.is_game_over(): return False # Convert input and validate origin = self.__convert_to_numeric_tuple(currentCenter) destination = self.__convert_to_numeric_tuple(newCenter) if not origin or not destination: # If input was invalid return False # Create piece object, move object, and validate piece = self._gameBoard.create_piece(origin) move = Move(origin, destination, piece, self._currentPlayer, self._gameBoard) if not move.is_legal(): return False # Execute move and check for victory self._gameBoard.move_piece(piece, destination) if self.check_victory(): self.assign_victory(self._currentPlayer) # Toggle whose turn it is self._currentPlayer = OPPONENT[self._currentPlayer] return True
def strategy(self, data): global trajectory, traj_times, traj_screen team = data.teams[self.team] ball = data.ball self.predictor.update(ball, 0.0) if trajectory is None: trajectory = [] traj_times = [] traj_screen = False for i in xrange(1, 3): trajectory.append(self.predictor.predict(i)) traj_times.append(time.time() + i) for i in xrange(len(trajectory)): if traj_times[i] < time.time(): trajectory = [] traj_times = [] traj_screen = False for i in xrange(1, 3): trajectory.append(self.predictor.predict(i)) traj_times.append(time.time() + i) break out_data = VsssOutData() out_data.moves.append(Move()) out_data.moves.append(Move()) out_data.moves.append(Move()) return out_data
def __init__(self): self.map = None self.start = State(0, 0) self.goal = State(0.5, 0.5) self.moves = [ Move(0.5, 0), # forward Move(-0.5, 0), # back Move(0, 1.5708), # turn left 90 Move(0, -1.5708) ] # turn right 90 self.robot = Robot(0.5, 0.5) self.is_working = False # Replace with mutex after all self.map_subscriber = rospy.Subscriber("map", OccupancyGrid, self.new_map_callback) #self.start_subscriber = rospy.Subscriber("initialpose", PoseWithCovarianceStamped, self.new_start_callback) #self.goal_subscriber = rospy.Subscriber("goal", PoseStamped, self.new_goal_callback) self.path_publisher = rospy.Publisher("trajectory", MarkerArray, queue_size=1) self.pose_publisher = rospy.Publisher("debug_pose", PoseStamped, queue_size=1)
def next(self): raw_entry = self.next_raw() source_x = ((raw_entry[1] >> 6) & 077) & 0x7 source_y = (((raw_entry[1] >> 6) & 077) >> 3) & 0x7 target_x = (raw_entry[1] & 077) & 0x7 target_y = ((raw_entry[1] & 077) >> 3) & 0x7 promote = (raw_entry[1] >> 12) & 0x7 move = Move(source=Square.from_x_and_y(source_x, source_y), target=Square.from_x_and_y(target_x, target_y), promotion="nbrq"[promote + 1] if promote else None) # Replace the non standard castling moves. if move.uci == "e1h1": move = Move.from_uci("e1g1") elif move.uci == "e1a1": move = Move.from_uci("e1c1") elif move.uci == "e8h8": move = Move.from_uci("e8g8") elif move.uci == "e8a8": move = Move.from_uci("e8c8") return { "position_hash": raw_entry[0], "move": move, "weight": raw_entry[2], "learn": raw_entry[3] }
def __init__(self): self.map = None self.start = None self.goal = None self.moves = [ Move(0.1, 0), # forward Move(-0.1, 0), # back Move(0, 1.5708), # turn left 90 Move(0, -1.5708) ] # turn right 90 self.robot = Robot(0.5, 0.5) self.is_working = False # Replace with mutex after all self.map_subscriber = rospy.Subscriber("map", OccupancyGrid, self.new_map_callback) self.start_subscriber = rospy.Subscriber("initialpose", PoseWithCovarianceStamped, self.new_start_callback) self.goal_subscriber = rospy.Subscriber("goal", PoseStamped, self.new_goal_callback) self.path_publisher = rospy.Publisher("trajectory", MarkerArray, queue_size=1) self.pose_publisher = rospy.Publisher("debug_pose", PoseStamped, queue_size=1) # what will be there. A module goes into variable. Isn't it too much memory consumption. Maybe I should assign function replan() to this variable? self.planner = planners.astar.replan
def _legal_moves_1(self, player, roll): # player = 0 or 1 # roll = 3 other_player = 0 if player == 1 else 1 legal_moves = [] # Checkers on bar if self.board[player, 25] != 0: if self.board[other_player, roll] == 0: legal_moves.append(Move(25, roll)) elif self.board[other_player, roll] == 1: legal_moves.append(Move(25, roll, blot=True)) else: bearing_off = self.board[player, 7:].sum() == 0 for i in range(1, 25): if self.board[player, i] != 0: if i - roll > 0 and self.board[other_player, 25 - i + roll] == 0: legal_moves.append(Move(i, roll)) elif i - roll > 0 and self.board[other_player, 25 - i + roll] == 1: legal_moves.append(Move(i, roll, blot=True)) elif i - roll <= 0 and bearing_off: legal_moves.append(Move(i, roll)) return legal_moves
def __init__(self, player, game_map): self.user_interface = UserInterface() self.game_map = game_map self.move = Move(game_map) self.merchant = Merchant(game_map, self.move) self.player = player self.errors = 0
def setUp(self): """ Set defaults for creating test Team objects """ self.default_move = ["None", 0, 0, 0, "None", 0, "None"] self.default_pokemon = [ 0, "None", ("None", ), 0, 0, { "None": "None" }, [], [ Move(*self.default_move), Move(*self.default_move), Move(*self.default_move), Move(*self.default_move) ] ] self.default_pokemon_list = [ Pokemon(*self.default_pokemon), Pokemon(*self.default_pokemon), Pokemon(*self.default_pokemon), Pokemon(*self.default_pokemon), Pokemon(*self.default_pokemon), Pokemon(*self.default_pokemon) ]
def test_cloning(self): move = Move(rsmart = "rsmart", rid = "rid", compound_id= "compound_id") cloned_move = move.clone() different_python_object = (id(move) != id(cloned_move)) identical_move_object = move.eq_full_inchi_key(cloned_move) assert (different_python_object and identical_move_object)
def random_pokemon(side): pokemon = Pokemon(randint(1, num_pokemon), randint(1, 2)) if side == 'pc': pokemon.moves = Move.latest_moves(4) else: num_moves = randint(2, 3) pokemon.moves = Move.random_moves(num_moves) return pokemon
def undo_all_moves(self, annotation=''): while self.undo_list: move = self.undo_list.pop() rev_move = Move([[idx, dest, src] for idx, src, dest in move.affected_squares]) rev_move.annotation = move.annotation self.make_move(rev_move, True, False) move.annotation = annotation self.redo_list.append(move) annotation = rev_move.annotation
def setUp(self): p = Position() self.moves = p.get_legal_moves() m1 = Move.from_uci('e2e4') m2 = Move.from_uci('b1c3') self.san = SanNotation(p, m1) self.san_dup = SanNotation(p, m1) self.san_other = SanNotation(p, m2) self.position = p self.m1 = m1 self.m2 = m2
def test_move_list(self): root = Game() variation = root.add_main_variation(Move.from_uci("e2e4")) assert len(root) == 1 assert root[Move.from_uci("e2e4")] == variation assert root[0] == variation next_var = variation.add_main_variation(Move.from_uci("c7c5")) assert next_var.get_prev_moves() == " e2e4 c7c5" assert next_var.get_prev_moves(format="san") == " e2e4 c5" root.game_score()
def undo_move(self, move=None, notify=True, redo=True, annotation=''): if move is None: if not self.undo_list: return if redo: move = self.undo_list.pop() rev_move = Move([[idx, dest, src] for idx, src, dest in move.affected_squares]) rev_move.annotation = move.annotation self.make_move(rev_move, notify, False) if redo: move.annotation = annotation self.redo_list.append(move)
def play_moves(self): # plays l = list() for card in self.current_player.cards[Tag.Hand]: if (card.cost > self.current_player.resource): continue m = Move(type = MoveType.Play) m.set_entity(card) l.append(m) # attacks if len(self.opp_player.taunts): target_list = self.opp_player.taunts.copy() else: target_list = self.opp_player.cards[Tag.Minion].copy() target_list.append(self.opp_player.cards[Tag.Hero]) target_list = list(filter(lambda x : x.is_attack_target, target_list)) for card in self.current_player.cards[Tag.Minion]: if not card.can_attack: continue for target in target_list: m = Move(type = MoveType.Attack) m.set_entity(card) m.set_target(target) l.append(m) #end_this_turn l.append(Move(MoveType.EndThisTurn)) return l
def test_pawn_captures(self): """Tests pawn captures in the kings gambit.""" pos = Position() pos.make_move(pos.get_move_from_san("e4")) pos.make_move(pos.get_move_from_san("e5")) pos.make_move(pos.get_move_from_san("f4")) accepted = pos.copy() self.assertTrue(Move.from_uci("e5f4") in accepted.get_pseudo_legal_moves()) self.assertTrue(Move.from_uci("e5f4") in accepted.get_legal_moves()) accepted.make_move(accepted.get_move_from_san("exf4")) wierd_declined = pos.copy() wierd_declined.make_move(wierd_declined.get_move_from_san("d5")) wierd_declined.make_move(wierd_declined.get_move_from_san("exd5"))
def __init__(self, level, speed, tileset, **kwargs): super().__init__( dirRule=lambda: { -1: Direction.Left, 0: None, 1: Direction.Right }[self.move.getDir(x=True)], **kwargs) self.collision = Collision(self, level) self.move = Move(self, speed, collision=self.collision) self._gravity = GravityLine(self, 2, h=level.map.h // 2) self.jumping = Jumping(self.move, self._gravity, 2) self._input = Input(inputStream=self.getInputStream()) self.applyInputSettings() self._damageTimer = MinTimeEventStream(duration=2) self._damageTimer.subscribe("self", self._takeDmg, autoInit=False) def _isMoving(): return self.move.getSpeed(x=True) != 0 def _hDir(): return self.move.getDir(x=True) def _vDir(): return {False: -1, True: 1}[self._gravity.positiveDir()] image = Files.loadImage(tileset) self._display = Display(image, self, Animation(image, 11, _isMoving, _hDir, _vDir), True) self._weapon = Weapon(level, anchor=self, offsetFunc=lambda: ((5 * self.getIntDir()), 0), inputStream=self.getInputStream())
def test_move_info(self): """Tests move info generation.""" pos = Position() e4 = pos.get_move_info(Move.from_uci('e2e4')) self.assertEqual(e4.san, 'e4') self.assertFalse(e4.is_check) self.assertFalse(e4.is_checkmate) self.assertFalse(e4.is_castle)
def play(self,args): """ Updates the board according to the move specified as argument """ color = self.__decodeColor__(args[0]) posLetter,posNumber = self.__decodePosition__(args[1]) m = Move(color=color,posLetter=posLetter,posNumber=posNumber) self.board.update(m) self.bPlayer.updateListLegal(m.getListFormat(),self.board.getKilled()) self.wPlayer.updateListLegal(m.getListFormat(),self.board.getKilled()) self.log.logDebug(self.board.showBoard()) return ''
def test_single_step_pawn_move(self): """Tests that single step pawn moves are possible.""" pos = Position() a3 = Move.from_uci('a2a3') self.assertTrue(a3 in pos.get_pseudo_legal_moves()) self.assertTrue(a3 in pos.get_legal_moves()) pos.get_move_info(a3) pos.make_move(a3)
def move_by(self): """move""" try: move = Move(self.input.text(),self.output.text()) except IOError as e: QMessageBox.critical(None, "Error", "{0}".format(e), QMessageBox.Abort) return try: if self.units.currentText() == 'values': try: move.by_points(int(self.value.text())) except ValueError as e: QMessageBox.critical(None, "ERROR: Invalid number of values", "{0}".format(e), QMessageBox.Abort) return elif self.units.currentText() == 'meters': try: move.by_distance(float(self.value.text())) except ValueError as e: QMessageBox.critical(None, "ERROR: Invalid number of values", "{0}".format(e), QMessageBox.Abort) return elif self.units.currentText() == 'seconds': try: move.by_seconds(float(self.value.text())) except ValueError as e: QMessageBox.critical(None, "ERROR: Invalid number of values", "{0}".format(e), QMessageBox.Abort) return except MoveError as e: QMessageBox.critical(None, "Error", "{0}".format(e), QMessageBox.Abort) return show_as_layer.show(self.output.text(),self.stylePath)
class Enemy(Object, Dir, IDed, Alive, Health, Drawable, Inputable): def __init__(self, rect, speed, tileset, level, maxHealth, **kwargs): super().__init__(rect=rect, dirRule=lambda: { -1: Direction.Left, 0: None, 1: Direction.Right, }[self.move.getDir(x=True)], idName="enemy", baseHealth=maxHealth, **kwargs) self.collision = Collision(self, level, "enemy") self.move = Move(self, speed, self.collision) self.gravity = GravityLine(self, 2, h=level.map.h // 2) self._ai = AI(self) def _isMoving(): return self.move.getSpeed(x=True) != 0 def _hDir(): return self.move.getDir(x=True) def _vDir(): return {False: -1, True: 1}[self.gravity.positiveDir()] image = Files.loadImage(tileset) self._display = Display(image, self, Animation(image, 11, _isMoving, _hDir, _vDir), True) def tick(self): collisions = self.move() self.gravity.tick(collisions) self._ai.tick(collisions) if collisions.get("bullet"): self.decHealth(1) self.move.setSpeed(y=self.gravity.getDir() * -8) if self.getHealth() == 0: self.kill() return collisions @Behaviors.cleanupCollision def kill(self): super().kill()
def test___init__(self): with self.assertRaises(ValueError): Move(Square('a1'), Square('a1')) with self.assertRaises(ValueError): m = Move.from_uci('a1a2q') for move in gen_moves(): pass
def move(self, tiles, opponent_move): opponent_move_str = str(opponent_move) if opponent_move else '' self.popen.stdin.write(''.join(tiles) + ":" + opponent_move_str + "\n") self.popen.stdin.flush() line = self.popen.stdout.readline() if not line: raise ExternalPlayerError("no move") # Might raise InvalidMoveError move = Move.from_str(line.rstrip()) return move
def move_piece(self, play, black): """Moves piece that was selected""" A = 65 #The letter A in ASCII x1 = ord(play[0].strip().upper()) - A y1 = int(play[1]) - 1 x2 = ord(play[2].strip().upper()) - A y2 = int(play[3]) - 1 start = x1 + (y1 * 9) end = x2 + (y2 * 9) if black: if not Move.is_legal_move(start, end, self.black_board, self.white_board): return False self.black_board = Move.apply_attack_move(start, end, self.black_board) self.white_board = Move.apply_defense_move(start, end, self.white_board) else: if not Move.is_legal_move(start, end, self.white_board, self.black_board): return False self.white_board = Move.apply_attack_move(start, end, self.white_board) self.black_board = Move.apply_defense_move(start, end, self.black_board) return True
class MoveTestCase(ut.TestCase): def setUp(self): piece = (0, 1, BLACK) direction = FORWARD_LEFT self.move = Move(piece, direction) def tearDown(self): self.move = None def testClone(self): self.move.add(FORWARD_RIGHT) new_move = self.move.clone() # print # print "Move:" # self.move.printMove() # print # print "New Move:" # new_move.printMove() self.assertTrue(self.move == new_move)
def tell(self, about, receivers, command, **kwargs): """send info about player 'about' to users 'receivers'""" def encodeKwargs(): """those values are classes like Meld, Tile etc. Convert to str(python2) or bytes(python3""" for keyword in ('tile', 'tiles', 'meld', 'melds'): if keyword in kwargs: kwargs[keyword] = str(kwargs[keyword]).encode() encodeKwargs() if about.__class__.__name__ == 'User': about = self.playerForUser(about) if not isinstance(receivers, list): receivers = list([receivers]) assert receivers, 'DeferredBlock.tell(%s) has no receiver' % command self.__enrichMessage(self.table.game, about, command, kwargs) aboutName = about.name if about else None if self.table.running and len(receivers) in [1, 4]: # messages are either identical for all 4 players # or identical for 3 players and different for 1 player. And # we want to capture each message exactly once. self.table.game.appendMove(about, command, kwargs) localDeferreds = [] for rec in self.__convertReceivers(receivers): isClient = rec.__class__.__name__.endswith('Client') if Debug.traffic and not isClient: message = u'-> {receiver:<15} about {about} {command}{kwargs}'.format( receiver=rec.name[:15], about=about, command=command, kwargs=Move.prettyKwargs(kwargs)) logDebug(message) if isClient: defer = Deferred() defer.addCallback(rec.remote_move, command, **kwargs) else: defer = self.table.server.callRemote( rec, 'move', aboutName, command.name, **kwargs) if defer: defer.command = command.name defer.notifying = 'notifying' in kwargs self.__addRequest(defer, rec, about) else: msg = m18nE('The game server lost connection to player %1') self.table.abort(msg, rec.name) if isClient: localDeferreds.append(defer) for defer in localDeferreds: defer.callback(aboutName) # callback needs an argument !
def test_scholars_mate(self): """Tests the scholars mate.""" pos = Position() self.assertTrue(pos.get_castling_right("q")) e4 = Move.from_uci('e2e4') self.assertTrue(e4 in pos.get_legal_moves()) pos.make_move(e4) self.assertTrue(pos.get_castling_right("q")) e5 = Move.from_uci('e7e5') self.assertTrue(e5 in pos.get_legal_moves()) self.assertFalse(e4 in pos.get_legal_moves()) pos.make_move(e5) self.assertTrue(pos.get_castling_right("q")) Qf3 = Move.from_uci('d1f3') self.assertTrue(Qf3 in pos.get_legal_moves()) pos.make_move(Qf3) self.assertTrue(pos.get_castling_right("q")) Nc6 = Move.from_uci('b8c6') self.assertTrue(Nc6 in pos.get_legal_moves()) pos.make_move(Nc6) self.assertTrue(pos.get_castling_right("q")) Bc4 = Move.from_uci('f1c4') self.assertTrue(Bc4 in pos.get_legal_moves()) pos.make_move(Bc4) self.assertTrue(pos.get_castling_right("q")) Rb8 = Move.from_uci('a8b8') self.assertTrue(Rb8 in pos.get_legal_moves()) pos.make_move(Rb8) self.assertFalse(pos.get_castling_right("q")) self.assertFalse(pos.is_check()) self.assertFalse(pos.is_checkmate()) self.assertFalse(pos.is_game_over()) self.assertFalse(pos.is_stalemate()) Qf7_mate = Move.from_uci('f3f7') self.assertTrue(Qf7_mate in pos.get_legal_moves()) pos.make_move(Qf7_mate) self.assertTrue(pos.is_check()) self.assertTrue(pos.is_checkmate()) self.assertTrue(pos.is_game_over()) self.assertFalse(pos.is_stalemate()) self.assertEqual(pos.fen, "1rbqkbnr/pppp1Qpp/2n5/4p3/2B1P3/8/PPPP1PPP/RNB1K1NR b KQk - 0 4")
def run(self): self.knight = Knight(self.start_position, self.verbosity.verbose_int) self.knight.add_to_board(self.board) if self.closed == True: self.end_positions = self.knight.get_possible_moves() count = 0 duration = 0 largest_tour = 0 start = time.time() complete = False while len(self.knight.visited_positions) < self.board.size and self._check_limit(count, duration): #garner stats largest_tour = self.verbosity.min_max(self, largest_tour) self.verbosity.potential_OBOB(self) self.verbosity.progress(count) if len(self.knight.visited_positions) < 4: largest_tour = len(self.knight.visited_positions) if self.time_limit != None and count%1000 == 0: duration = time.time()-start #find the next move possible_positions = self.knight.get_possible_moves() self.verbosity.possible_moves(self.knight.get_current_position(), possible_positions) if len(possible_positions) == 0: previous_position = self.knight.retrace() t = Trace(count, previous_position, retrace=True) count += 1 continue initial_moves = [] for position in possible_positions: #the position already has a weight when it's created if self._check_closed_tour(position, count) == True: #either the tour is complete, or the knight retraced and we return to the while loop complete = True break move = Move(position, self.knight.get_visited_positions()[:]) initial_moves.append(move) if len(initial_moves) != 0 and complete != True: best_move = Move.choose_best_move(initial_moves, self.end_positions) if not self.knight.set_position(best_move.get_position()): raise MoveError(best_move.get_position()) t = Trace(count, best_move.get_position(), retrace=False) count += 1 end_time = round(time.time() - start,3) return self.knight, count, self.board, end_time
def __init__(self, cfg): self.cfg = cfg self.webui = None self.gcode_queue = queue.Queue(100) self.gcode_file = None self.idling = True self.pause = False self.ev_buffer = asyncio.Event() self.pid = {} self.setpoint = {} self.setpoint_fail_time = {} self.tolerance = 3 self.current_status = None self.heater_enable_mcodes = True self.heater_disable_eof = True self.ignore_endstop = False self.prepare_endswitches() self.machine_ready = False self.move = Move(self.cfg, self) self.gcode = GCode(self.cfg) dim = self.cfg.settings["num_motors"] audiodev = self.cfg.settings["sound_device"] self.current_e = 0 self.extruder_safety_timeout = 300 # FIXME self.extruder_safety_time = time.time() + self.extruder_safety_timeout for n in ["ext", "bed"]: name = n.upper() o = GPOutput("heater_" + name) s = ScaledSensor(self.cfg, name) t = Thermistor100k(s) self.pid[n] = PidController(t, o, 0.3, 0.004, 0.5) self.launch_pid(n, 20) self.loop = asyncio.get_event_loop() self.sc = StepperCluster(audiodev, dim, self.cfg, self.esw) self.sc.connect_cmd_buffer(self.move.get_output_buffer()) self.loop.add_writer(self.sc.fileno(), self.handle_sc_write) asyncio.async(self.gcode_processor()) asyncio.async(self.coro_check_machine())
#TODO def clear_board(self): pass def reset(self): pass # do we want this public? def toggle_turn(self): """Toggles whos turn it is.""" if __name__ == '__main__': from notation import SanNotation f = Position() # print 11, f['a1'] # print 11, f[Square('a1')] m = Move.from_uci('b1c3') print SanNotation(f, m) f.make_move(m) print f f.make_move(Move.from_uci('c7c5')) print f print f["a7"] # # for move in f.get_legal_moves(): # move # print f.is_check() # print f.is_checkmate() # print f.is_stalemate() # print f.is_game_over()
class Printer(object): def __init__(self, cfg): self.cfg = cfg self.webui = None self.gcode_queue = queue.Queue(100) self.gcode_file = None self.idling = True self.pause = False self.ev_buffer = asyncio.Event() self.pid = {} self.setpoint = {} self.setpoint_fail_time = {} self.tolerance = 3 self.current_status = None self.heater_enable_mcodes = True self.heater_disable_eof = True self.ignore_endstop = False self.prepare_endswitches() self.machine_ready = False self.move = Move(self.cfg, self) self.gcode = GCode(self.cfg) dim = self.cfg.settings["num_motors"] audiodev = self.cfg.settings["sound_device"] self.current_e = 0 self.extruder_safety_timeout = 300 # FIXME self.extruder_safety_time = time.time() + self.extruder_safety_timeout for n in ["ext", "bed"]: name = n.upper() o = GPOutput("heater_" + name) s = ScaledSensor(self.cfg, name) t = Thermistor100k(s) self.pid[n] = PidController(t, o, 0.3, 0.004, 0.5) self.launch_pid(n, 20) self.loop = asyncio.get_event_loop() self.sc = StepperCluster(audiodev, dim, self.cfg, self.esw) self.sc.connect_cmd_buffer(self.move.get_output_buffer()) self.loop.add_writer(self.sc.fileno(), self.handle_sc_write) asyncio.async(self.gcode_processor()) asyncio.async(self.coro_check_machine()) def add_webui(self, webui): self.webui = webui def launch_pid(self, name, sp): self.pid[name].spawn() self.set_setpoint(name, sp) def shutdown(self): self.loop.stop() for name in self.pid: self.pid[name].set_setpoint(0) self.pid[name].shutdown() if self.sc is not None: self.sc.zero_output() self.sc.zero_output() self.sc.zero_output() self.sc.zero_output() self.sc.close() def set_setpoint(self, name, sp, report=True): if sp and sp < 10: sp = 10 elif name == "ext" and sp > 280: sp = 280 elif name == "bed" and sp > 120: sp = 120 print("Set", name, "temperature:", sp, "deg. C") self.setpoint[name] = sp self.setpoint_fail_time[name] = 0 self.pid[name].set_setpoint(sp) if report and self.webui: self.webui.queue_setpoint(name, sp) def set_zoffset(self, zoff): print("PRINTER: Set Z-offset:", zoff) self.gcode.set_zoffset(zoff) def get_temperature(self, name): return self.pid[name].get_input() def check_setpoint_immediate(self, name): temp = self.get_temperature(name) sp = self.setpoint[name] dt = abs(temp - sp) if sp < 30: # Heater off = ok dt = 0 ok = (dt < self.tolerance) return ok def check_setpoint(self, name): ok = self.check_setpoint_immediate(name) if ok: self.setpoint_fail_time[name] = 0 elif not self.setpoint_fail_time[name]: self.setpoint_fail_time[name] = time.time() + 10 return (ok or time.time() < self.setpoint_fail_time[name]) def check_setpoints(self): return self.check_setpoint("ext") and self.check_setpoint("bed") @asyncio.coroutine def coro_check_machine(self): self.tolerance = 3 wasok = True while True: res = self.check_setpoints() if res: # Hysteresis self.tolerance = 10 else: self.tolerance = 3 if not res and wasok: print("Printer not ready") elif res and not wasok: print("Printer ready") wasok = res self.machine_ready = res self.update_status() yield from asyncio.sleep(2.0) def set_position_mm(self, x, y, z, e): if self.webui: self.webui.queue_move(x, y, z, e) if e != self.current_e: self.current_e = e self.extruder_safety_time = time.time() + self.extruder_safety_timeout def printer_handler(self): ti = time.time() if self.extruder_safety_time < ti and "ext" in self.pid and \ self.setpoint["ext"] > 150: print("Extruder safety timeout hit. Lowering setpoint!") self.pid["ext"].set_setpoint(self.setpoint["ext"] - 50) @asyncio.coroutine def print_file(self, fname): if self.gcode_file is not None: return False print("Starting print:", fname) self.gcode_file = AIOFileReader(fname) asyncio.sleep(0) return True @asyncio.coroutine def wait_for_setpoints(self): while True: if self.check_setpoint_immediate("ext") and self.check_setpoint_immediate("bed"): break yield from asyncio.sleep(2) @asyncio.coroutine def start_auto(self, sp_ext, en_ext, sp_bed, en_bed, fname): if self.gcode_file is not None: return False if en_bed: # Heat up bed first self.set_setpoint("bed", sp_bed) while True: t_bed = self.get_temperature("bed") if t_bed > (sp_bed - 10): break yield from asyncio.sleep(5) if en_ext: # Bed near ok, so start hotend self.set_setpoint("ext", sp_ext) while True: t_ext = self.get_temperature("ext") if t_ext > (sp_ext - 10): break yield from asyncio.sleep(5) # Temperatures high enough to start homing self.reset() yield from self.execute_gcode("G28 X0 Y0") yield from self.wait_for_setpoints() yield from self.execute_gcode("G28 Z0") yield from self.print_file(fname) @asyncio.coroutine def execute_gcode(self, cmd): try: self.gcode_queue.put_nowait(cmd) except queue.Full: return False yield from asyncio.sleep(0) return True def _read_gcode(self): try: ret = self.gcode_queue.get_nowait() except queue.Empty: ret = "" return ret @asyncio.coroutine def _queue_move(self, obj): if self.move.buffer_ready(): self.move.process_command(obj) yield from asyncio.sleep(0) else: self.ev_buffer.clear() yield from self.ev_buffer.wait() self.move.process_command(obj) @asyncio.coroutine def gcode_processor(self): idle = True while True: if (self.gcode_file is None or self.pause) and self.gcode_queue.empty(): if not idle: yield from self._queue_move({"command":"eof"}) idle = True yield from asyncio.sleep(0.2) continue if self.gcode_file and not self.pause: if not self.machine_ready: yield from asyncio.sleep(0.2) continue l = self.gcode_file.readline() if l is None: # End of file self.gcode_file = None if self.heater_disable_eof: self.set_setpoint("ext", 0) self.set_setpoint("bed", 0) yield from self._queue_move({"command":"eof"}) self.move.reset() continue else: l = self._read_gcode() if len(l) == 0: # File reader stalled yield from self._queue_move({"command":"eof"}) self.move.reset() continue obj = self.gcode.process_line(l) if obj is None: continue # print("PRINTER GCODE:", repr(obj)) cmd = obj["command"] if cmd == "setpoint": if self.heater_enable_mcodes: self.set_setpoint(obj["type"], obj["value"]) if obj["wait"]: yield from self.wait_for_setpoints() elif cmd == "log": self.webui.queue_log(obj['type'], obj['value']) else: yield from self._queue_move(obj) idle = False self.set_idle(False) def _heater_status(self, name): ok = self.check_setpoint(name) sp = self.setpoint[name] temp = self.get_temperature(name) if sp == 0: return "off" if ok: return "ok" if sp > temp: return "low" if sp < temp: return "high" def update_status(self, force=False): if self.idling: motors = "idle" elif self.gcode_file is not None: motors = "processing" else: motors = "moving" ext = self._heater_status("ext") bed = self._heater_status("bed") status = (motors, ext, bed) if self.webui is None: return if self.current_status == status: return self.current_status = status self.webui.queue_status(*status) def set_idle(self, idle): if idle != self.idling: self.idling = idle self.update_status() def handle_sc_write(self): if not self.idling: ret = self.sc.pull_cmd_buffer() if ret == 1: self.set_idle(True) if self.move.buffer_ready() and not self.ev_buffer.is_set(): # print("PRINTER: cond notify") self.ev_buffer.set() else: self.sc.zero_output() def set_pause(self, pause): self.pause = pause print("Set pause:", repr(pause)) @asyncio.coroutine def stop(self): print("Stopping...") self.abort() yield from self.execute_gcode("G91") yield from self.execute_gcode("G1 Z5 F5000") yield from self.execute_gcode("G90") def abort(self): print("Aborting...") if self.gcode_file: self.gcode_file.close() self.gcode_file = None while not self.gcode_queue.empty(): self.gcode_queue.get_nowait() self.sc.cancel_destination() self.sc.flush_queue() # We may have interrupted a move. Make sure we know where we are... scpos = self.sc.get_position() gpos = self.move.reverse_transform(scpos) self.gcode.set_position(gpos) self.set_setpoint("ext", 0) self.set_setpoint("bed", 0) def reset(self): self.gcode.reset() self.sc.set_position([0, 0, 0, 0]) self.move.reset() self.set_position_mm(0, 0, 0, 0) def set_heater_enable_mcodes(self, value): self.heater_enable_mcodes = value def set_heater_disable_eof(self, value): self.heater_disable_eof = value def set_ignore_endstop(self, value): if self.ignore_endstop != value: self.ignore_endstop = value if value: self.disable_endswitches() else: self.enable_endswitches() def disable_endswitches(self): for e in self.esw: e.disable_exceptions() def enable_endswitches(self): for e in self.esw: e.enable_exceptions() def prepare_endswitches(self): self.esw = [] for axis in ["X", "Y", "Z"]: eswname = "endstop_" + axis self.esw.append(AsyncGPInput(eswname, self)) def gpio_event(self, name, val): print("GPIO Event from", name, "value:", val) self.sc.stop() self.sc.cancel_destination() self.sc.restart() def run(self): self.loop.run_forever()
if matches.group(2) and matches.group(2) != m.source.file: continue if matches.group(3) and matches.group(3) != str(m.source.rank): continue # Move matches. Assert it is not ambiguous. if source: raise MoveError( "Move is ambiguous: %s matches %s and %s." % san, source, m) source = m.source if not source: raise MoveError("No legal move matches %s." % san) return Move(source, target, matches.group(5) or None) if __name__ == '__main__': from position import Position from move import Move p = Position() m = Move.from_uci('b1c3') san = SanNotation(p, m) print san print SanNotation.to_move(p, san)
def __init__(self, moves = None): if moves is None: moves = [Move.generate_random_move() for i in xrange(NUMBER_OF_MOVES_PER_MOVE_LIST)] list.__init__(self, moves)
def setUp(self): piece = (0, 1, BLACK) direction = FORWARD_LEFT self.move = Move(piece, direction)
def get_pseudo_legal_moves(self, source=None): """:yield: Pseudo legal moves in the current position. :param source: The source square to limit moves or None for all possible moves. """ tomove = self.fen._to_move for x88 in [ x88 for x88 in Square._x88_squares.keys() if self._pieces[x88] and Piece.color(self._pieces[x88]) == tomove and (source is None or x88 == source._x88)]: piece = self._pieces[x88] klass = Piece.klass(piece) # pawn moves if klass == PAWN: single, double, capleft, capright = X88.PAWN_OFFSETS[tomove] # Single square ahead. Do not capture. offset = x88 + single if not self._pieces[offset]: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # Two squares ahead. Do not capture. if X88.is_secondrank(x88, tomove): offset = x88 + double if not self._pieces[offset]: yield Move.from_x88(x88, offset) # Pawn captures. for cap in [capleft, capright]: offset = x88 + cap if offset & X88.X88: continue target = self._pieces[offset] if target and Piece.color(target) != tomove: # Promotion. if X88.is_backrank(offset, tomove): for promote_to in Piece.promote_to: yield Move.from_x88(x88, offset, promote_to) else: yield Move.from_x88(x88, offset) # En-passant. elif not target and offset == self.fen._ep: yield Move.from_x88(target, self.fen._ep) #piece moves else: # for each a direction a piece moves in for offset in X88.PIECE_OFFSETS[Piece.klass(piece)]: t_x88 = x88 + offset # while we do not fall off the board while not t_x88 & 0x88: # if there was not piece to attack then yield a quiet move if not self._pieces[t_x88]: yield Move.from_x88(x88, t_x88) # do not break out # else there is a piece there else: # if we can attack generate a move if Piece.color(self._pieces[t_x88]) != tomove: yield Move.from_x88(x88, t_x88) # we hit something so break out break # Knight and king do not go multiple times in their direction. if klass in [KNIGHT, KING]: break # travel down the board in the direction t_x88 += offset # castling moves opponent = Piece.opposite_color(tomove) ok = True # get possible castling for the side to move for castle in [c for c in self.fen._castle_rights if Piece.color(c) == tomove]: (square, enum), _ = Piece.castle_squares[castle] king = Square(square) if Piece.klass(castle) == KING: direc = 1 else: direc = -1 # for offset in the squares the king will travel for offset in range(0, 3): s = Square.from_x88(king._x88 + (offset * direc)) # if we are not the king square and we are occuppied if offset and self._pieces[s._x88]: ok = False break # if we are trying to travel through check if self.is_attacked(opponent, s): ok = False break # kludge: we have to check occupancy for one more square on the queen side if direc == -1 and self._pieces[s._x88 - 1]: ok = False if ok: yield Move(king, s)