예제 #1
0
 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))
예제 #2
0
 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
예제 #3
0
 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))
예제 #4
0
 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)
예제 #5
0
 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
예제 #6
0
    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)
예제 #7
0
 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
예제 #8
0
 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