用于在矩阵中移动的逻辑不起作用

问题描述 投票:0回答:1

我在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

现在我检查Knight的可能移动(被检查尚未实现):

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')
python python-3.x matrix chess
1个回答
2
投票

您在possible_moves中的索引检查是错误的,因为列表索引从0len(Config.board)-1,而不是从1len(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

© www.soinside.com 2019 - 2024. All rights reserved.