Python 用于在矩阵中移动的逻辑是';行不通
我正在用python构建国际象棋。我正在努力在黑板上移动一块,它由8个列表组成,如下所示:Python 用于在矩阵中移动的逻辑是';行不通,python,python-3.x,matrix,chess,Python,Python 3.x,Matrix,Chess,我正在用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 ['___', '___', '___', '___', '___', '___', '___', '___'
[['___' 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
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 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 ['___', '___', '___', '___', '___', '___', '___', '___'] 1
a b c d e f g h
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
现在我检查骑士可能的动作(正在检查的动作尚未执行):
然而,由于某种原因,坐标变得不正常,当它应该能够:
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\u 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')
导入时间
类配置:
字母=元组('abcdefghijklmnopqrstuvxyz')
@类方法
def新板(cls,B类型):
def尺寸(x):
返回范围(x)中的z的['''.\']
如果btype.lower()中的“自定义”:
btype=int(btype.replace('custom','').strip())
cls.board=尺寸(B类型)
elif btype.lower()==“默认值”:
电路板=尺寸(8)
elif btype.lower()==“扩展”:
电路板=尺寸(10)
elif btype.lower()==“小”:
电路板=尺寸(5)
elif btype.lower()==“max”:
电路板=尺寸(25)
elif btype.lower()==“min”:
电路板=尺寸(1)
@类方法
def打印板(cls):
def printl():
对于范围内的x(透镜(电路板)):
打印(''*6+f'{cls.letters[x]}',end='')
打印(“\n”)
printl()
对于范围内的x(透镜(电路板)):
打印(f'{len(cls.board)-x}{cls.board[x]}{len(Config.board)-x}\n')
printl()
打印('\n'*4)
@类方法
def tile_转换(cls,x,disp=False):
如果不是disp:
如果存在(x,str):
返回cls.字母索引(x)
其他:
返回cls.信函[x]
其他:
返回len(Config.board)-int(x)
类棋子:
定义初始(自身、位置、颜色、数量、工件):
self.x=int(Config.tile\u convert(位置[0]))
self.y=len(配置板)-int(位置[1])
self.color=颜色
self.pieceid=num
self.set_id()
self.create()
定义(自我):
返回self.\u类\u.\u名称__
def set_id(自身):
如果self.\uuuuu class.\uuuuu name.\uuuuuu!=“骑士”:
self.pieceid=f'{piece[0]}{self.pieceid}'
其他:
self.pieceid=f'N{self.pieceid}'
如果self.color不是无:
如果self.color.lower()在('black','white','b','w')中:
self.pieceid=self.color.lower()[0]+self.pieceid
如果self.color.lower()
self.color='black'
elif self.color.lower()
self.color='white'
其他:
self.color=None
打印(“无效的颜色输入。未设置颜色”)
self.set_id()
其他:
self.pieceid='.'+self.pieceid
def创建(自我):
Config.board[self.y][self.x]=self.pieceid
def移动(自身,位置):
如果位置在self.mable_moves()中:
配置板[self.y][self.x]='\uuuuuu'
self.x=Config.tile\u convert(位置[0])
self.y=Config.tile\u convert(位置[1],真)
Config.board[self.y][self.x]=self.pieceid
Config.print_board()
其他:
打印(f'无法移动到{pos}')
def获取信息(自我):
打印(f'{self.\uuuuuuu类\uuuuuuu名称\uuuuuuuu}:\n')
打印('ID:',self.pieceid)
打印('Position:',Config.tile\u convert(self.x),Config.tile\u convert(self.y,True),sep='')
打印('Color:',self.Color)
骑士等级(棋子):
定义初始化(self,pos,color=None,num=''):
棋子。初始(self,pos,color,num,self.\uuuuu类\uuuuuu.\uuuuu名称)
def可能的_移动(自):
位置移动=[]
#向上,右侧(1个空格,2个空格)
尝试:
如果1您的索引在中检查可能的移动是错误的,因为列表索引从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
def可能的移动(自):
位置移动=[]
boardlen=len(配置板)
对于xoff,yoff在[(1,2),(-1,2),(1,-2),(-1,-2),(2,1),(-2,1),(2,-1),(-2,-1)]中:
newx=self.x+xoff
newy=self.y+yoff
如果0,为什么在设置self.y
时使用disp=True
?该参数的含义是什么?我不理解tile\u convert
的逻辑。使用disp=True
转换将显示的y编号转换为内部编号,因为内部编号上升,而显示编号下降。在本例中,我正在输入一个显示y值。在任何情况下,y值似乎有效,x值似乎无效。当您使用if
语句检查索引时,是否真的需要try/except indexer
?这就是为什么代码在没有try
的情况下中断,因为if
测试是错误的。