0

I'm creating a simple Minimax algorithm for playing tic-tac-toe. A function make_move() takes a board and x/y coordinates and returns the board with the given move made. I use this function both to make moves and create a list of child boards to choose the best next move.

My problem: Any time I call the function, it changes the global board variable to reflect the move as well. I don't use board = make_move() and have also tried using the function with a copy of board instead, to no effect. Here is a simpler version of my code:

board = [ [0 for x in range(3)] for y in range(3) ] # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

def make_move(state, x, y): # return board with given move made
  state[y][x] = 1

  return state

print(make_move(board, 1, 1)) # prints [[0, 0, 0], [0, 1, 0], [0, 0, 0]]

print(board) # also prints [[0, 0, 0], [0, 1, 0], [0, 0, 0]]

My question: since I don't specify board = make_move(board, ...), which would obviously change the original board variable, what am I doing wrong here which causes board to change?

Passing board[:] instead of board to make_move(), which should otherwise create a seperate copy, does not work.

I hope this was descriptive enough; it's my first question :)

lixitrixi
  • 11
  • 4
  • 2
    Consider this. In the top line, you create one list object that contains three other list objects. In your entire program, those are the ONLY four list objects that ever exist. Those lists go by different names, `state` and `board` both refer to that original list object. – Tim Roberts Aug 09 '21 at 00:26
  • 1
    The global variable `board` is not changed, it is still referring to the exact same object, the on you passed to `make_move`, and mutate inside. – juanpa.arrivillaga Aug 09 '21 at 00:54

1 Answers1

1

[:] is creating so called shallow copy- a new object with references copied from the old one. To create a deep copy use copy.deepcopy():

import copy
board = [ [0 for x in range(3)] for y in range(3) ] # [[0, 0, 0], [0, 0, 0], [0, 0, 0]]

def make_move(state, x, y): # return board with given move made
  state_copy = copy.deepcopy(state)
  state_copy[y][x] = 1

  return state_copy
Hubert Bossy
  • 140
  • 1
  • 11