Lab 3 Part 2: User input

Lab 3 Part 2: User input

At the moment, your evolver for lists does not use any human input. This section adds your input to the game — first by toggling each light individually and then to toggle a light and all of its neighbors simultaneously:the full game of Lights-On!

Evolving lists with user input

The approach to evolving lists thus far is, well, a bit too random. This section will enable the user to guide the process by choosing an element from the list.

Copy these evolve and setNewElement functions at the bottom of the code you have so far, so that they will run in place of your current evolve and setNewElement functions.

def evolve(aList):
    """ evolve takes in a list of integers, aList,
          and returns a new list of integers
          considered to be the "next generation"
    """
    n = len(aList)  # n now holds the size of the list aList
    x = int(input("Enter an index to change: "))  # Get numeric input from user
    return [setNewElement(aList, i, x) for i in range(n)]

def setNewElement(aList, i, x = 0):
    """ setNewElement returns the NEW list's ith element
          input aList: any list of integers
          input i: the index of the new element to return
          input x: the user's chosen column
    """
    if i == x:  # if it's the user's chosen column,
        return choice([0, 1])    # return a random 0 or 1
    else:                        # otherwise,
        return aList[i]          # return the original
 

Try running runGenerations([0, 0, 0, 0, 0, 0]). Now,the execution should pause and wait for you to enter the index of one of the list items. Note that the item you choose does not simply change from 0 to 1 or from 1 to 0 — the call to choice randomizes the result, so it may take more than one try to change it.

Toggling the lights

Change the above setNewElement function so that when you choose a light, that light toggles from 0 to 1 or from 1 to 0, as appropriate.

Hint: if the old value of the light is aList[i], what will you get if you subtract that value from 1?

Be sure to test your code by running

runGenerations([0, 0, 0, 0, 0, 0])

At this point, it’s true that the “game” is not difficult to win…On to the official Lights-On game:

Toggling neighboring lights, too

Finishing the game Now, you are finally ready to implement the full 1D version of “Lights-On”. Modify your code so that the game play is as it should be (i.e., when you toggle one light, the lights next to it also toggle). Remember, lights do not “wraparound”. That is, the lights at the edge of the board have only one neighbor.

The function runGenerations(aList) should play the game from the initial starting list aList as usual.

Suggestions / Hints:

  • Only the function setNewElement needs to change to implement this game. You will need to compare the value of i, which is checked for each light in the row, and x, which is the user’s chosen index.
  • You want not only the light equal to your choice x to change, but you want the neighbors of x to change, too. But, remember that the list does not “wrap” around!
  • The user might make silly choices for index values, such as a negative number. Make sure that you do not allow invalid indices to alter any “light”. (i.e. you should not make any change if setNewElement is passed an index that is less than 0 or greater than the length of aList.)

It is still straightforward to win the game if you start from a known board state, for example:

runGenerations([0, 0, 0, 0, 0, 0])

Testing:

When developing a program, it’s important to devise good tests to check the behavior of the program. So far, you have been supplied with the tests. It’s time for you to start devising your own good tests. For this part of the lab, what would be good tests of

runGenerations([0, 0, 0, 0, 0, 0])

? That is, what sequence of inputs would convince you that the program is working properly? Explore until you understand the pattern of inputs that thoroughly tests the function. Describe your “good” tests and the expected results in a docstring right after the usual docstring in your runGenerations() function.

Putting it all together, and then some…

Starting from a random binary list

Create a function named

randomBinaryList(n)

that takes in a nonnegative integer, n, and returns a list of length n in which each element is equally likely to be a 0 or a 1. Raw recursion is one way to handle this; list comprehensions are a better way. This randomBinaryList function makes it easy to start a new, random game.

Once you finish this function, try it out by running

runGenerations(randomBinaryList(9))

to be sure it works.

Warning: One thing that won’t work is the following:

return [choice([0, 1])] * n   # won't work!!

The reason is that the above line only returns a list of n zeros or n ones. Again, raw recursion or a list comprehension will do the trick…

Call your instructor or TA and

?Get checked 2?

[Run and play the game by hand. Make sure the program toggles the lights to left and right. Make sure they have a docstring describing their “good” tests”.]

Let the computer play!?

The computer is bored. It wants to play too. So, don’t be selfish — write anew version of evolve so that the computer gets to play! That is, have the computer choose (randomly) one of the possible indices. It’s easiest to do this at precisely the place in the code where you(a human) were providing keyboard input. That’s it— once you make the change from a human choice of a square to a computer-made, random choice, the machine should play the game (making random selections) until it’s solved. Warning:one-sixth of all binary lists are dead ends! That is, there is no combination of toggled lights that will end up at the all-ones list. So,letting the computer play for a long time on one of those dead ends will result in Python running out of memory.

Congratulations!You’ve completed this week’s CSCI 203 Lab.

Be sure to submit your hw3pr1.py file in the usual way. You’re welcome to end lab here — or, if you’d like, you might try to use the graphics in the next part.

Call your instructor or TA and

?Get checked 3?

[Run and watch computer play.]

Optional – adding colored lights -continue the lab with part 3, using the same hw3pr1.py file.

OR, go back to the main HW3 page and continue with the rest of the homework.