Justxd22 commited on
Commit
4b16b59
Β·
1 Parent(s): b7025df

Implement round advancement and update game logic for accusations and UI display

Browse files
app.py CHANGED
@@ -74,6 +74,24 @@ class GameSession:
74
  if action == "select_suspect":
75
  return None
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  if action == "chat_message":
78
  suspect_id = payload.get("suspect_id")
79
  message = payload.get("message")
@@ -95,14 +113,34 @@ class GameSession:
95
  arg = payload.get("input") # Default for single-input tools
96
 
97
  if tool_name == "accuse":
98
- result_msg = self.game.make_accusation(payload.get("suspect_id"))
99
- return {
100
- "action": "game_over",
101
- "data": {
102
- "message": result_msg,
103
- "verdict": self.game.verdict_correct
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
105
- }
106
 
107
  kwargs = {}
108
  if tool_name == "get_location":
 
74
  if action == "select_suspect":
75
  return None
76
 
77
+ if action == "next_round":
78
+ if self.game.advance_round():
79
+ return {
80
+ "action": "update_status",
81
+ "data": {
82
+ "round": self.game.round,
83
+ "points": self.game.points
84
+ }
85
+ }
86
+ else:
87
+ return {
88
+ "action": "game_over",
89
+ "data": {
90
+ "message": "COLD CASE. You ran out of time.",
91
+ "verdict": False
92
+ }
93
+ }
94
+
95
  if action == "chat_message":
96
  suspect_id = payload.get("suspect_id")
97
  message = payload.get("message")
 
113
  arg = payload.get("input") # Default for single-input tools
114
 
115
  if tool_name == "accuse":
116
+ result = self.game.make_accusation(payload.get("suspect_id"))
117
+
118
+ if result["result"] == "win":
119
+ return {
120
+ "action": "game_over",
121
+ "data": {
122
+ "message": result["message"],
123
+ "verdict": True
124
+ }
125
+ }
126
+ elif result["result"] == "loss":
127
+ return {
128
+ "action": "game_over",
129
+ "data": {
130
+ "message": result["message"],
131
+ "verdict": False
132
+ }
133
+ }
134
+ else:
135
+ return {
136
+ "action": "round_failure",
137
+ "data": {
138
+ "message": result["message"],
139
+ "eliminated_id": result["eliminated_id"],
140
+ "round": result["new_round"],
141
+ "points": result["new_points"]
142
+ }
143
  }
 
144
 
145
  kwargs = {}
146
  if tool_name == "get_location":
game/game_engine.py CHANGED
@@ -15,6 +15,8 @@ class GameInstance:
15
  self.logs = [] # Chat logs
16
  self.game_over = False
17
  self.verdict_correct = False
 
 
18
 
19
  # Initialize Agents
20
  self._init_agents()
@@ -106,28 +108,43 @@ class GameInstance:
106
  return result
107
 
108
  def advance_round(self):
109
- if self.round < self.max_rounds:
110
- self.round += 1
111
- return True
112
- else:
113
- self.game_over = True
114
- return False
115
 
116
  def make_accusation(self, suspect_id):
117
- self.game_over = True
118
-
119
- # Check if correct
120
  murderer = next((s for s in self.scenario["suspects"] if s["is_murderer"]), None)
 
121
 
122
  if murderer and murderer["id"] == suspect_id:
 
123
  self.verdict_correct = True
124
- msg = f"CORRECT! {murderer['name']} was the murderer."
 
 
 
125
  else:
126
- self.verdict_correct = False
127
- msg = f"INCORRECT. The true murderer was {murderer['name'] if murderer else 'Unknown'}."
 
128
 
129
- self.log_event("System", f"FINAL ACCUSATION: {suspect_id}. Result: {msg}")
130
- return msg
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
  # Global Session Store
133
  SESSIONS = {}
 
15
  self.logs = [] # Chat logs
16
  self.game_over = False
17
  self.verdict_correct = False
18
+ self.eliminated_suspects = []
19
+ self.max_rounds = 3 # 3 Chances
20
 
21
  # Initialize Agents
22
  self._init_agents()
 
108
  return result
109
 
110
  def advance_round(self):
111
+ # Deprecated: Rounds advance via accusation now
112
+ pass
 
 
 
 
113
 
114
  def make_accusation(self, suspect_id):
 
 
 
115
  murderer = next((s for s in self.scenario["suspects"] if s["is_murderer"]), None)
116
+ suspect_name = next((s["name"] for s in self.scenario["suspects"] if s["id"] == suspect_id), "Unknown")
117
 
118
  if murderer and murderer["id"] == suspect_id:
119
+ self.game_over = True
120
  self.verdict_correct = True
121
+ return {
122
+ "result": "win",
123
+ "message": f"CORRECT! {murderer['name']} was the murderer."
124
+ }
125
  else:
126
+ # Wrong accusation
127
+ self.eliminated_suspects.append(suspect_id)
128
+ self.log_event("System", f"Incorrect accusation: {suspect_name}. Eliminated.")
129
 
130
+ if self.round >= self.max_rounds:
131
+ self.game_over = True
132
+ self.verdict_correct = False
133
+ return {
134
+ "result": "loss",
135
+ "message": f"WRONG. That was your last chance. The killer was {murderer['name']}."
136
+ }
137
+ else:
138
+ # Advance Round
139
+ self.round += 1
140
+ self.points += 5
141
+ return {
142
+ "result": "continue",
143
+ "message": f"{suspect_name} is INNOCENT. +5 Points. Try again.",
144
+ "eliminated_id": suspect_id,
145
+ "new_round": self.round,
146
+ "new_points": self.points
147
+ }
148
 
149
  # Global Session Store
150
  SESSIONS = {}
ui/static/css/noir.css CHANGED
@@ -60,6 +60,22 @@ body, html {
60
  display: flex;
61
  gap: 20px;
62
  font-size: 1.1rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
  /* --- Left Panel: Suspect Files --- */
 
60
  display: flex;
61
  gap: 20px;
62
  font-size: 1.1rem;
63
+ align-items: center;
64
+ }
65
+
66
+ .stat-btn {
67
+ background: transparent;
68
+ border: none;
69
+ color: var(--accent-red);
70
+ font-size: 1.2rem;
71
+ cursor: pointer;
72
+ transition: transform 0.2s;
73
+ padding: 0 5px;
74
+ }
75
+
76
+ .stat-btn:hover {
77
+ transform: scale(1.2);
78
+ color: #fff;
79
  }
80
 
81
  /* --- Left Panel: Suspect Files --- */
ui/static/js/game_logic.js CHANGED
@@ -71,6 +71,9 @@ function handleServerMessage(message) {
71
  case 'update_status':
72
  updateStatus(data);
73
  break;
 
 
 
74
  case 'game_over':
75
  triggerGameOver(data);
76
  break;
@@ -81,6 +84,12 @@ function handleServerMessage(message) {
81
 
82
  // --- Game Logic ---
83
 
 
 
 
 
 
 
84
  function initializeGame(data) {
85
  gameState = data;
86
  renderSuspects();
@@ -93,7 +102,7 @@ function initializeGame(data) {
93
  addChatMessage('system', `VICTIM: ${data.scenario.victim.name}`);
94
 
95
  // Update UI stats
96
- document.getElementById('round-display').innerText = `${data.round}/5`;
97
  document.getElementById('points-display').innerText = data.points;
98
 
99
  renderCaseFile(data.scenario);
@@ -117,6 +126,40 @@ function renderCaseFile(scenario) {
117
  }, 20, 20);
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  function triggerGameOver(data) {
121
  const overlay = document.createElement('div');
122
  overlay.id = 'game-over-overlay';
 
71
  case 'update_status':
72
  updateStatus(data);
73
  break;
74
+ case 'round_failure':
75
+ handleRoundFailure(data);
76
+ break;
77
  case 'game_over':
78
  triggerGameOver(data);
79
  break;
 
84
 
85
  // --- Game Logic ---
86
 
87
+ function updateStatus(data) {
88
+ document.getElementById('round-display').innerText = `${data.round}/3`;
89
+ document.getElementById('points-display').innerText = data.points;
90
+ showNotification("TIME ADVANCED (+5 PTS)");
91
+ }
92
+
93
  function initializeGame(data) {
94
  gameState = data;
95
  renderSuspects();
 
102
  addChatMessage('system', `VICTIM: ${data.scenario.victim.name}`);
103
 
104
  // Update UI stats
105
+ document.getElementById('round-display').innerText = `${data.round}/3`;
106
  document.getElementById('points-display').innerText = data.points;
107
 
108
  renderCaseFile(data.scenario);
 
126
  }, 20, 20);
127
  }
128
 
129
+ function handleRoundFailure(data) {
130
+ showNotification("❌ " + data.message);
131
+
132
+ // Update stats
133
+ document.getElementById('round-display').innerText = `${data.round}/3`;
134
+ document.getElementById('points-display').innerText = data.points;
135
+
136
+ // Eliminate Suspect Visuals
137
+ const card = document.querySelector(`.suspect-card[data-id="${data.eliminated_id}"]`);
138
+ if (card) {
139
+ card.classList.add('eliminated');
140
+ card.onclick = null; // Disable clicking
141
+ card.style.opacity = "0.5";
142
+ card.style.filter = "grayscale(100%)";
143
+
144
+ // Add X overlay
145
+ const xMark = document.createElement('div');
146
+ xMark.innerText = "❌";
147
+ xMark.style.position = "absolute";
148
+ xMark.style.top = "50%";
149
+ xMark.style.left = "50%";
150
+ xMark.style.transform = "translate(-50%, -50%)";
151
+ xMark.style.fontSize = "5rem";
152
+ xMark.style.color = "red";
153
+ xMark.style.opacity = "0.8";
154
+ card.appendChild(xMark);
155
+ }
156
+
157
+ if (gameState.currentSuspect === data.eliminated_id) {
158
+ gameState.currentSuspect = null;
159
+ addChatMessage('system', "Suspect eliminated. Select another.");
160
+ }
161
+ }
162
+
163
  function triggerGameOver(data) {
164
  const overlay = document.createElement('div');
165
  overlay.id = 'game-over-overlay';
ui/templates/game_interface.html CHANGED
@@ -20,7 +20,7 @@
20
  <div id="top-bar">
21
  <div class="game-title">MURDER.AI</div>
22
  <div class="stats-panel">
23
- <span>ROUND: <span id="round-display">1/5</span></span>
24
  <span>POINTS: <span id="points-display">10</span></span>
25
  </div>
26
  </div>
 
20
  <div id="top-bar">
21
  <div class="game-title">MURDER.AI</div>
22
  <div class="stats-panel">
23
+ <span>ROUND: <span id="round-display">1/3</span></span>
24
  <span>POINTS: <span id="points-display">10</span></span>
25
  </div>
26
  </div>