0

I was writing a program to play checkers. In it the original board state is stored in a variable called Board. It's only used 3 times,

  1. Initialize it
  2. Pass a copy of it into a function: Eval(1, Board.copy(), 7)
  3. To print it.

However, every time the Board variable changes. How to debug this issue? and why does this happen?

Code:

Board = [
['_', 'b', '_', 'b', '_', 'b', '_', 'b'],
['b', '_', 'b', '_', 'b', '_', 'b', '_'],
['_', 'b', '_', 'b', '_', 'b', '_', 'b'],
['_', '_', '_', '_', '_', '_', '_', '_'],
['_', '_', '_', '_', '_', '_', '_', '_'],
['w', '_', 'w', '_', 'w', '_', 'w', '_'],
['_', 'w', '_', 'w', '_', 'w', '_', 'w'],
['w', '_', 'w', '_', 'w', '_', 'w', '_']
]

def cheq(x, y, board):
    if x < 0 or x > 7 or y < 0 or y > 7:
        return "None"
    return board[y][x]

def calc(player: bool, board):
    board = board[:]
    play = 'wW' if player else 'bB'
    oppo = 'bB' if player else 'wW'
    moves = []
    for y in range(8):
        for x in range(8):
            if cheq(x, y, board) in play:
                if cheq(x + 1, y + 1, board) in oppo and cheq(x + 2, y + 2, board) == '_':
                    moves.append([[x, y], [x + 2, y + 2], [[x + 1, y + 1]]])
                if cheq(x - 1, y + 1, board) in oppo and cheq(x - 2, y + 2, board) == '_':
                    moves.append([[x, y], [x - 2, y + 2], [[x - 1, y + 1]]])
                if cheq(x + 1, y - 1, board) in oppo and cheq(x + 2, y - 2, board) == '_':
                    moves.append([[x, y], [x + 2, y - 2], [[x + 1, y - 1]]])
                if cheq(x - 1, y - 1, board) in oppo and cheq(x - 2, y - 2, board) == '_':
                    moves.append([[x, y], [x - 2, y - 2], [[x - 1, y - 1]]])

    if moves == []:
        if player:
            for y in range(8):
                for x in range(8):
                    if cheq(x, y, board) in play:
                        if cheq(x + 1, y - 1, board) == '_':
                            moves.append([[x, y], [x + 1, y - 1], []])
                        if cheq(x - 1, y - 1, board) == '_':
                            moves.append([[x, y], [x - 1, y - 1], []])
        else:
            for y in range(8):
                for x in range(8):
                    if cheq(x, y, board) in play:
                        if cheq(x + 1, y + 1, board) == '_':
                            moves.append([[x, y], [x + 1, y + 1], []])
                        if cheq(x - 1, y + 1, board) == '_':
                            moves.append([[x, y], [x - 1, y + 1], []])
    
    return moves

snaps = []

def Eval(color:bool, playB, depth=3):
    for playM in calc(color, playB):
        oppoB =  move(playB, playM)
        for oppoM in calc(not color, oppoB):
            lastB = move(oppoB, oppoM)
            snaps.append([playB, lastB, playM, oppoM])
            if depth > 0:
                Eval(color, lastB, depth-1)

def move(boardC, move):
    boardC = boardC[:]
    org, new, cap = move
    boardC[new[1]][new[0]] = boardC[org[1]][org[0]]
    boardC[org[1]][org[0]] = '_'
    for x, y in cap:
        boardC[y][x] = '_'

    #board[0] = ["W" if i == "w" else i for i in board[0]]
    #board[7] = ["B" if i == "b" else i for i in board[1]]

    return boardC

from timeit import timeit


#print(timeit(lambda: Eval(1, Board.copy(), 7), number=1))
Eval(1, Board.copy(), 7)
print(len(snaps))
print(Board)
  • 2
    `board[:]` and `Board.copy()` both make a *shallow* copy, a new list of references to the *same* rows as the original. You want a *deep* copy (or at least, a deeper copy than what you currently have). – chepner Mar 19 '23 at 16:52

0 Answers0