-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Description
当前逻辑,士,象在同一纵列时,某些中文着法无法形成有效的移动。例子如下:
>>> 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
Labels
No labels