Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -20,7 +20,7 @@ def init_game(username, loadout):
|
|
20 |
"kills": 0,
|
21 |
"bonus": bonus,
|
22 |
"round": 0,
|
23 |
-
"status": "active",
|
24 |
"revives": 0,
|
25 |
"ammo": 100,
|
26 |
"armor": 100,
|
@@ -29,8 +29,8 @@ def init_game(username, loadout):
|
|
29 |
"plates": 3,
|
30 |
"max_plates": 12,
|
31 |
"in_gulag": False,
|
32 |
-
"gulag_count": 0, # number of times
|
33 |
-
"gulag_tokens": 0 # only obtainable AFTER
|
34 |
}
|
35 |
|
36 |
@app.route("/")
|
@@ -45,7 +45,7 @@ def start():
|
|
45 |
return limit_response("User required")
|
46 |
game_states[user] = init_game(user, loadout)
|
47 |
resp = (f"Game started for {user}! Players:150, Bonus:{game_states[user]['bonus']:.1f}, Plates:3. "
|
48 |
-
"
|
49 |
return limit_response(resp)
|
50 |
|
51 |
@app.route("/fight", methods=["GET"])
|
@@ -54,91 +54,142 @@ def fight():
|
|
54 |
if not user or user not in game_states:
|
55 |
return limit_response("Start game first with !start")
|
56 |
state = game_states[user]
|
57 |
-
|
|
|
58 |
if state["status"] != "active":
|
59 |
msg = f"Game over. Final Kills: {state['kills']}. "
|
60 |
if state["status"] == "won":
|
61 |
-
msg += "You emerged victorious! Use !start to
|
62 |
elif state["status"] == "eliminated":
|
63 |
msg += "You were eliminated. Use !start to try again."
|
64 |
elif state["status"] == "gulag":
|
65 |
-
msg += "You
|
66 |
return limit_response(msg)
|
67 |
|
68 |
-
# If no plates, effective bonus is reduced.
|
69 |
effective_bonus = state["bonus"] if state["plates"] > 0 else state["bonus"] * 0.7
|
70 |
state["round"] += 1
|
71 |
r = state["round"]
|
72 |
final_round = state["players"] <= 3
|
73 |
event = random.choice(["fight", "loot", "buy", "ambush"])
|
74 |
resp = f"R{r}: "
|
75 |
-
|
76 |
-
#
|
77 |
if event == "fight":
|
78 |
-
#
|
79 |
-
if "Air Strike" in state["equipment"] and random.random() < 0.
|
80 |
-
|
81 |
-
kills = random.randint(2, 4)
|
82 |
state["kills"] += kills
|
83 |
state["players"] = max(state["players"] - kills, 1)
|
84 |
-
state["ammo"] = max(state["ammo"] - random.randint(5,
|
85 |
resp += f"You called in an Air Strike! It obliterated {kills} enemies. "
|
86 |
state["equipment"].remove("Air Strike")
|
87 |
else:
|
88 |
-
#
|
89 |
-
scenario = random.randint(1,
|
90 |
gun_used = random.choice(["M4", "AK-47", "Shotgun", "Sniper", "SMG"])
|
|
|
|
|
91 |
if scenario == 1:
|
92 |
-
kills = random.randint(1,2)
|
93 |
-
resp += f"Your precision shot with the {gun_used} downed {kills} foe(s). "
|
94 |
-
elif scenario == 2:
|
95 |
kills = 1
|
96 |
-
resp += f"
|
|
|
|
|
|
|
97 |
elif scenario == 3:
|
98 |
-
|
99 |
-
|
100 |
-
kills = 0
|
101 |
elif scenario == 4:
|
102 |
-
kills =
|
103 |
-
resp += f"A burst from your {gun_used}
|
104 |
elif scenario == 5:
|
105 |
-
|
106 |
-
|
107 |
-
state["plates"] = max(state["plates"] - 1, 0)
|
108 |
elif scenario == 6:
|
109 |
kills = 1
|
110 |
-
resp += f"
|
111 |
-
state["plates"] = max(state["plates"] - 1, 0)
|
112 |
elif scenario == 7:
|
113 |
-
resp += f"Your {gun_used}
|
114 |
-
|
115 |
-
kills = 0
|
116 |
elif scenario == 8:
|
117 |
-
|
118 |
-
|
119 |
elif scenario == 9:
|
120 |
kills = 1
|
121 |
-
resp += f"
|
122 |
-
state["plates"] = max(state["plates"] - 1, 0)
|
123 |
elif scenario == 10:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
kills = 0
|
125 |
-
resp += f"
|
126 |
-
|
127 |
-
|
|
|
|
|
128 |
kills = 1
|
129 |
-
resp += f"
|
130 |
state["kills"] += kills
|
131 |
if kills > 0:
|
132 |
state["players"] = max(state["players"] - kills, 1)
|
133 |
-
state["ammo"] = max(state["ammo"] - random.randint(5,
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
|
141 |
-
#
|
142 |
elif event == "loot":
|
143 |
loot = random.choice(["weapon", "ammo", "armor", "plate", "gulag token"])
|
144 |
if loot == "weapon":
|
@@ -163,14 +214,14 @@ def fight():
|
|
163 |
else:
|
164 |
resp += "Plates are already maxed out. "
|
165 |
elif loot == "gulag token":
|
166 |
-
# Only allow picking up
|
167 |
if state["gulag_count"] > 0 and state["gulag_tokens"] == 0:
|
168 |
state["gulag_tokens"] = 1
|
169 |
resp += "Found a Gulag Token on the battlefield! "
|
170 |
else:
|
171 |
resp += "No useful token found. "
|
172 |
|
173 |
-
#
|
174 |
elif event == "buy":
|
175 |
item = random.choice(["UAV", "Air Strike", "Cluster Strike", "Armor Box", "Plates", "Gulag Token"])
|
176 |
if item in ["UAV", "Air Strike"]:
|
@@ -191,14 +242,13 @@ def fight():
|
|
191 |
else:
|
192 |
resp += "Your plates are already at maximum. "
|
193 |
elif item == "Gulag Token":
|
194 |
-
# Only allow buying a token if you've been to gulag and don't already have one.
|
195 |
if state["gulag_count"] > 0 and state["gulag_tokens"] == 0:
|
196 |
state["gulag_tokens"] = 1
|
197 |
resp += "Purchased a Gulag Token for a second chance! "
|
198 |
else:
|
199 |
resp += "No need for a token right now. "
|
200 |
|
201 |
-
#
|
202 |
elif event == "ambush":
|
203 |
resp += "Ambushed! "
|
204 |
amb = random.choice(["escaped", "lost ammo", "got a kill"])
|
@@ -210,22 +260,23 @@ def fight():
|
|
210 |
state["players"] = max(state["players"] - kills, 1)
|
211 |
resp += f"Ambush escalated into a firefight and you secured {kills} kill(s) with your {gun_used}! "
|
212 |
else:
|
213 |
-
resp += "Managed to evade the ambush, but remain
|
214 |
elif amb == "lost ammo":
|
215 |
lost = random.randint(10, 20)
|
216 |
state["ammo"] = max(state["ammo"] - lost, 0)
|
217 |
-
resp += f"Got caught off guard and lost {lost} ammo
|
218 |
else:
|
219 |
kills = random.randint(1, 2)
|
220 |
state["kills"] += kills
|
221 |
state["players"] = max(state["players"] - kills, 1)
|
222 |
resp += f"Overpowered the ambushers and secured {kills} kill(s) with your {gun_used}! "
|
223 |
-
|
224 |
-
# Natural eliminations occur
|
225 |
nat = random.randint(5, 15)
|
226 |
state["players"] = max(state["players"] - nat, 1)
|
227 |
resp += f"Additionally, {nat} enemies were eliminated naturally. "
|
228 |
-
|
|
|
229 |
if state["players"] <= 1:
|
230 |
state["status"] = "won"
|
231 |
resp += f"Victory! Final Kills: {state['kills']}. You emerged triumphant, warrior! Use !start to play again."
|
@@ -246,19 +297,18 @@ def gulag():
|
|
246 |
waiting_msg = "In Gulag: waiting for an opponent... "
|
247 |
outcome = random.random()
|
248 |
# Multiple Gulag outcomes:
|
249 |
-
if outcome < 0.
|
250 |
state["status"] = "active"
|
251 |
state["in_gulag"] = False
|
252 |
state["players"] = max(state["players"] - random.randint(2,5), 1)
|
253 |
resp = waiting_msg + "After a fierce duel, you won the Gulag fight and return to battle. Use !fight to continue."
|
254 |
-
elif outcome < 0.
|
255 |
state["status"] = "eliminated"
|
256 |
resp = waiting_msg + f"Your opponent proved too strong. You were eliminated in Gulag. Final Kills: {state['kills']}. Use !start to play again."
|
257 |
else:
|
258 |
-
# Stalemate: you lose a plate and must fight again in Gulag.
|
259 |
if state["plates"] > 0:
|
260 |
state["plates"] = max(state["plates"] - 1, 0)
|
261 |
-
resp = waiting_msg + "The Gulag duel
|
262 |
return limit_response(resp)
|
263 |
|
264 |
if __name__ == "__main__":
|
|
|
20 |
"kills": 0,
|
21 |
"bonus": bonus,
|
22 |
"round": 0,
|
23 |
+
"status": "active", # active, gulag, eliminated, won
|
24 |
"revives": 0,
|
25 |
"ammo": 100,
|
26 |
"armor": 100,
|
|
|
29 |
"plates": 3,
|
30 |
"max_plates": 12,
|
31 |
"in_gulag": False,
|
32 |
+
"gulag_count": 0, # number of times downed
|
33 |
+
"gulag_tokens": 0 # only obtainable AFTER first gulag
|
34 |
}
|
35 |
|
36 |
@app.route("/")
|
|
|
45 |
return limit_response("User required")
|
46 |
game_states[user] = init_game(user, loadout)
|
47 |
resp = (f"Game started for {user}! Players:150, Bonus:{game_states[user]['bonus']:.1f}, Plates:3. "
|
48 |
+
"Brace yourself for intense combat! Use !fight to engage.")
|
49 |
return limit_response(resp)
|
50 |
|
51 |
@app.route("/fight", methods=["GET"])
|
|
|
54 |
if not user or user not in game_states:
|
55 |
return limit_response("Start game first with !start")
|
56 |
state = game_states[user]
|
57 |
+
|
58 |
+
# If game already ended, display final results.
|
59 |
if state["status"] != "active":
|
60 |
msg = f"Game over. Final Kills: {state['kills']}. "
|
61 |
if state["status"] == "won":
|
62 |
+
msg += "You emerged victorious! Use !start to play again."
|
63 |
elif state["status"] == "eliminated":
|
64 |
msg += "You were eliminated. Use !start to try again."
|
65 |
elif state["status"] == "gulag":
|
66 |
+
msg += "You're in Gulag! Use !gulag to fight your opponent."
|
67 |
return limit_response(msg)
|
68 |
|
69 |
+
# If you have no plates, your effective bonus is reduced.
|
70 |
effective_bonus = state["bonus"] if state["plates"] > 0 else state["bonus"] * 0.7
|
71 |
state["round"] += 1
|
72 |
r = state["round"]
|
73 |
final_round = state["players"] <= 3
|
74 |
event = random.choice(["fight", "loot", "buy", "ambush"])
|
75 |
resp = f"R{r}: "
|
76 |
+
|
77 |
+
# ---- FIGHT EVENT ----
|
78 |
if event == "fight":
|
79 |
+
# Lower chance for Air Strike usage.
|
80 |
+
if "Air Strike" in state["equipment"] and random.random() < 0.15:
|
81 |
+
kills = random.randint(2, 3)
|
|
|
82 |
state["kills"] += kills
|
83 |
state["players"] = max(state["players"] - kills, 1)
|
84 |
+
state["ammo"] = max(state["ammo"] - random.randint(5,10), 0)
|
85 |
resp += f"You called in an Air Strike! It obliterated {kills} enemies. "
|
86 |
state["equipment"].remove("Air Strike")
|
87 |
else:
|
88 |
+
# Select one of 15 gunfight scenarios.
|
89 |
+
scenario = random.randint(1,15)
|
90 |
gun_used = random.choice(["M4", "AK-47", "Shotgun", "Sniper", "SMG"])
|
91 |
+
downed = False
|
92 |
+
kills = 0
|
93 |
if scenario == 1:
|
|
|
|
|
|
|
94 |
kills = 1
|
95 |
+
resp += f"Your precision shot with the {gun_used} downed {kills} foe. "
|
96 |
+
elif scenario == 2:
|
97 |
+
resp += f"Your {gun_used} jammed at a critical moment, and you were caught off guard—downed! "
|
98 |
+
downed = True
|
99 |
elif scenario == 3:
|
100 |
+
kills = 1
|
101 |
+
resp += f"You outmaneuvered an enemy with your {gun_used} and secured a kill. "
|
|
|
102 |
elif scenario == 4:
|
103 |
+
kills = 1
|
104 |
+
resp += f"A burst from your {gun_used} earned you {kills} kill, though you were rattled. "
|
105 |
elif scenario == 5:
|
106 |
+
resp += f"Your attempt to flank with the {gun_used} backfired—you were overwhelmed and downed! "
|
107 |
+
downed = True
|
|
|
108 |
elif scenario == 6:
|
109 |
kills = 1
|
110 |
+
resp += f"Your rapid reload with the {gun_used} allowed you to grab a kill. "
|
|
|
111 |
elif scenario == 7:
|
112 |
+
resp += f"Disaster! Your {gun_used} misfired and left you exposed—downed! "
|
113 |
+
downed = True
|
|
|
114 |
elif scenario == 8:
|
115 |
+
resp += f"A stray round from your {gun_used} grazed an enemy, but nothing decisive happened. "
|
116 |
+
kills = 0
|
117 |
elif scenario == 9:
|
118 |
kills = 1
|
119 |
+
resp += f"An aggressive assault with your {gun_used} got you {kills} kill. "
|
|
|
120 |
elif scenario == 10:
|
121 |
+
kills = 1
|
122 |
+
resp += f"A lucky headshot with your {gun_used} secured {kills} kill, but you lost a plate. "
|
123 |
+
state["plates"] = max(state["plates"] - 1, 0)
|
124 |
+
elif scenario == 11:
|
125 |
+
kills = 1
|
126 |
+
resp += f"Suppressive fire from your {gun_used} earned you {kills} kill. "
|
127 |
+
elif scenario == 12:
|
128 |
+
resp += f"In a moment of hesitation, you failed to act and were downed by enemy fire. "
|
129 |
+
downed = True
|
130 |
+
elif scenario == 13:
|
131 |
+
kills = 1
|
132 |
+
resp += f"Your {gun_used} shot knocked an enemy out for {kills} kill, but your cover was compromised."
|
133 |
+
if random.random() < 0.5:
|
134 |
+
downed = True
|
135 |
+
resp += " You were subsequently overwhelmed. "
|
136 |
+
elif scenario == 14:
|
137 |
+
kills = 1
|
138 |
+
resp += f"Your {gun_used} burst ricocheted, earning {kills} kill but costing you a plate. "
|
139 |
+
state["plates"] = max(state["plates"] - 1, 0)
|
140 |
+
elif scenario == 15:
|
141 |
kills = 0
|
142 |
+
resp += f"In the chaos, you managed no kills and were left vulnerable."
|
143 |
+
if random.random() < 0.5:
|
144 |
+
downed = True
|
145 |
+
# In final round, force at least one kill if not downed.
|
146 |
+
if final_round and not downed and kills == 0:
|
147 |
kills = 1
|
148 |
+
resp += f"Under final round pressure, you managed a desperate 1 kill with your {gun_used}. "
|
149 |
state["kills"] += kills
|
150 |
if kills > 0:
|
151 |
state["players"] = max(state["players"] - kills, 1)
|
152 |
+
state["ammo"] = max(state["ammo"] - random.randint(5,10), 0)
|
153 |
+
# Additional chance to lose a plate from stray enemy fire.
|
154 |
+
if not downed and random.random() < 0.3:
|
155 |
+
lost = 1
|
156 |
+
state["plates"] = max(state["plates"] - lost, 0)
|
157 |
+
resp += f"Amid the firefight, you lost {lost} plate from enemy fire. "
|
158 |
+
|
159 |
+
# If downed, try self-revive (low chance) or enter Gulag.
|
160 |
+
if downed:
|
161 |
+
if random.random() < 0.1: # 10% chance to self-revive
|
162 |
+
state["revives"] += 1
|
163 |
+
if state["plates"] > 0:
|
164 |
+
lost_plate = 1
|
165 |
+
state["plates"] = max(state["plates"] - lost_plate, 0)
|
166 |
+
resp += f"Miraculously, you self-revived (lost {lost_plate} plate). "
|
167 |
+
else:
|
168 |
+
resp += "Miraculously, you self-revived despite having no plates. "
|
169 |
+
else:
|
170 |
+
lost_plate = random.randint(1, 2)
|
171 |
+
state["plates"] = max(state["plates"] - lost_plate, 0)
|
172 |
+
# First downing: free Gulag chance; afterward, need a token.
|
173 |
+
if state["gulag_count"] == 0:
|
174 |
+
state["gulag_count"] += 1
|
175 |
+
state["in_gulag"] = True
|
176 |
+
state["status"] = "gulag"
|
177 |
+
resp += f"Downed by enemy fire (lost {lost_plate} plate(s))! You've earned a free Gulag chance. Use !gulag."
|
178 |
+
return limit_response(resp)
|
179 |
+
else:
|
180 |
+
if state["gulag_tokens"] > 0:
|
181 |
+
state["gulag_tokens"] -= 1
|
182 |
+
state["gulag_count"] += 1
|
183 |
+
state["in_gulag"] = True
|
184 |
+
state["status"] = "gulag"
|
185 |
+
resp += f"Downed again (lost {lost_plate} plate(s))! You used a Gulag Token for another chance. Use !gulag."
|
186 |
+
return limit_response(resp)
|
187 |
+
else:
|
188 |
+
state["status"] = "eliminated"
|
189 |
+
resp += f"Downed by enemy fire (lost {lost_plate} plate(s))! No Gulag Tokens available. Game over. Final Kills: {state['kills']}. Use !start to play again."
|
190 |
+
return limit_response(resp)
|
191 |
|
192 |
+
# ---- LOOT EVENT ----
|
193 |
elif event == "loot":
|
194 |
loot = random.choice(["weapon", "ammo", "armor", "plate", "gulag token"])
|
195 |
if loot == "weapon":
|
|
|
214 |
else:
|
215 |
resp += "Plates are already maxed out. "
|
216 |
elif loot == "gulag token":
|
217 |
+
# Only allow picking up if you've been to gulag and don't already have one.
|
218 |
if state["gulag_count"] > 0 and state["gulag_tokens"] == 0:
|
219 |
state["gulag_tokens"] = 1
|
220 |
resp += "Found a Gulag Token on the battlefield! "
|
221 |
else:
|
222 |
resp += "No useful token found. "
|
223 |
|
224 |
+
# ---- BUY EVENT ----
|
225 |
elif event == "buy":
|
226 |
item = random.choice(["UAV", "Air Strike", "Cluster Strike", "Armor Box", "Plates", "Gulag Token"])
|
227 |
if item in ["UAV", "Air Strike"]:
|
|
|
242 |
else:
|
243 |
resp += "Your plates are already at maximum. "
|
244 |
elif item == "Gulag Token":
|
|
|
245 |
if state["gulag_count"] > 0 and state["gulag_tokens"] == 0:
|
246 |
state["gulag_tokens"] = 1
|
247 |
resp += "Purchased a Gulag Token for a second chance! "
|
248 |
else:
|
249 |
resp += "No need for a token right now. "
|
250 |
|
251 |
+
# ---- AMBUSH EVENT ----
|
252 |
elif event == "ambush":
|
253 |
resp += "Ambushed! "
|
254 |
amb = random.choice(["escaped", "lost ammo", "got a kill"])
|
|
|
260 |
state["players"] = max(state["players"] - kills, 1)
|
261 |
resp += f"Ambush escalated into a firefight and you secured {kills} kill(s) with your {gun_used}! "
|
262 |
else:
|
263 |
+
resp += "Managed to evade the ambush, but remain on high alert. "
|
264 |
elif amb == "lost ammo":
|
265 |
lost = random.randint(10, 20)
|
266 |
state["ammo"] = max(state["ammo"] - lost, 0)
|
267 |
+
resp += f"Got caught off guard and lost {lost} ammo. "
|
268 |
else:
|
269 |
kills = random.randint(1, 2)
|
270 |
state["kills"] += kills
|
271 |
state["players"] = max(state["players"] - kills, 1)
|
272 |
resp += f"Overpowered the ambushers and secured {kills} kill(s) with your {gun_used}! "
|
273 |
+
|
274 |
+
# Natural eliminations always occur.
|
275 |
nat = random.randint(5, 15)
|
276 |
state["players"] = max(state["players"] - nat, 1)
|
277 |
resp += f"Additionally, {nat} enemies were eliminated naturally. "
|
278 |
+
|
279 |
+
# Check for game win.
|
280 |
if state["players"] <= 1:
|
281 |
state["status"] = "won"
|
282 |
resp += f"Victory! Final Kills: {state['kills']}. You emerged triumphant, warrior! Use !start to play again."
|
|
|
297 |
waiting_msg = "In Gulag: waiting for an opponent... "
|
298 |
outcome = random.random()
|
299 |
# Multiple Gulag outcomes:
|
300 |
+
if outcome < 0.35:
|
301 |
state["status"] = "active"
|
302 |
state["in_gulag"] = False
|
303 |
state["players"] = max(state["players"] - random.randint(2,5), 1)
|
304 |
resp = waiting_msg + "After a fierce duel, you won the Gulag fight and return to battle. Use !fight to continue."
|
305 |
+
elif outcome < 0.65:
|
306 |
state["status"] = "eliminated"
|
307 |
resp = waiting_msg + f"Your opponent proved too strong. You were eliminated in Gulag. Final Kills: {state['kills']}. Use !start to play again."
|
308 |
else:
|
|
|
309 |
if state["plates"] > 0:
|
310 |
state["plates"] = max(state["plates"] - 1, 0)
|
311 |
+
resp = waiting_msg + "The Gulag duel ended in a stalemate—you lost a plate and remain in Gulag. Use !gulag to try again."
|
312 |
return limit_response(resp)
|
313 |
|
314 |
if __name__ == "__main__":
|