1 Overview For this assignment you are to write a Python program which allows a user to play against the computer in a two-player game which is a version of Nim. For this game we start with two piles of n chips (for n > 1) and the players alternate turns. A player can take as many chips as she wants from one of the piles on her turn (but must take at least one chip). The player to take the last chip is the winner. Your program will first ask the user how many chips to start with and then let the human player move first. Once the human makes a play then your program will display the chips in each pile. The computer will announce its move and then you will display the number of chips in each pile prior to the human choosing again. Repeat this process until the game is over. The computer, who is player two, should follow the optimal strategy. The optimal strategy for player two is to take the same number of chips player one takes, but from the opposite pile that player one used on the last turn (i.e. if player 1 picks 3 chips from pile 2, then the computer will take 3 chips from pile 1). The computer will always be player two for this program. If the computer follows the optimal strategy then it will win every time. While that may be frustrating to players, it will be very gratifying to you since you wrote the code to make it happen! :) 2 Details No single part of this program is very difficult. The hard part is keeping track of the variables and making sure the functions do exactly what they're supposed to do - no more, no less. I provided a shell of the program called hw2 skeleton.py for this assignment. You must complete this program and not alter what is written in the main part of the program. You will just add code to functions. Note that each function receives variables as needed. You MUST NOT reference variables inside of a function unless you pass those variables to the function explicitly. Each function has a docstring and some test cases in it so you can see what it should output. I've shown some sample output at the end of this document to help you further understand how the program works. I also recorded a short video showing the program behavior. It is in the same folder as example programs and is named walkthrough_hw2.mp4 3 Error Handling You do not have to worry about the user typing in input of the wrong data type. Specif- ically, if you ask the user to choose pile 1 or pile 2 and they type "one" you don't have to worry about handling that. But you do have to deal with the user typing 3 for the pile for instance. Similarly, if you ask the user how many chips he'd like to take from a chosen pile and he enters more chips than are in the pile, or zero chips, then you have to re-prompt until he follows the rules. See the sample output below for further clarification. 4 Advice This may seem like a big program! But you need to realize that none of the individual functions are more complex that what you wrote in Lab 3 or Homework 1. The way to attack this project is in stages. Start by reading through the functions one by one and understanding what they are sup- posed to do. Then read through the main program and try to understand how the functions are being called and how the return values from the functions are helpful. This may seem like a waste of time but I guarantee you that the effort you put in up front will pay off in the long run. Ask me or your TA for help if you have any questions whatsoever in this stage. We'll talk about how to do doctests in class so you can tell when you write your functions if they are working in the few cases provided. Developing code is like writing a really good essay. You don't just sit down and write the essay from start to end. Instead, you think about things at a high level first (what arguments are you going to make, what's the supporting evidence and so on) and then you make an outline of the essay before you start digging into the details. Writing code is similar - you start by thinking about the design and how the program will work in general terms. I've given you a lot of structure here but there is still a lot to get your head around. Once you start writing functions you should be testing them as you go. I'll show you how to run doctests in class but the tests listed there are not exhaustive. Once you have a few functions then you have to ensure that everything is working together in harmony as you intended. And then once things are working you polish them up at the end by running through your test cases to verify correctness and prettiness and repeat until you're happy with the result. 5 Submission Please submit your completed python program to Canvas entitled lastname_firstname_hw2.py by the due date. 6 Sample Output Welcome to the game of chips. I know you know the rules so let's go. How many chips to start with in each pile? 11 Here are the piles Pile 1: 00000 00000 O Pile 2: 00000 00000 O It is your turn. Which pile would you like to take from? (1 or 2) 1 How many would you like from pile1? 12 Pile 1 does not have that many chips. Try again. Which pile would you like to take from? (1 or 2) 1 How many would you like from pile1? 4 That was a legal move. Thank you. Here are the piles Pile 1: 00000 00 Pile 2: 00000000000 Now it is my turn. I'm thinking I, the champion chips computer, will take 4 chips from pile 2 Here are the piles Pile 1: 00000 00 Pile 2: 00000 00 It is your turn. Which pile would you like to take from? (1 or 2) 3 3 is not a valid pile number Which pile would you like to take from? (1 or 2) 1 How many would you like from pile1? 0 You must take at least one chip. Which pile would you like to take from? (1 or 2) 1 How many would you like from pile1? 6 That was a legal move. Thank you. Here are the piles Pile 1: 0 Pile 2: 00000 00 Now it is my turn. I'm thinking I, the champion chips computer, will take 6 chips from pile 2 Here are the piles Pile 1: 0 Pile 2: 0 It is your turn. Which pile would you like to take from? (1 or 2) 2 How many would you like from pile2? 1 That was a legal move. Thank you. Here are the piles Pile 1: 0 Pile 2: Now it is my turn. I'm thinking .. I, the champion chips computer, will take 1 chips from pile 1 The game is over and I won because I took the last chip. Thanks for playing. You wanna wager next time? # Homework 2 # This program lets a human play against the computer in the game of chips # import time import doctest #### ####### # def initializeGame() : void -> int PRE: Nothing is passed to this function POST: A valid number of chips is returned II III chips = 0 while chips void Two non-negative integers are passed to the function POST: The piles of chips are displayed to the screen where each chip is an "o". A space inserted after every fifth chip to improve readability. Further, a newline is inserted after both piles are displayed >>> displayPiles (3,6) Pile 1: 000 Pile 2: 00000 O
>>> displayPiles (6,4) Pile 1: 00000 O Pile 2: 0000 int, int PRE: Two integers, both non-negative, at least one larger than zero, are passed in. The first number represents the count of chips in pile 1, the second number is the count of chips in pile 2 POST: Two values are returned: (1) the pile that the human player has chosen (e.g. 1 or 2) which I'll call humanPile. (2) the number of chips that the human would like to take from his chosen pile which I'll call humanChips. The function ensures that the move is valid but does not update the number of chips in either pile. To be precise, upon returning the function ensures that there are at least humanChips chips left in humanPile. HR # end of getHumanMove ###* # def updatePiles (pileChosen, chipsChosen, plchips, p2chips): int, int, int, int -> int, int PRE: Four parameters are passed to this function. (1) the pile chosen from, (2) the number of chips chosen from that pile, (3) the current count of chips in pile 1, (4) the current count of chips in pile 2. POST: Two values are returned, namely, the count of chips in each pile after the move. >>> updatePiles(1,3,5,6) (2, 6) >>> updatePiles (2,3,5,6) (5, 3) #end of updatePiles ######### ####### ######## # def computerMove (humanPile, humanChips): int, int -> int, int PRE: Two parameters are passed to this function: (1) the pile the human chose from on her last turn, (2) the number of chips the human took on her last turn POST: The pile chosen by the computer, and the number of chips chosen by the computer are returned >>> computerMove (1,3) (2, 3) >>> computerMove (2,4) (1, 4) # #end of computerMove ########### #MAIN PROGRAM # ##if name = "__main__": ## doctest.testmod() print ("Welcome to the game of chips. I know you know the rules so let's go. ") numChips = initializeGame() pilelchips = numChips pile2chips numchips gameOver = False while not gameOver: print("Here are the piles ") displayPiles(pilelchips, pile2chips ) print ("It is your turn.") humanPile, humanChips = getHumanMove (pilelchips, pile2chips ) pilelchips, pile2chips = updatePiles (humanPile, humanChips, pilelchips, pile2chips) print("Here are the piles") displayPiles (pilelchips, pile2chips) computerPile, computerChips = computerMove (humanPile, humanChips ) pilelchips, pile2chips updatePiles (computerPile, computerChips, pilelchips, pile2chips ) print ("Now it is my turn. I'm thinking time. sleep(3) #This is just to slow things down a little. print ("I, the champion chips computer, will take", computerChips, "chips from pile", computer Pile) if pilelchips == 0 and pile2chips == 0: gameover = True print ("The game is over and I won because I took the last chip.") print ("Thanks for playing. You wanna wager next time?")