def generateNewPuzzle(numSlides): # From a starting configuration, make numSlides number of moves (and # animate these moves). sequence =  board = getStartingBoard() drawBoard(board, '') pygame.display.update() pygame.time.wait(500) # pause 500 milliseconds for effect lastMove = None for i in range(numSlides): move = getRandomMove(board, lastMove) slideAnimation(board, move, 'Generating new puzzle...', animationSpeed=int(TILESIZE / 3)) makeMove(board, move) sequence.append(move) lastMove = move return (board, sequence)
generateNewPuzzle() function will be called at the start of each new game. It will create a new board data structure by calling
getStartingBoard() and then randomly scramble it. The first few lines of
generateNewPuzzle() get the board and then draw it to the screen (freezing for half a second to let the player see the fresh board for a moment).
numSlides parameter will show tell the function how many of these random moves to make. The code for doing a random move is the
getRandomMove() call on line 11  to get the move itself, then call
slideAnimation() to perform the animation on the screen. Because doing the slide animation does not actually update the board data structure, we update the board by calling
makeMove() on line 13 .
We need to keep track of each of the random moves that was made so that the player can click the "Solve" button later and have the program undo all these random moves. (The "Being Smart By Using Stupid Code" section talks about why and how we do this.) So the move is appended to the list of moves in sequence on line 14 .
Then we store the random move in a variable called
lastMove which will be passed to
getRandomMove() on the next iteration. This prevents the next random move from undoing the random move we just performed.
All of this needs to happen
numSlides number of times, so we put lines 11  to 15  inside a
for loop. When the board is done being scrambled, then we return the board data structure and also the list of the random moves made on it.