首页 > 解决方案 > 尽管存在,但无法从列表中删除元素 - Reversi

问题描述

我正在尝试用 Python 编写一个简单的黑白棋游戏。

在我的代码中有两个主要列表:

takered - 包含红色玩家占据的位置

takeblue - 包含蓝色玩家占据的位置

在玩家的每一次移动之后,我都会更新这些列表以包含每个玩家的更新位置

这是我的问题:

当我使用输入运行代码时:

R

02

23

我收到一条错误消息,指出在列表中找不到最后一个索引,因此无法删除它。

到目前为止,我尝试的是使用 for 循环中的缩进,因为其余代码对我来说似乎是正确的。

我的代码:

import numpy as np
import math


def isfull(board):
    for i in range(0, 4):
        for j in range(0, 4):
            if board[i][j] == 'e':
                return False
    return True


def main():
    board = np.empty([4, 4], dtype=str)
    for t in range(0, 4):
        for n in range(0, 4):
            board[t, n] = 'e'
    board[1, 1] = 'R'
    board[1, 2] = 'B'
    board[2, 1] = 'B'
    board[2, 2] = 'R'
    takenblue = [[1, 2], [2, 1]]
    takenred = [[1, 1], [2, 2]]
    toswitch1=[]
    toswitch2=[]
    print(board)
    player = str(input('input player R or B: '))
    otherplayer = 'e'
    while isfull(board) == False:
        if player == 'R':
            otherplayer = 'B'
        else:
            otherplayer = 'R'
        loc = list(input(player + 'loc '))
        for i in range(0, 2):
            loc[i] = int(loc[i], base=10)
        if player == 'R':
            if board[loc[0], loc[1]]=='e':
                for j in takenred:
                    if (loc[0] == j[0] or loc[1] == j[1] or abs(loc[1] - j[1]) == abs(loc[0] - j[0]) or abs(
                            loc[1] - j[1]) == abs(j[0] - loc[0])):
                        if (board[math.floor((loc[0] + j[0]) // 2), math.floor((loc[1] + j[1]) // 2)] == otherplayer):
                            board[math.floor((loc[0] + j[0]) // 2), math.floor((loc[1] + j[1]) // 2)] = player
                            board[loc[0], loc[1]] = player
                            toswitch1 = [math.floor((loc[0] + j[0]) // 2), math.floor((loc[1] + j[1]) // 2)]
                            print(takenred)
                            print(toswitch1)
                takenblue.remove(toswitch1)
                takenred.append(toswitch1)
                takenred.append(loc)
            print('R: ', takenred)
            print('B: ', takenblue)

        if player == 'B':
            if board[loc[0], loc[1]]=='e':
                for t in takenblue:
                    if (loc[0] == t[0] or loc[1] == t[1] or abs(loc[1] - t[1]) == abs(loc[0] - t[0]) or abs(
                            loc[1] - t[1]) == abs(t[0] - loc[0])):
                        if(board[math.floor((loc[0] + t[0]) // 2), math.floor((loc[1] + t[1]) // 2)] == otherplayer):
                            board[math.floor((loc[0] + t[0]) // 2), math.floor((loc[1] + t[1]) // 2)] = player
                            board[loc[0], loc[1]] = player
                            toswitch2 = [math.floor((loc[0] + t[0]) // 2), math.floor((loc[1] + t[1]) // 2)]
                            print(toswitch2)
                    takenred.remove(toswitch2)
                    takenblue.append(toswitch2)
                    takenblue.append(loc)
            print('B: ', takenblue)
            print('R: ', takenred)
        if player == 'B':
            player = 'R'
            otherplayer = 'B'
        else:
            player = 'B'
            otherplayer = 'R'
        print(board)


if __name__ == '__main__':
    main()

欢迎任何帮助!

终端:

[['e' 'e' 'e' 'e']
 ['e' 'R' 'B' 'e']
 ['e' 'B' 'R' 'e']
 ['e' 'e' 'e' 'e']]
input player R or B: R
Rloc 02
[1, 2]
R:  [[1, 1], [2, 2], [1, 2], [0, 2]]
B:  [[2, 1]]
[['e' 'e' 'R' 'e']
 ['e' 'R' 'R' 'e']
 ['e' 'B' 'R' 'e']
 ['e' 'e' 'e' 'e']]
Bloc 23
[2, 2]
Traceback (most recent call last):
  File "x:/xxx/xxx/xxx/xxx.py", line 78, in <module>
    main()
  File "x:/x/xxx/xxx/xxx.py", line 63, in main
    takenred.remove(toswitch2)
ValueError: list.remove(x): x not in list

Process finished with exit code 1

标签: pythonreversiothello

解决方案


我发现了几个问题:

  • 您尝试修改列表takenred以及takenblue您正在迭代的列表。这是一个经典的错误,也是你错误的原因。如果您打算删除或添加元素,您应该迭代列表的副本。
  • 对玩家的removeappend指令似乎没有足够的缩进。它们应该在每个玩家的最后一个 if 语句中完成,即当一个位置应该从一个玩家翻转到另一个时。
  • 要翻转的位置的检测是错误的。有时您会错过位置,例如当有 2 个位置需要翻转时。

这是脚本的修改版本。我将不同的部分拆分为专用功能,以使其更易于理解。要翻转的位置的错误检测在coords_to_flip功能中。此函数应返回要翻转的坐标列表。

import numpy as np
import math
import itertools


def isfull(board):
    for (i, j) in itertools.product(range(4), repeat=2):
        if board[i][j] == 'e':
            return False
    return True


def canflip(played_row, played_col, current_row, current_col):
    return played_row == current_row \
        or played_col == current_col \
        or abs(played_col - current_col) == abs(played_row - current_row) \
        or abs(played_col - current_col) == abs(current_row - played_row)


def coords_to_flip(played_row, played_col, current_row, current_col):
    return math.floor((played_row + current_row) // 2), math.floor((played_col + current_col) // 2)


def main():
    board = np.empty([4, 4], dtype=str)
    for (t, n) in itertools.product(range(4), repeat=2):
        board[t, n] = 'e'
    board[1, 1] = 'R'
    board[1, 2] = 'B'
    board[2, 1] = 'B'
    board[2, 2] = 'R'
    takenblue = [[1, 2], [2, 1]]
    takenred = [[1, 1], [2, 2]]
    toswitch1 = []
    toswitch2 = []
    player = ''
    print(board)
    while player.upper() not in ('R', 'B'):
        player = str(input('Starting player R or B: '))
    player = player.upper()
    otherplayer = 'e'
    while not isfull(board):
        if player == 'R':
            otherplayer = 'B'
        else:
            otherplayer = 'R'
        loc = []
        while len(loc) != 2:
            loc = list(input(player + 'loc (2 digits)'))
        loc = [int(val) for val in loc]
        print(loc)
        row, col = loc
        if board[row, col] != 'e':
            print('Coord (%d,%d) not possible, already taken by %s' % (row, col, board[row, col]))
            player, otherplayer = otherplayer, player
            continue

        print('row:', row)
        print('col:', col)

        if player == 'R':
            for redrow, redcol in takenred[::]:
                if canflip(row, col, redrow, redcol):
                    taken_row, taken_col = coords_to_flip(row, col, redrow, redcol)
                    if (board[taken_row, taken_col] == otherplayer):
                        board[taken_row, taken_col] = player
                        board[row, col] = player
                        toswitch1 = [taken_row, taken_col]
                        print('takenblue:', takenblue)
                        print('toswitch1:', toswitch1)
                        takenblue.remove(toswitch1)
                        takenred.append(toswitch1)
                        takenred.append(loc)
            print('R: ', takenred)
            print('B: ', takenblue)

        if player == 'B':
            for bluerow, bluecol in takenblue[::]:
                if canflip(row, col, bluerow, bluecol):
                    taken_row, taken_col = coords_to_flip(row, col, bluerow, bluecol)
                    if(board[taken_row, taken_col] == otherplayer):
                        board[taken_row, taken_col] = player
                        board[row, col] = player
                        toswitch2 = [taken_row, taken_col]
                        print('takenred:', takenred)
                        print('toswitch2:', toswitch2)
                        takenred.remove(toswitch2)
                        takenblue.append(toswitch2)
                        takenblue.append(loc)
            print('B: ', takenblue)
            print('R: ', takenred)

        player, otherplayer = otherplayer, player
        print(board)


if __name__ == '__main__':
    main()

推荐阅读