-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathgame.py
More file actions
200 lines (175 loc) · 7.6 KB
/
game.py
File metadata and controls
200 lines (175 loc) · 7.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
import glob
import os
from pythonwarrior.config import Config
from pythonwarrior.level import Level
from pythonwarrior.player_generator import PlayerGenerator
from pythonwarrior.profile import Profile
from pythonwarrior.tower import Tower
from pythonwarrior.ui import UI
class Game(object):
def __init__(self):
self._profile = None
self._current_level = None
self._next_level = None
def start(self):
UI.puts('Welcome to Python Warrior')
if os.path.exists(Config.path_prefix + '/.profile'):
self._profile = Profile.load(Config.path_prefix + '/.profile')
else:
if not os.path.exists(Config.path_prefix + '/pythonwarrior'):
self.make_game_directory()
if self.profile().epic:
if self.profile().level_after_epic():
self.go_back_to_normal_mode()
else:
self.play_epic_mode()
else:
self.play_normal_mode()
def make_game_directory(self):
if UI.ask("No pythonwarrior directory found, \
would you like to create one?"):
os.mkdir(Config.path_prefix + '/pythonwarrior')
else:
UI.puts('Unable to continue without directory.')
raise Exception("Unable to continue without directory.")
def play_epic_mode(self):
if Config.delay:
Config.delay = Config.delay/2
self.profile().current_epic_score = 0
self.profile().current_epic_grades = {}
if Config.practice_level:
self._current_level = self._next_level = None
self.profile().level_number = Config.practice_level
self.play_current_level()
else:
playing = True
while playing:
self._current_level = self._next_level = None
self.profile().level_number += 1
playing = self.play_current_level()
self.profile().save()
def play_normal_mode(self):
if Config.practice_level:
UI.puts("Unable to practice level while not in epic mode,"
"remove -l options")
else:
if self.current_level().number == 0:
self.prepare_next_level()
UI.puts("First level has been generated."
"See the pythonwarrior/%s/README for instructions."
% self.profile().directory_name())
else:
self.play_current_level()
def play_current_level(self):
continue_play = True
UI.puts("Starting level %d" % self.current_level().number)
self.current_level().play()
if self.current_level().is_passed():
if self.next_level().exists():
UI.puts("Success! You have found the stairs.")
else:
UI.puts("CONGRATULATIONS! You have climbed to the top "
"of the tower and rescued the fair maiden Python")
continue_play = False
self.current_level().tally_points()
if self.profile().epic:
if self.final_report() and not continue_play:
UI.puts(self.final_report())
else:
self.request_next_level()
else:
continue_play = False
UI.puts("Sorry, you failed level %d. "
"Change your script and try again." %
self.current_level().number)
if (not Config.skip_input) and self.current_level().clue \
and UI.ask("Would you like to read the "
"additional clues for this level?"):
UI.puts(self.current_level().clue)
return continue_play
def request_next_level(self):
if not Config.skip_input:
if self.next_level().exists():
if UI.ask('Would you like to continue on to the next level?'):
self.prepare_next_level()
UI.puts('See the updated README in the pythonwarrior/' +
self.profile().directory_name() +
' directory')
else:
UI.puts('Staying on current level.'
'Try to earn more points next time.')
else:
if UI.ask('Would you like to continue on to epic mode?'):
self.prepare_epic_mode()
UI.puts('Run pythonwarrior again to play epic mode.')
else:
UI.puts("Staying on current level. "
"Try to earn more points next time.")
def prepare_next_level(self):
self.next_level().load_level()
PlayerGenerator(self.next_level(), self.current_level()).generate()
self.profile().level_number += 1
self.profile().save()
def prepare_epic_mode(self):
self.profile().enable_epic_mode()
self.profile().level_number = 0
self.profile().save()
def go_back_to_normal_mode(self):
self.profile().enable_normal_mode()
self.prepare_next_level()
UI.puts('Another level has been added since you started epic, '
'going back to normal mode')
UI.puts('See the updated README in the '
'pythonwarrior/%s directory' % self.profile().directory_name())
def profiles(self):
return [Profile.load(profile) for profile in self.profile_paths()]
def profile_paths(self):
return glob.glob(Config.path_prefix + '/pythonwarrior/**/.profile')
def profile(self):
if self._profile is None:
self._profile = self.choose_profile()
return self._profile
def new_profile(self):
profile = Profile()
profile.tower_path = UI.choose('tower', self.towers()).path
profile.warrior_name = UI.request('Enter a name for your warrior: ')
return profile
def towers(self):
return [Tower(path) for path in self.tower_paths()]
def tower_paths(self):
tower_paths = glob.glob(os.path.normpath(os.path.abspath(__file__) +
'/../towers/*'))
tower_paths = [path for path in tower_paths
if os.path.isdir(path) and '__' not in path]
return tower_paths
def current_level(self):
if not self._current_level:
self._current_level = self.profile().current_level()
return self._current_level
def next_level(self):
if not self._next_level:
self._next_level = self.profile().next_level()
return self._next_level
def final_report(self):
average_grade = self.profile().calculate_average_grade()
if average_grade and not Config.practice_level:
report = ""
report += ("Your average grade for this tower is: %s\n\n" %
Level.grade_letter(average_grade))
def choose_profile(self):
profile = UI.choose('profile',
self.profiles() + [['new', 'New Profile']])
if profile == 'new':
profile = self.new_profile()
if [prof for prof in self.profiles() if prof.player_path == profile.player_path]:
if UI.ask('Are you sure you want to replace your existing'
'profile for this tower?'):
UI.puts('Replacing existing profile.')
return profile
else:
UI.puts('Not replacing profile.')
raise Exception('Not replacing profile')
else:
return profile
else:
return profile