/
anachronos.py
executable file
·339 lines (289 loc) · 9.29 KB
/
anachronos.py
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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#!/usr/bin/env python
# THIS ARE REALLY COOL GAMES, GUY.
import fabulous.color
from player import Player
import logic
from map import MapGenerator, Map
from game import GameState
import game
import sys
import os
def get_coords(map):
coords = None
while not coords:
try:
coords = raw_input(": ").split(',')
coords[0] = int(coords[0])
coords[1] = int(coords[1])
if coords[0] < 0 or coords[0] >= map.size or coords[1] < 0 or coords[1] >= map.size:
coords = None
except:
coords = None
return coords
def display_map(state, player):
state.paint_map()
raw_input()
def display_unit_details(state, player):
print "\n Enter the coordinates of the unit. (x,y)"
coords = get_coords(state.map)
unit = state.locate_unit(coords[0], coords[1])
if unit:
print ("%s: " % unit.player.name) + str(unit)
raw_input()
else:
print "There is not a unit at that location."
raw_input()
def move_unit(state, player):
print "\nEnter the coordinates of the unit to move. (x,y)"
coords = get_coords(state.map)
unit = state.locate_unit(coords[0], coords[1])
if unit and unit.player.name is player.name:
print "Enter the coordinates to move to. (x,y)"
moveto = get_coords(state.map)
tile = state.map.tile(moveto[0], moveto[1])
path = unit.can_move(tile)
if path:
player.move_number +=1
player.paradox += logic.calculate_distance(unit.location, tile)/2
player.moves.append(game.MoveAction(player.move_number, player, unit, unit.location, tile, path))
if not path:
print "Couldn't move that unit there."
raw_input()
else:
print "You don't have a unit at that location."
raw_input()
def deploy_units(state, player):
raw_input()
state.paint_map()
for unit in player.units:
deployed = False
while not deployed:
print "\nEnter coordinates to deploy %s" % unit
coords = get_coords(state.map)
unit_at = state.locate_unit(coords[0], coords[1])
if not unit_at:
deployed = unit.deploy(state.map.tile(coords[0], coords[1]))
state.paint_map()
def attack(state, player):
print "\nEnter the coordinates of the unit to attack with. (x,y)"
coords = get_coords(state.map)
unit = state.locate_unit(coords[0], coords[1])
if unit and unit.player.name is player.name:
print "Enter the coordinates to attack. (x,y)"
attackto = get_coords(state.map)
tile = state.map.tile(attackto[0], attackto[1])
if unit.can_attack(tile):
player.attack_number +=1
player.paradox += logic.calculate_distance(unit.location, tile)/2
player.attacks.append(game.AttackAction(player.attack_number, player, unit, unit.location, tile))
else:
print "Couldn't use that unit to attack there."
raw_input()
else:
print "You don't have a unit at that location."
raw_input()
def forfeit(state, player):
over = """
_____ ____
/ ____| / __ \
| | __ __ _ _ __ ___ ___ | | | |__ _____ _ __
| | |_ |/ _` | '_ ` _ \ / _ \ | | | |\ \ / / _ \ '__|
| |__| | (_| | | | | | | __/ | |__| | \ V / __/ |
\_____|\__,_|_| |_| |_|\___| \____/ \_/ \___|_|
"""
print over
print "\t%s has forfeit the battle.\n" % player.name
raw_input()
sys.exit(0)
def previous_moves(state, player):
print "\nSee moves from which turn? (Current turn is %d) (0 to cancel)" % state.turn_number
turn = -1
while turn < 1 or turn > state.turn_number - 1:
try:
turn = int(raw_input(": "))
except:
pass
if turn == 0:
return
moves = [move for move in state.move_stack[turn] if move.unit.player.name == player.name]
for move in moves:
print move
raw_input()
def previous_attacks(state, player):
print "\nSee attacks from which turn? (Current turn is %d) (0 to cancel)" % state.turn_number
turn = -1
while turn < 1 or turn > state.turn_number - 1:
try:
turn = int(raw_input(": "))
except:
pass
if turn == 0:
return
attacks = [attack for attack in state.attack_stack[turn] if attack.unit.player.name == player.name]
for attack in attacks:
print attack
raw_input()
def previous_map(state, player):
print "\nSee map from which turn? (Current turn is %d) (0 to cancel)" % state.turn_number
turn = -1
while turn < 1 or turn > state.turn_number - 1:
try:
turn = int(raw_input(": "))
except:
pass
if turn == 0:
return
oldmap = Map(state.map.size)
oldmap.zones = state.map_stack[turn]
oldmap.draw()
raw_input()
def undo_move(state, player):
print "\nUndo which move? (turn, id) (0,0 to cancel)"
move = (-1,-1)
while move[0] < 1 or move[0] > state.turn_number - 1 or move[1] < 1:
try:
move = raw_input(": ").split(',')
move[0] = int(move[0])
move[1] = int(move[1])
if len(move) < 2:
move.append(0)
except:
pass
if move == (0,0):
return
if player.paradox - move[0] < 0:
print "Insufficient paradox points. You would destabilize the timestream!"
return
player.paradox -= move[0]*10
state.undo_move(move[0], move[1])
state.replay(move[0])
def undo_attack(state, player):
print "\nUndo which attack? (turn, id) (0,0 to cancel)"
move = (-1,-1)
while move[0] < 1 or move[0] > state.turn_number - 1 or move[1] < 1:
try:
move = raw_input(": ").split(',')
move[0] = int(move[0])
move[1] = int(move[1])
if len(move) < 2:
move.append(0)
except:
pass
if move == (0,0):
return
if player.paradox - move[0] < 0:
print "Insufficient paradox points. You would destabilize the timestream!"
return
player.paradox -= move[0]*10
state.undo_attack(move[0], move[1])
state.replay(move[0])
def game_over(state, player):
over = """
_____ ____
/ ____| / __ \
| | __ __ _ _ __ ___ ___ | | | |__ _____ _ __
| | |_ |/ _` | '_ ` _ \ / _ \ | | | |\ \ / / _ \ '__|
| |__| | (_| | | | | | | __/ | |__| | \ V / __/ |
\_____|\__,_|_| |_| |_|\___| \____/ \_/ \___|_|
"""
print over
print "\t%s ended their turn with no units.\n" % player.name
raw_input()
sys.exit(0)
def display_turn_menu(state, player):
end = False
state.paint_map()
commands = {
"1":display_map,
"2":display_unit_details,
"3":move_unit,
"4":attack,
"5":previous_moves,
"6":undo_move,
"7":previous_attacks,
"8":undo_attack,
"9":previous_map,
"e":None,
"q":forfeit
}
while not end:
command = ""
while command not in commands:
state.paint_map()
print "\n%s, it is your turn." % player.name
print "PARADOX (%s)" % str(fabulous.color.cyan(str(player.paradox)))
print """
[1] View Map
[2] View Unit Details
[3] Move Unit
[4] Attack
[5] View Past Moves
[6] Undo Past Moves
[7] View Past Attacks
[8] Undo Past Attacks
[9] View Past Maps
[e] End turn
[q] Forfeit
""" + "\n"
command = raw_input(": ")
if command == "e":
end = True
else:
commands[command](state, player)
anachronos_title = """
O~
O~ ~~ O~~
O~ O~~ O~~ O~~ O~~ O~~~O~~ O~ O~~~ O~~ O~~ O~~ O~~ O~~~~
O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~ O~ O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~
O~~~~~~ O~~ O~~ O~~O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~O~~ O~~ O~~~
O~~ O~~ O~~ O~~O~~ O~~ O~~ O~ O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~ O~~
O~~ O~~O~~~ O~~ O~~ O~~~ O~~~O~~ O~~O~~~ O~~ O~~~ O~~ O~~ O~~ O~~
"""
anachronos_subtitle = """
(c) 2012 Ducks Unlimited
"""
welcome = """
Welcome to Anachronos.
Anachronos is a turn-based strategy game where the orders you give your units are not final.
By spending your Paradox points wisely, you can turn back the clock, prevent battles from occuring,
or turn the tables on your opponent completely.
... spend your Paradox points carelessly, and you'll wish you'd never tampered with time at all.
"""
players_prompt = "How many players will be engaging in battle: "
name_prompt = "Enter your name: "
color_prompt = "Please enter your prefered army color: "
map_prompt = "Enter the name of a pregenerated map file, else leave your battlefield up to the fickle hand of fate: "
player_deployments = ["%s will deploy in the top left corner of the map.",
"%s will deploy in the bottom right corner of the map.",
"%s will deploy in the top left corner of the map.",
"%s will deploy in the bottom right corner of the map."]
if __name__ == '__main__':
print fabulous.color.bold(anachronos_title)
print anachronos_subtitle
print welcome
player_num = 0
while player_num < 2 or player_num > 4:
try:
player_num = int(raw_input(players_prompt))
except:
print "Please enter a value that makes sense."
players = []
for i in range(0, player_num):
pname = raw_input(name_prompt)
pcolor = raw_input(color_prompt)
player = Player(pname, pcolor)
players.append(player)
generator = MapGenerator()
game_map = generator.create_map('dirt', 40)
state = GameState(game_map=game_map, players=players)
print "\nBeginning deployment phase"
for i in range(0, player_num):
print player_deployments[i] % players[i].name
deploy_units(state, players[i])
while True:
for player in state.players:
player.begin_turn()
display_turn_menu(state, player)
if not player.is_alive():
game_over(state, player)
state.play()