Skip to content

完善士、象在特殊条件下的中文着法走子 #12

@mooncaker816

Description

@mooncaker816

当前逻辑,士,象在同一纵列时,某些中文着法无法形成有效的移动。例子如下:

>>> b = ChessBoard("3a5/9/3a5/9/9/9/9/9/9/9 b")
>>> b.print_board()

9 ┌───┬───┬───士──┬───┬───┬───┬───┐
  │   │   │   │ \│/ │   │   │   │
8 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │   │ /│\ │   │   │   │
7 ├───┼───┼───士──┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
6 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │  │  │   │   │   │   │   │   │
5 ├───┴───┴───┴───┴───┴───┴───┴───┤
  │                              │
4 ├───┬───┬───┬───┬───┬───┬───┬───┤
  │  │  │   │   │   │  │  │  │
3 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
2 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │   │   │ \│/ │  │  │  │
1 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │   │ /│\ │  │   │   │
0 └───┴───┴───┴───┴───┴───┴───┴───┘

  a   b   c   d   e   f   g   h   i
  0   1   2   3   4   5   6   7   8
>>> b.move_text("士4进5")
>>> b.print_board()

9 ┌───┬───┬───士──┬───┬───┬───┬───┐
  │   │   │   │ \│/ │   │   │   │
8 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │   │ /│\ │   │   │   │
7 ├───┼───┼───士──┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
6 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │  │  │   │   │   │   │   │   │
5 ├───┴───┴───┴───┴───┴───┴───┴───┤
  │                              │
4 ├───┬───┬───┬───┬───┬───┬───┬───┤
  │  │  │   │   │   │  │  │  │
3 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
2 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │   │   │ \│/ │  │  │  │
1 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │   │ /│\ │  │   │   │
0 └───┴───┴───┴───┴───┴───┴───┴───┘

  a   b   c   d   e   f   g   h   i
  0   1   2   3   4   5   6   7   8

看了下代码,Move.from_text这里有点问题,循环首先处理的是下面那个士,但是由于Move.text_move_to_std_move并没有检查非法移动的逻辑,会返回一个潜在的非法目标位置,紧接着就跳出循环返回了,这就导致了真正需要处理的士没有得到处理。

# move.py

    @staticmethod
    def from_text(board, move_str):
...
...
...
            #同一行选出来多个,这种情况下, 只有士象是可以多个子尝试移动而不用标明前后的
            if (len(poss) > 1) and (man_kind not in ['a', 'b']):
                return None

            for pos in poss:
                move = Move.text_move_to_std_move(man_kind, move_player, pos,
                                                  move_str[2:])
                if move:
                    return (pos, move)

我在想这里是否可以把所有的潜在移动坐标都返回出去,然后在board.move_text中依次处理这些点位,由于board.move 中会检查移动的有效性,这就保证了在中文着法无误(唯一性)的前提下,只要board.move能返回Move,就一定形成了有效的移动。

# board.py

    def move_text(self, move_str):
        ret = Move.from_text(self, move_str)
        if not ret:
            return None
这里依次循环处理返回的潜在点位,如果能成功move,就说明当前这个点位就是正确的移动点位,如果都失败了,那么就返回无效移动
++++++++++++++++++
        move_from, move_to = ret    
        return self.move(move_from, move_to)
++++++++++++++++++

大概改了下,感觉可行,但是毕竟没有仔细查看过完整的代码,不知道有没有别的负面影响。

# board.py
    def move_text(self, move_str):
        ret = Move.from_text(self, move_str)
        if not ret:
            return None
+++++++++++++++++++++++++++++++
        # move_from, move_to = ret    
        # return self.move(move_from, move_to)
        for r in ret:
            move_from, move_to = r
            move = self.move(move_from, move_to)
            if move is not None:
                return move

        return None
+++++++++++++++++++++++++++++++
# move.py

            #同一行选出来多个,这种情况下, 只有士象是可以多个子尝试移动而不用标明前后的
            if (len(poss) > 1) and (man_kind not in ['a', 'b']):
                return None
+++++++++++++++++++++++++++++++
            moves = []
            for pos in poss:
                move = Move.text_move_to_std_move(man_kind, move_player, pos,
                                                  move_str[2:])
                if move:
                    # return (pos, move)
                    moves.append((pos, move))

            return moves
            # return None
+++++++++++++++++++++++++++++++
        else:
            #多选一移动
            if move_str[0] in ['前','中','后']:
                poss = board.get_fenchs(fench)
                if move_player == BLACK:
                    poss.reverse()
                
                move_indexs = {"前": -1, "中": 1, "后": 0}
                pos = poss[move_indexs[move_str[0]]]
   
                #print(man_kind, move_player, pos, move_str[2:])
                move = Move.text_move_to_std_move(man_kind, move_player, pos,
                                                  move_str[2:])
                if move:
+++++++++++++++++++++++++++++++
                    # return (pos, move)
                    return [(pos, move)]
+++++++++++++++++++++++++++++++
                else:
                    return None
            #多兵选一移动
            else:
                pass
>>> b.move_text("士4进5")
<cchess.move.Move object at 0x0000019C6DF1D7F0>
>>> b.print_board()

9 ┌───┬───┬───┬───┬───┬───┬───┬───┐
  │   │   │   │ \│/ │   │   │   │
8 ├───┼───┼───┼───士──┼───┼───┼───┤
  │   │  │   │ /│\ │   │   │   │
7 ├───┼───┼───士──┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
6 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │  │  │   │   │   │   │   │   │
5 ├───┴───┴───┴───┴───┴───┴───┴───┤
  │                              │
4 ├───┬───┬───┬───┬───┬───┬───┬───┤
  │  │  │   │   │   │  │  │  │
3 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │  │  │   │   │   │   │
2 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │   │   │ \│/ │  │  │  │
1 ├───┼───┼───┼───┼───┼───┼───┼───┤
  │   │  │   │ /│\ │  │   │   │
0 └───┴───┴───┴───┴───┴───┴───┴───┘

  a   b   c   d   e   f   g   h   i
  0   1   2   3   4   5   6   7   8

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions