Python 用于在矩阵中移动的逻辑是';行不通

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 ['___', '___', '___', '___', '___', '___', '___', '___'

我正在用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
      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
测试是错误的。