0

I'm trying to write a simple Reversi game in Python.

In my code have two main lists:

takenred - which contains the places occupied by the red player

takenblue - which contains the places occupied by the blue player

After every move of a player I update those lists to contain the updated locations of each player

Here is my problem:

When I run the code with the input:

R

02

23

I get an error message that says that the last index wasn't found in the list and thus it can't be removed..

What I tried so far was to play with the indents in the for loops because the rest of the code seems right to me.

My code:

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()

Any help would be welcomed!

Terminal:

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

1 Answers1

1

There are several problems I identified:

  • You try to modify the lists takenred and takenblue on which you are iterating on. This a classical mistake and the reason of your error. You should iterate on a copy of the lists if you intend to remove or add elements.
  • The remove and append instruction for the players seem not indented enough. They should be done within the last if statement for each player, i.e. when a location should flip from a player to another.
  • The detection of the locations to flip is buggy. Sometimes you miss locations, for instance when there are 2 locations to flip.

Here is a modified version of the script. I split the different parts into dedicated functions to make it easier to understand. The buggy detection of locations to flip is in the coords_to_flip function. This function should return a list of 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()
Frodon
  • 3,684
  • 1
  • 16
  • 33
  • After further inspection of my code and the code that was suggested to me, I come to a conclusion that my code works just fine and has no major mistakes in it, although two small changes are needed for the code to run as expected: 1. in the end for loop in each player's section a [ : : ] must be added, I was not aware of this method but thanks to @Frodon I now know that.. 2. The add and remove commands from the list by the ending of each player section in my code should be indented into the for loop and if condition for each removal should be added. – Python_Programmer Dec 30 '20 at 19:31