def create_drop_move(self, side: Side, ktype: KomaType, end_sq: Square) -> Move: """Creates a drop Move. Move need not necessarily be legal or even valid. """ return Move(start_sq=Square.HAND, end_sq=end_sq, koma=Koma.make(side, ktype))
def visit_move(self, reader: Reader, line: str) -> None: game = reader.game match = re.search(KIF_MOVELINE_REGEX, line) if match is None: raise TypeError("Match object is None, cannot identify move") else: movenum = match.group("movenum") movestr = match.group("move") movetime = match.group("movetime") totaltime = match.group("totaltime") move: Move if movestr in GameTermination: move = TerminationMove(GameTermination(movestr)) else: m = re.search(KIF_MOVE_REGEX, movestr) if m is None: raise ValueError( "KIF move regex failed to match movestr: " + movestr) dest = m.group("sq_dest") komastr = m.group("koma") drop_prom = m.group("drop_prom") sq_origin = m.group("sq_origin") # Find destination square if dest == "同 ": end_sq = game.curr_node.move.end_sq captured = game.position.get_koma(sq=end_sq) else: col = int(dest[0]) row = int(KanjiNumber[dest[1]]) end_sq = Square.from_cr(col, row) captured = game.position.get_koma(sq=end_sq) ktype: KomaType if komastr[0] == "成": ktype = KTYPE_FROM_KANJI[komastr[1]] ktype = ktype.promote() else: try: ktype = KTYPE_FROM_KANJI[komastr] except KeyError as e: #TODO: handle gracefully and skip game raise KeyError("Unknown koma encountered: " + komastr) from e # Find origin square if drop_prom != "打": start_sq = Square.from_coord(int(sq_origin)) else: if ktype not in HAND_TYPES: raise ValueError("Koma " + str(ktype) + " cannot be dropped") start_sq = Square.HAND # Not NONE, not on board # Identify if promotion is_promotion = (drop_prom == "成") # Construct Move side = Side.SENTE if (int(movenum) % 2 == 1) else Side.GOTE koma = Koma.make(side, ktype) move = Move(start_sq, end_sq, is_promotion, koma, captured) game.add_move(move) return
def create_move(self, start_sq: Square, end_sq: Square, is_promotion: bool = False) -> Move: """Creates a move from two squares. Move need not necessarily be legal or even valid. """ return Move(start_sq=start_sq, end_sq=end_sq, is_promotion=is_promotion, koma=self.get_koma(start_sq), captured=self.get_koma(end_sq))
def test_make_move(self): self.position.set_koma(Koma.vGI, Square.b76) self.position.set_koma(Koma.UM, Square.b87) move = Move(start_sq=Square.b76, end_sq=Square.b87, is_promotion=True, koma=Koma.vGI, captured=Koma.UM) self.position.make_move(move) self.assertEqual(self.position.get_koma(sq=Square.b87), Koma.vNG) self.assertEqual( self.position.get_hand_of_side(Side.GOTE).mochigoma_dict[Koma.KA], 1)
def receive_promotion(self, caller: MoveInputHandler, is_promotion: Optional[bool], sq: Square, ktype: KomaType) -> None: if is_promotion is None: # This means promotion choice is cancelled caller._set_state("ready") return else: # Promotion choice is made, yes or no mv = Move(start_sq=caller.focused_sq, end_sq=sq, koma=Koma.make(caller.position.turn, ktype), captured=caller.position.get_koma(sq), is_promotion=is_promotion) caller._send_move(mv) caller._set_state("ready") return
def write_move(self, move: Move, pos: Position, is_same: bool = False) -> str: if move.is_null(): raise ValueError("Attempting to write notation for a NullMove") if isinstance(move, TerminationMove): return self.write_termination_move(move) res = [] for builder in self.move_format: if isinstance(builder, DestinationNotationBuilder): if is_same: res.append(self.write_same_destination(move.end_sq)) else: res.append(self.write_destination(move.end_sq)) continue res.append(builder.build(move, pos, self)) return "".join(res)
def unmake_move(self, move: Move) -> None: """Unplays/retracts a move from the board. """ if move.is_pass(): self.movenum -= 1 return elif move.is_drop: self.set_koma(Koma.NONE, move.end_sq) self.inc_hand_koma(move.side, KomaType.get(move.koma)) self.turn = self.turn.switch() self.movenum -= 1 return else: if move.captured != Koma.NONE: self.dec_hand_koma(move.side, KomaType.get(move.captured).unpromote()) self.set_koma(move.captured, move.end_sq) self.set_koma(move.koma, move.start_sq) self.turn = self.turn.switch() self.movenum -= 1 return
def make_move(self, move: Move) -> None: """Makes a move on the board. """ if move.is_pass(): # to account for game terminations or other passing moves self.movenum += 1 return elif move.is_drop: self.dec_hand_koma(move.side, KomaType.get(move.koma)) self.set_koma(move.koma, move.end_sq) self.turn = self.turn.switch() self.movenum += 1 return else: self.set_koma(Koma.NONE, move.start_sq) if move.captured != Koma.NONE: self.inc_hand_koma(move.side, KomaType.get(move.captured).unpromote()) self.set_koma( move.koma.promote() if move.is_promotion else move.koma, move.end_sq) self.turn = self.turn.switch() self.movenum += 1 return