CSC 15 Assignment: Horse Race Part I due before next week's lab FIRST OF ALL: Learn How to KILL ZOMBIES! The animation framework that I created for you, which allows you to create animation inside a while loop, uses multiple, synchronized threads. This means that sometimes the program doesn't stop when it's supposed to end, even if you try closing the window or hit Cntrl-C. In these situations, do the following: At the terminal prompt where you ran the program, type Cntrl-Z. You'll see a message such as [5]+ Stopped python2 bounce.py This program is NOT DEAD. It's a ZOMBIE! A zombie is a program that should have died but didn't. You need to kill it with the following command: kill -9 %5 The "5" needs to match the number in the message above. Don't leave zombies around. While one or two zombies may not be a big deal, if there are too many zombies they will overhelm your operating system's resources and your computer will die a grisly death. At the command prompt, type the word "jobs". This shows all the programs at their current status that were started from the terminal. You can kill them with the same command. Zombies can also be created when you try to terminate a program before it's supposed to end. kill and jobs are common linux commands that should also work in MacOS and Msys in Windows. ------------- Part I 1. Download the skeleton program 'hrskeleton.py' AND the 'racer.gif' animated gif, and make sure they're in the same directory. Study the 'mydraw' function towards the end of the skeleton program. The current program demonstrates all the graphical elements you will need to complete the assignment, including the drawing of lines, text and advancing the animated gif through its frames. In particular, the following code should be used BEFORE the animation loop begins to load and prepare any animated gifs to be used in the program. The gif must be in the same directory as the program. # sets up loading and preparation of animated gif: gif1 = GdkPixbuf.PixbufAnimation.new_from_file("racer.gif") animator = gif1.get_iter() # call animator.advance() to goto next frame animframe = animator.get_pixbuf() # one animation frame gifwidth = animframe.get_width() # width,height dimensions of gif: gifheight = animframe.get_height() Now, inside the main animation loop, advance the animated gif to its next frame and extract the frame with: animator.advance() # go to next frame of the gif animframe = animator.get_pixbuf() # get animation frame from gif You only need to do this once for all the horses in the race. Then to display a horse at coordinates x,y, do: Gdk.cairo_set_source_pixbuf(brush,animframe,x,y) # place x,y here brush.paint() # paints picture at coordinates x,y At the very end of the main animation loop (outer loop), call updateDisplay() # refresh screen image - must call at end of loop time.sleep(0.05) # delay by 50ms 2. Horse Race Simulation. The lab asks you to complete a horse race simulation. YOU MAY ONLY MODIFY THE 'mydraw' function. DO NOT USE GLOBAL VARIABLES LIKE IN THE STICK FIGURE PROGRAM. You need to generalize the variables (hx,hy) into arrays that can represent n horses. You must be able to vary the number of horses in your race by just changing the value of n. Make sure you understand the structure of the main animation loop: it needs to redraw the entire image each time it runs, including background, lines and text. It needs to call updateDisplay() and time.sleep at the end of each loop. Because you will need to display n horses instead of an array of horses, you will need to write NESTED loops within the main animation loop. These loops must be properly indented. Nested loops can get confusing so please think carefully about each of the 5 principal components of your loop: are they present? To move the horses forward, you just need to change their x coordinates by a random value, such as randint(1,5) (between 1 and 5 pixels). Besides the hrskeleton program, you can also refer to the circles.py program that animates n bouncing circles. Your finished program should look like mine: there needs to be lines separating the racing lanes, a finsh line, the name of each horse displayed in each line, as well as some text caption. In the skeleton program I used the following variables (besides width,height) to calculate the graphical coordinates needed: n: number of horses yoffset: a amount of space to leave at the top to display messages gifwidth,gifheight: width and height of animated gif image lanewidth: the distance between the horizontal lines. finish: the x coordinate of the finish line. The race ends when some horse crosses the finish line. stop: a boolean variable to control the main animation loop NOTE: People with MacOS may experience some irregularities with the animation, but should still be able to finish the assignment. If it becomes really difficult, you can always run it in Linux in the lab. ----------------- PART II. The first part of the assignment just asks you to stop the race when some horse crosses the finish line. Now you need to enhance it as follows: 1. During each step of the race, you need to display the number of the horse that's in the lead. If there's a tie for the lead, multiple numbers should be displayed. At the end of the race, the winning horse should be indicated (in text at the top). The winning horse is not necessarilty always the first horse you detected that has moved past the finish line. To display text beginning at a certain position in the program follow the example in the skeleton program. 2. Create the option of using a different animated gif for each horse. (you will need another array). You can find plenty of gifs online. However, since the gifs are of different sizes, you should scale them to be of the same size in your program: animframe = animator.get_pixbuf() # gets animation frame animframe = animframe.scale_simple(GW,GH,GdkPixbuf.InterpType.NEAREST) Here, GW and GH are the desired width and height of the animation frame. 3. Name the horses. Use the "command line argument array" sys.argv. First put "import sys" at the top of the program. When you start a python program, you can start using a command such as $ python3.4 horserace abc def ghi Inside the program, sys.argv[0]=="horserace", sys.argv[1]=="abc", etc.. Thus you can name the horses, as well as determine how many horses are going to be in the race when you start the program. ... For additional, optional work, consult lab5b.txt.