0

I have the following code

def poss_move(val, board, n):
  # val is a value between 0 and n*n-1
  for i in range(n*n):
    if i == val:
      board[i // n][i % n] = 'Q'
      continue
    if i % n == val % n or i // n == val // n: #mark row and column with a dot
      board[i//n][i%n] = '.'

    #mark diagonals with a dot
    if i % (n + 1) == val % (n + 1) and abs(i % n - val % n) == abs(i // n - val // n): 
      board[i//n][i%n] = '.'
    if i % (n - 1) == val % (n - 1) and abs(i % n - val % n) == abs(i // n - val // n):
      board[i//n][i%n] = '.'
  return board

def next_available_position(val, board, n):
  if val < 0 or val >= n * n:
    return -1
  for i in range(val, n * n):
    if board[i//n][i%n] == '0':
      return i
  return -1

def sol(val, board, bt, result, n):
  board[val // n][val % n] == 'Q'
  print(f'AW1 val: {val}, bt: {bt}')
  board = poss_move(val=val, board=board, n=n)
  print(f'AW2 val: {val}, bt: {bt}')
  nap = next_available_position(val=val, board=board, n=n)
  while nap >= 0:
    board_tmp = [i for i in board]
    result, board_tmp = sol(val=nap, board=board, bt=board_tmp, result=result, n=n)
    board = [i for i in board_tmp]
    board[nap // n][nap % n] = '.'
    nap = next_available_position(val=nap, board=board, n=n)
  result.append([board,2])
  return result, bt

def run():
  m = 3 #board size = n x n
  board_ini = [['0' for x in range(m)] for y in range(m)] #initialize board with '0' in every row and col
  result = []
  board_t = []
  result, board_t = sol(val=0, board=board_ini, bt=board_t, result=result, n=m)

run()

I am getting the following output:

AW1 val: 0, bt: []

AW2 val: 0, bt: []

AW1 val: 5, bt: [['Q', '.', '.'], ['.', '.', '0'], ['.', '0', '.']]

AW2 val: 5, bt: [['Q', '.', '.'], ['.', '.', 'Q'], ['.', '.', '.']]

My question is: why is the value of bt variable changing from:

AW1 val: 5, bt: [['Q', '.', '.'], ['.', '.', '0'], ['.', '0', '.']]

to

AW2 val: 5, bt: [['Q', '.', '.'], ['.', '.', 'Q'], ['.', '.', '.']]

I am getting nuts, thought it was something about using global variables so I rewrote all the code to avoid them as far as I understand bt is a local variable and I am doing nothing to it between the 2 prints and its value is changing.

  • `board_tmp = [i for i in board]` is only a shallow copy, so it still contains the same lists as `board` contains. – kaya3 Sep 16 '22 at 01:48
  • in `result, board_tmp = sol(val=nap, board=board, bt=board_tmp, result=result, n=n)` both, `board` and `bt` have same elements being themselves lists. Changing `board` items has changed therefore also `bt` items even if there were no changes done to `bt`. The lists board and bt were different, BUT their elements were the same. You can proove it by inserting checks on id() of their elements which will be the same for board and bt. – Claudio Sep 16 '22 at 02:49
  • if you insert: to ```def sol(val, board, bt, result, n): if bt: for i in range(len(board)): if id(board[i]) == id(bt[i]): print("BINGO")``` and run your code, you will see "BINGO" on output. Evidence that board and bt have the same content. – Claudio Sep 16 '22 at 02:52
  • import the copy module and do this: ```while nap >= 0: board_tmp = copy.deepcopy(board)``` instead of `[i for i in board]` to achieve separation between board and board_tmp which becomes board and bt which finally makes you then wonder how it comes that changes to board are mirrored in bt what made you going nuts. – Claudio Sep 16 '22 at 02:57

0 Answers0