1

I'm trying to solve the Lights Out puzzle. I use a two-dimensional list of Boolean values, such as [[True, True, True], [True, True, True], [True, True, True]], to represent the condition of a light. I want to reverse the boolean value at a given location such as (1,1), and I code as:

class LightsOutPuzzle(object):

    def __init__(self, board):
        self.board = board

    def get_board(self):
        return self.board

    def perform_move(self, row, col):      
        self.board[row][col] = not self.board[row][col]
        print(self.board)
        return LightsOutPuzzle(self.board)

I call perform_move(1,1) on

[[False, False, False], [False, False, False], [False, False, False]]

but the result is:

[[False, True, False], [False, True, False], [False, True, False]]

which makes me confused. Could you please tell me what's wrong with it? What is the right way to do this task? Thanks a lot for helping!

I'm using this function to generate new boards:

def create_puzzle(rows, cols):
    c = []
    r = []
    for x in range(cols):
        c.append(False)
    for y in range(rows):
        r.append(c)
    return LightsOutPuzzle(r)

Does it cause the problem?

Thank you sooooo much for your replies!!! QWQ

Akito L
  • 13
  • 4
  • You initializrd board to have the same single list as all rows. Probably something like `board = [[] * 3]` instead of `board = [[], [], []]` – Reut Sharabani Sep 17 '18 at 04:20
  • 1
    This is likely what's going on: https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly – NPE Sep 17 '18 at 04:20
  • What was the expected result? And you you know that Python starts at 0? – Prayson W. Daniel Sep 17 '18 at 04:21
  • In other words, the problem is not in the code that you posted but in the code that you used to initialize the original board. You should initialize it with `LightsOutPuzzle([[True]*3 for _ in range(3)])`. – DYZ Sep 17 '18 at 04:21
  • Thank you soooo much guys! Now the problem is solved and I really didn't expect the cause!! I've learned from it! Thx again!!! – Akito L Sep 17 '18 at 05:06

2 Answers2

1

The probe statement i saw in your code is in function def create_puzzle(rows, cols)

def create_puzzle(rows, cols):

c = []
r = []

for x in range(cols):  
    c.append(False)    #Statement1

for y in range(rows):  
    r.append(c)        #Statement2

return LightsOutPuzzle(r)

Statement1 : Appends elements to list #[False, False, False] Suppose id(c) is 0x1000

Statement2 : This statement will append Same List (c) to your rowList result (reference id) : [0x1000, 0x1000, 0x1000]

So your row will have reference to same List, This is the reason when you make change in one of the columns List it is reflecting in all other columns Lists as well

Change your create_puzzle

def create_puzzle(rows, cols):

     myBoard = [[False]*cols for i in range(rows)]
     return LightsOutPuzzle(myBoard )
Ashish
  • 623
  • 4
  • 10
Shivam Seth
  • 677
  • 1
  • 8
  • 21
0

you can do it inside the init method itself then change the perform_move method, try this

class LightsOutPuzzle(object):

def __init__(self, board):
    self.board = board
    board = [not i for i in board]
    print(board)

def get_board(self):
    return self.board

def perform_move(self, row, col):
    self.board[row][col] = not self.board[row][col]
    print(self.board)
    return LightsOutPuzzle(self.board)

def main():
    LightsOutPuzzle([False, False, False])


if __name__ == '__main__':
    main()