You won’t be able to handle the fast-paced excitement of these racing . . . snails. But what they lack in speed they make up for in ASCII-art cuteness. Each snail (represented by an @
character for the shell and v
for the two eyestalks) moves slowly but surely toward the finish line. Up to eight snails, each with a custom name, can race each other, leaving a slime trail in their wake. This program is good for beginners.
When you run snailrace.py, the output will look like this:
Snail Race, by Al Sweigart [email protected]
@v <-- snail
How many snails will race? Max: 8
> 3
Enter snail #1's name:
> Alice
Enter snail #2's name:
> Bob
Enter snail #3's name:
> Carol
START FINISH
| |
Alice
......@v
Bob
.....@v
Carol
.......@v
--snip--
This program makes use of two data structures, stored in two variables: snailNames
is a list of strings of each snail’s name, and snailProgress
is a dictionary whose keys are the snails’ names and whose values are integers representing how many spaces the snails have moved. Lines 79 to 82 read the data in these two variables to draw the snails at appropriate places on the screen.
1. """Snail Race, by Al Sweigart [email protected]
2. Fast-paced snail racing action!
3. This code is available at https://nostarch.com/big-book-small-python-programming
4. Tags: short, artistic, beginner, game, multiplayer"""
5.
6. import random, time, sys
7.
8. # Set up the constants:
9. MAX_NUM_SNAILS = 8
10. MAX_NAME_LENGTH = 20
11. FINISH_LINE = 40 # (!) Try modifying this number.
12.
13. print('''Snail Race, by Al Sweigart [email protected]
14.
15. @v <-- snail
16.
17. ''')
18.
19. # Ask how many snails to race:
20. while True: # Keep asking until the player enters a number.
21. print('How many snails will race? Max:', MAX_NUM_SNAILS)
22. response = input('> ')
23. if response.isdecimal():
24. numSnailsRacing = int(response)
25. if 1 < numSnailsRacing <= MAX_NUM_SNAILS:
26. break
27. print('Enter a number between 2 and', MAX_NUM_SNAILS)
28.
29. # Enter the names of each snail:
30. snailNames = [] # List of the string snail names.
31. for i in range(1, numSnailsRacing + 1):
32. while True: # Keep asking until the player enters a valid name.
33. print('Enter snail #' + str(i) + "'s name:")
34. name = input('> ')
35. if len(name) == 0:
36. print('Please enter a name.')
37. elif name in snailNames:
38. print('Choose a name that has not already been used.')
39. else:
40. break # The entered name is acceptable.
41. snailNames.append(name)
42.
43. # Display each snail at the start line.
44. print('\n' * 40)
45. print('START' + (' ' * (FINISH_LINE - len('START')) + 'FINISH'))
46. print('|' + (' ' * (FINISH_LINE - len('|')) + '|'))
47. snailProgress = {}
48. for snailName in snailNames:
49. print(snailName[:MAX_NAME_LENGTH])
50. print('@v')
51. snailProgress[snailName] = 0
52.
53. time.sleep(1.5) # The pause right before the race starts.
54.
55. while True: # Main program loop.
56. # Pick random snails to move forward:
57. for i in range(random.randint(1, numSnailsRacing // 2)):
58. randomSnailName = random.choice(snailNames)
59. snailProgress[randomSnailName] += 1
60.
61. # Check if a snail has reached the finish line:
62. if snailProgress[randomSnailName] == FINISH_LINE:
63. print(randomSnailName, 'has won!')
64. sys.exit()
65.
66. # (!) EXPERIMENT: Add a cheat here that increases a snail's progress
67. # if it has your name.
68.
69. time.sleep(0.5) # (!) EXPERIMENT: Try changing this value.
70.
71. # (!) EXPERIMENT: What happens if you comment this line out?
72. print('\n' * 40)
73.
74. # Display the start and finish lines:
75. print('START' + (' ' * (FINISH_LINE - len('START')) + 'FINISH'))
76. print('|' + (' ' * (FINISH_LINE - 1) + '|'))
77.
78. # Display the snails (with name tags):
79. for snailName in snailNames:
80. spaces = snailProgress[snailName]
81. print((' ' * spaces) + snailName[:MAX_NAME_LENGTH])
82. print(('.' * snailProgress[snailName]) + '@v')
After entering the source code and running it a few times, try making experimental changes to it. The comments marked with (!)
have suggestions for small changes you can make. On your own, you can also try to figure out how to do the following:
zzz
to appear next to them.Try to find the answers to the following questions. Experiment with some modifications to the code and rerun the program to see what effect the changes have.
snailName[:MAX_NAME_LENGTH]
on line 81 to snailNames[0]
?print('@v')
on line 50 to print('v@')
?