用于在矩阵中移动的逻辑不起作用
Logic used to move in a matrix isn't working
我正在 python 下棋。我正在努力移动棋盘上的一块,它由 8 个列表组成,如下所示:
[['___' for z in range(x)] for z in range(x)] # z is 8 in this instance
漂亮的印刷看起来像这样:
a b c d e f g h
8 ['___', '___', '___', '___', '___', '___', '___', '___'] 8
7 ['___', '___', '___', '___', '___', '___', '___', '___'] 7
6 ['___', '___', '___', '___', '___', '___', '___', '___'] 6
5 ['___', '___', '___', '___', '___', '___', '___', '___'] 5
4 ['___', '___', '___', '___', '___', '___', '___', '___'] 4
3 ['___', '___', '___', '___', '___', '___', '___', '___'] 3
2 ['___', '___', '___', '___', '___', '___', '___', '___'] 2
1 ['___', '___', '___', '___', '___', '___', '___', '___'] 1
a b c d e f g h
我在棋盘上放了一个棋子:
def create(self):
Config.board[self.y][self.x] = self.pieceid
然后看起来像这样:
a b c d e f g h
8 ['___', '___', '___', '___', '___', '___', '___', '___'] 8
7 ['___', '___', '___', '___', '___', '___', '___', '___'] 7
6 ['___', '___', '___', '___', '___', '___', '___', '___'] 6
5 ['___', '___', '___', '___', '___', '___', '___', '___'] 5
4 ['___', '___', '___', '___', '___', '___', '___', '___'] 4
3 ['___', '___', '___', '___', '___', '___', '___', '___'] 3
2 ['___', '___', '___', '___', '___', '___', '___', '___'] 2
1 ['___', '___', '___', '___', 'wN1', '___', '___', '___'] 1
a b c d e f g h
现在我检查骑士可能的走法(正在检查还没有实现):
def possible_moves(self):
pos_moves = []
# Up, Right (1 space, 2 spaces)
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x + 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
#Up, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x - 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
# Down, Right
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x + 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
#Down, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x - 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
# Right, Up
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
if Config.board[self.x + 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Right, Down
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x + 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
#Left, Up
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
print('Current: ', self.x, self.y)
print('New: ', self.x - 1, self.y - 2)
if Config.board[self.x - 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Left, Down
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x - 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
return pos_moves
如果走法在这些可能的走法之内,我就走:
def move(self, pos):
if pos in self.possible_moves():
Config.board[self.y][self.x] = '___'
self.x = Config.tile_convert(pos[0])
self.y = Config.tile_convert(pos[1], True)
Config.board[self.y][self.x] = self.pieceid
然而,由于某种原因,坐标变得不正常,并且棋子在应该能够移动时却无法移动:
knight1.move('f3')
time.sleep(2)
knight1.move('g5')
time.sleep(2)
knight1.move('h7')
time.sleep(2)
print(knight1.possible_moves()) # f8 should be in here
knight1.move('f8') # fails
通过打印坐标我推断出问题是它们没有正确更新。我的逻辑有什么问题?
这是我的tile_convert()
方法:
def tile_convert(cls, x, disp=False):
if not disp:
if isinstance(x, str):
return cls.letters.index(x)
else:
return cls.letters[x]
else:
return len(Config.board) - int(x)
如果你愿意,这是我的完整代码运行:
import time
class Config:
letters = tuple('abcdefghijklmnopqrstuvwxyz')
@classmethod
def new_board(cls, btype):
def size(x):
return [['___' for z in range(x)] for z in range(x)]
if 'custom' in btype.lower():
btype = int(btype.replace('custom', '').strip())
cls.board = size(btype)
elif btype.lower() == 'default':
cls.board = size(8)
elif btype.lower() == 'extended':
cls.board = size(10)
elif btype.lower() == 'small':
cls.board = size(5)
elif btype.lower() == 'max':
cls.board = size(25)
elif btype.lower() == 'min':
cls.board = size(1)
@classmethod
def print_board(cls):
def printl():
for x in range(len(cls.board)):
print(' '*6 + f'{cls.letters[x]}', end='')
print('\n')
printl()
for x in range(len(cls.board)):
print(f'{len(cls.board)-x} {cls.board[x]} {len(Config.board)-x}\n')
printl()
print('\n'*4)
@classmethod
def tile_convert(cls, x, disp=False):
if not disp:
if isinstance(x, str):
return cls.letters.index(x)
else:
return cls.letters[x]
else:
return len(Config.board) - int(x)
class ChessPiece:
def __init__(self, pos, color, num, piece):
self.x = int(Config.tile_convert(pos[0]))
self.y = len(Config.board) - int(pos[1])
self.color = color
self.pieceid = num
self.set_id()
self.create()
def __str__(self):
return self.__class__.__name__
def set_id(self):
if self.__class__.__name__ != "Knight":
self.pieceid = f'{piece[0]}{self.pieceid}'
else:
self.pieceid = f'N{self.pieceid}'
if self.color is not None:
if self.color.lower() in ('black', 'white', 'b', 'w'):
self.pieceid = self.color.lower()[0] + self.pieceid
if self.color.lower() == 'b':
self.color = 'black'
elif self.color.lower() == 'w':
self.color = 'white'
else:
self.color = None
print("Invalid color input. Color not set.")
self.set_id()
else:
self.pieceid = '_' + self.pieceid
def create(self):
Config.board[self.y][self.x] = self.pieceid
def move(self, pos):
if pos in self.possible_moves():
Config.board[self.y][self.x] = '___'
self.x = Config.tile_convert(pos[0])
self.y = Config.tile_convert(pos[1], True)
Config.board[self.y][self.x] = self.pieceid
Config.print_board()
else:
print(f'Unable to move to {pos}')
def get_info(self):
print(f'{self.__class__.__name__}:\n')
print('ID: ', self.pieceid)
print('Position: ', Config.tile_convert(self.x), Config.tile_convert(self.y, True), sep='')
print('Color: ', self.color)
class Knight(ChessPiece):
def __init__(self, pos, color=None, num=''):
ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)
def possible_moves(self):
pos_moves = []
# Up, Right (1 space, 2 spaces)
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x + 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
#Up, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x - 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
# Down, Right
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x + 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
#Down, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x - 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
# Right, Up
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
if Config.board[self.x + 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Right, Down
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x + 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
#Left, Up
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
print('Current: ', self.x, self.y)
print('New: ', self.x - 1, self.y - 2)
if Config.board[self.x - 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Left, Down
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x - 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
return pos_moves
Config.new_board('default')
Config.print_board()
knight1 = Knight('e1', color='w', num=1)
Config.print_board()
# knight1.get_info()
# print('\n\n\nPossible Moves:', knight1.possible_moves())
knight1.move('f3')
time.sleep(2)
knight1.move('g5')
time.sleep(2)
knight1.move('h7')
time.sleep(2)
print(knight1.possible_moves())
knight1.move('f8')
您在 possible_moves
中的索引检查是错误的,因为列表索引从 0
到 len(Config.board)-1
,而不是从 1
到 len(Config.board)
。
您可以通过使用循环尝试所有不同的动作并设置变量来大大简化代码,这样您就不必不断重复长表达式。
def possible_moves(self):
pos_moves = []
boardlen = len(Config.board)
for xoff, yoff in [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]:
newx = self.x + xoff
newy = self.y + yoff
if 0 <= newx < boardlen and 0 <= newy < boardlen and Config.board[newy][newx] == '___':
pos_moves.append(f'{Config.tile_convert(newx)}{Config.tile_convert(newy, True)}')
return pos_moves
我正在 python 下棋。我正在努力移动棋盘上的一块,它由 8 个列表组成,如下所示:
[['___' for z in range(x)] for z in range(x)] # z is 8 in this instance
漂亮的印刷看起来像这样:
a b c d e f g h
8 ['___', '___', '___', '___', '___', '___', '___', '___'] 8
7 ['___', '___', '___', '___', '___', '___', '___', '___'] 7
6 ['___', '___', '___', '___', '___', '___', '___', '___'] 6
5 ['___', '___', '___', '___', '___', '___', '___', '___'] 5
4 ['___', '___', '___', '___', '___', '___', '___', '___'] 4
3 ['___', '___', '___', '___', '___', '___', '___', '___'] 3
2 ['___', '___', '___', '___', '___', '___', '___', '___'] 2
1 ['___', '___', '___', '___', '___', '___', '___', '___'] 1
a b c d e f g h
我在棋盘上放了一个棋子:
def create(self):
Config.board[self.y][self.x] = self.pieceid
然后看起来像这样:
a b c d e f g h
8 ['___', '___', '___', '___', '___', '___', '___', '___'] 8
7 ['___', '___', '___', '___', '___', '___', '___', '___'] 7
6 ['___', '___', '___', '___', '___', '___', '___', '___'] 6
5 ['___', '___', '___', '___', '___', '___', '___', '___'] 5
4 ['___', '___', '___', '___', '___', '___', '___', '___'] 4
3 ['___', '___', '___', '___', '___', '___', '___', '___'] 3
2 ['___', '___', '___', '___', '___', '___', '___', '___'] 2
1 ['___', '___', '___', '___', 'wN1', '___', '___', '___'] 1
a b c d e f g h
现在我检查骑士可能的走法(正在检查还没有实现):
def possible_moves(self):
pos_moves = []
# Up, Right (1 space, 2 spaces)
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x + 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
#Up, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x - 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
# Down, Right
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x + 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
#Down, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x - 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
# Right, Up
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
if Config.board[self.x + 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Right, Down
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x + 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
#Left, Up
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
print('Current: ', self.x, self.y)
print('New: ', self.x - 1, self.y - 2)
if Config.board[self.x - 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Left, Down
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x - 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
return pos_moves
如果走法在这些可能的走法之内,我就走:
def move(self, pos):
if pos in self.possible_moves():
Config.board[self.y][self.x] = '___'
self.x = Config.tile_convert(pos[0])
self.y = Config.tile_convert(pos[1], True)
Config.board[self.y][self.x] = self.pieceid
然而,由于某种原因,坐标变得不正常,并且棋子在应该能够移动时却无法移动:
knight1.move('f3')
time.sleep(2)
knight1.move('g5')
time.sleep(2)
knight1.move('h7')
time.sleep(2)
print(knight1.possible_moves()) # f8 should be in here
knight1.move('f8') # fails
通过打印坐标我推断出问题是它们没有正确更新。我的逻辑有什么问题?
这是我的tile_convert()
方法:
def tile_convert(cls, x, disp=False):
if not disp:
if isinstance(x, str):
return cls.letters.index(x)
else:
return cls.letters[x]
else:
return len(Config.board) - int(x)
如果你愿意,这是我的完整代码运行:
import time
class Config:
letters = tuple('abcdefghijklmnopqrstuvwxyz')
@classmethod
def new_board(cls, btype):
def size(x):
return [['___' for z in range(x)] for z in range(x)]
if 'custom' in btype.lower():
btype = int(btype.replace('custom', '').strip())
cls.board = size(btype)
elif btype.lower() == 'default':
cls.board = size(8)
elif btype.lower() == 'extended':
cls.board = size(10)
elif btype.lower() == 'small':
cls.board = size(5)
elif btype.lower() == 'max':
cls.board = size(25)
elif btype.lower() == 'min':
cls.board = size(1)
@classmethod
def print_board(cls):
def printl():
for x in range(len(cls.board)):
print(' '*6 + f'{cls.letters[x]}', end='')
print('\n')
printl()
for x in range(len(cls.board)):
print(f'{len(cls.board)-x} {cls.board[x]} {len(Config.board)-x}\n')
printl()
print('\n'*4)
@classmethod
def tile_convert(cls, x, disp=False):
if not disp:
if isinstance(x, str):
return cls.letters.index(x)
else:
return cls.letters[x]
else:
return len(Config.board) - int(x)
class ChessPiece:
def __init__(self, pos, color, num, piece):
self.x = int(Config.tile_convert(pos[0]))
self.y = len(Config.board) - int(pos[1])
self.color = color
self.pieceid = num
self.set_id()
self.create()
def __str__(self):
return self.__class__.__name__
def set_id(self):
if self.__class__.__name__ != "Knight":
self.pieceid = f'{piece[0]}{self.pieceid}'
else:
self.pieceid = f'N{self.pieceid}'
if self.color is not None:
if self.color.lower() in ('black', 'white', 'b', 'w'):
self.pieceid = self.color.lower()[0] + self.pieceid
if self.color.lower() == 'b':
self.color = 'black'
elif self.color.lower() == 'w':
self.color = 'white'
else:
self.color = None
print("Invalid color input. Color not set.")
self.set_id()
else:
self.pieceid = '_' + self.pieceid
def create(self):
Config.board[self.y][self.x] = self.pieceid
def move(self, pos):
if pos in self.possible_moves():
Config.board[self.y][self.x] = '___'
self.x = Config.tile_convert(pos[0])
self.y = Config.tile_convert(pos[1], True)
Config.board[self.y][self.x] = self.pieceid
Config.print_board()
else:
print(f'Unable to move to {pos}')
def get_info(self):
print(f'{self.__class__.__name__}:\n')
print('ID: ', self.pieceid)
print('Position: ', Config.tile_convert(self.x), Config.tile_convert(self.y, True), sep='')
print('Color: ', self.color)
class Knight(ChessPiece):
def __init__(self, pos, color=None, num=''):
ChessPiece.__init__(self, pos, color, num, self.__class__.__name__)
def possible_moves(self):
pos_moves = []
# Up, Right (1 space, 2 spaces)
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x + 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
#Up, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y - 1 <= len(Config.board):
if Config.board[self.x - 2][self.y - 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y - 1, True)}')
except IndexError: pass
# Down, Right
try:
if 1 <= self.x + 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x + 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
#Down, Left
try:
if 1 <= self.x - 2 <= len(Config.board) and 1 <= self.y + 1 <= len(Config.board):
if Config.board[self.x - 2][self.y + 1] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 2)}{Config.tile_convert(self.y + 1, True)}')
except IndexError: pass
# Right, Up
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
if Config.board[self.x + 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Right, Down
try:
if 1 <= self.x + 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x + 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x + 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
#Left, Up
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y - 2 <= len(Config.board):
print('Current: ', self.x, self.y)
print('New: ', self.x - 1, self.y - 2)
if Config.board[self.x - 1][self.y - 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y - 2, True)}')
except IndexError: pass
# Left, Down
try:
if 1 <= self.x - 1 <= len(Config.board) and 1 <= self.y + 2 <= len(Config.board):
if Config.board[self.x - 1][self.y + 2] == '___':
pos_moves.append(f'{Config.tile_convert(self.x - 1)}{Config.tile_convert(self.y + 2, True)}')
except IndexError: pass
return pos_moves
Config.new_board('default')
Config.print_board()
knight1 = Knight('e1', color='w', num=1)
Config.print_board()
# knight1.get_info()
# print('\n\n\nPossible Moves:', knight1.possible_moves())
knight1.move('f3')
time.sleep(2)
knight1.move('g5')
time.sleep(2)
knight1.move('h7')
time.sleep(2)
print(knight1.possible_moves())
knight1.move('f8')
您在 possible_moves
中的索引检查是错误的,因为列表索引从 0
到 len(Config.board)-1
,而不是从 1
到 len(Config.board)
。
您可以通过使用循环尝试所有不同的动作并设置变量来大大简化代码,这样您就不必不断重复长表达式。
def possible_moves(self):
pos_moves = []
boardlen = len(Config.board)
for xoff, yoff in [(1, 2), (-1, 2), (1, -2), (-1, -2), (2, 1), (-2, 1), (2, -1), (-2, -1)]:
newx = self.x + xoff
newy = self.y + yoff
if 0 <= newx < boardlen and 0 <= newy < boardlen and Config.board[newy][newx] == '___':
pos_moves.append(f'{Config.tile_convert(newx)}{Config.tile_convert(newy, True)}')
return pos_moves