3 from tkinter
import ttk
, messagebox
6 from scipy
.spatial
.distance
import cityblock
8 # Configurações do tabuleiro (tamanho (X,Y), orçamento inicial, Custo dos sensores)
10 ROWS
= int(sys
.argv
[1])
11 COLS
= int(sys
.argv
[2])
17 def __init__(self
, root
):
19 self
.root
.title("Caçadores da Arca Perdida")
21 # Inicialização de variáveis de estado
22 self
.perfect_mode
= False
23 self
.INITIAL_BUDGET
= 100
24 self
.SENSOR_COSTS
= {"GPR": 5, "MAG": 3, "VIS": 1, "DIG": 0}
26 self
.budget
= self
.INITIAL_BUDGET
27 self
.ark_loc
= (random
.randint(0, ROWS
- 1), random
.randint(0, COLS
- 1))
29 self
.probs
= np
.full((ROWS
, COLS
), 1.0 / (ROWS
* COLS
))
30 self
.used_sensors
= set()
31 self
.cell_history
= {}
32 self
.show_treasure_debug
= False
33 # Tabelas de Probabilidade Normais
34 self
.SENSOR_TABLES
= {
36 "STRONG": [0.75, 0.10, 0.05, 0.02],
37 "MODERATE": [0.15, 0.70, 0.15, 0.08],
38 "WEAK": [0.07, 0.15, 0.65, 0.15],
39 "NONE": [0.03, 0.05, 0.15, 0.75]
42 "HIGH": [0.70, 0.15, 0.10],
43 "MEDIUM": [0.20, 0.65, 0.25],
44 "LOW": [0.10, 0.20, 0.65]
47 "SUSPICIOUS": [0.60, 0.20],
48 "NORMAL": [0.40, 0.80]
51 # Tabelas de Probabilidade Perfeitas
52 self
.SENSOR_TABLES_PERFECT
= {
54 "STRONG": [1, 0, 0, 0],
55 "MODERATE": [0, 1, 0, 0],
72 self
.style
= ttk
.Style()
73 self
.style
.configure("Perfect.TButton", foreground
="green", font
=("Arial", 9, "bold"))
74 self
.style
.configure("Normal.TButton", foreground
="black")
78 # Define os sensores utilizados
80 def current_sensor_table(self
):
81 return self
.SENSOR_TABLES_PERFECT
if self
.perfect_mode
else self
.SENSOR_TABLES
85 self
.main_frame
= ttk
.Frame(self
.root
, padding
="10")
86 self
.main_frame
.grid(row
=0, column
=0, sticky
="nsew")
91 btn
= tk
.Button(self
.main_frame
, text
="", width
=15, height
=5,
92 font
=("Arial", 8), relief
="groove",
93 command
=lambda row
=r
, col
=c
: self
.cell_click(row
, col
))
94 btn
.grid(row
=r
, column
=c
, padx
=2, pady
=2, sticky
="nsew")
95 self
.buttons
[(r
, c
)] = btn
98 control_panel
= ttk
.Frame(self
.root
, padding
="10")
99 control_panel
.grid(row
=0, column
=1, sticky
="ns")
102 self
.budget_var
= tk
.StringVar(value
=f
"Orçamento: {self.budget}")
103 ttk
.Label(control_panel
, textvariable
=self
.budget_var
, font
=("Arial", 12, "bold")).pack(pady
=5)
105 # RadioButton Sensores
106 self
.sensor_var
= tk
.StringVar(value
="GPR")
107 sf
= ttk
.LabelFrame(control_panel
, text
=" Selecione o Sensor ", padding
="5")
108 sf
.pack(fill
='x', pady
=5)
109 for s
, cost
in self
.SENSOR_COSTS
.items():
110 ttk
.Radiobutton(sf
, text
=f
"{s} ({cost})", variable
=self
.sensor_var
, value
=s
).pack(anchor
='w')
112 # Botão Revelar tesouro
113 self
.reveal_btn
= ttk
.Button(control_panel
, text
="Revelar Tesouro: OFF", command
=self
.toggle_treasure
,
114 style
="Normal.TButton")
115 self
.reveal_btn
.pack(fill
='x', pady
=10)
117 # Botão Sensores Perfeitos
118 self
.perfect_btn
= ttk
.Button(control_panel
, text
="Sensores Perfeitos: OFF", command
=self
.toggle_perfect_mode
,
119 style
="Normal.TButton")
120 self
.perfect_btn
.pack(fill
='x', pady
=5)
123 ttk
.Label(control_panel
, text
="Histórico:").pack(anchor
='w', pady
=(10, 0))
124 self
.history_log
= tk
.Text(control_panel
, width
=30, height
=12, state
='disabled', font
=("Consolas", 9))
125 self
.history_log
.pack(pady
=5)
128 ttk
.Button(control_panel
, text
="Reiniciar Jogo", command
=self
.reset_game
).pack(fill
='x', pady
=2)
131 ttk
.Button(control_panel
, text
="Sair", command
=self
.root
.destroy
).pack(fill
='x', pady
=5)
134 self
.update_grid_display()
136 # Activa/Desactiva sensores perfeitos
137 def toggle_perfect_mode(self
):
138 self
.perfect_mode
= not self
.perfect_mode
139 if self
.perfect_mode
:
140 self
.perfect_btn
.config(text
="Sensores Perfeitos: ON", style
="Perfect.TButton")
142 self
.perfect_btn
.config(text
="Sensores Perfeitos: OFF", style
="Normal.TButton")
144 self
.history_log
.config(state
='normal')
145 self
.history_log
.insert(tk
.END
, f
"> Modo Sensores Perfeitos: {'ON' if self.perfect_mode else 'OFF'}\n")
146 self
.history_log
.see(tk
.END
)
147 self
.history_log
.config(state
='disabled')
149 # Activa/Desactiva localização do tesouro
150 def toggle_treasure(self
):
152 self
.show_treasure_debug
= not self
.show_treasure_debug
153 if self
.show_treasure_debug
:
154 self
.reveal_btn
.config(text
="Revelar Tesouro: ON", style
="Perfect.TButton")
156 self
.reveal_btn
.config(text
="Revelar Tesouro: OFF", style
="Normal.TButton")
158 self
.history_log
.config(state
='normal')
159 self
.history_log
.insert(tk
.END
, f
"> Modo Tesouro Visivel: {'ON' if self.show_treasure_debug else 'OFF'}\n")
160 self
.history_log
.see(tk
.END
)
161 self
.history_log
.config(state
='disabled')
163 self
.update_grid_display()
165 # Actualiza o tabuleiro
166 def update_grid_display(self
):
167 for (r
, c
), btn
in self
.buttons
.items():
168 treasure_header
= "!!! TESOURO !!!\n" if (self
.show_treasure_debug
and (r
, c
) == self
.ark_loc
) else ""
169 p_text
= f
"{self.probs[r, c]:.1%}"
170 history_text
= self
.cell_history
.get((r
, c
), "")
172 history_text
= "\n" + history_text
174 btn
.config(text
=f
"{treasure_header}{p_text}{history_text}")
176 # Cor de fundo baseada na probabilidade
177 intensity
= int(255 - (self
.probs
[r
, c
] * 350))
178 intensity
= max(min(intensity
, 255), 180)
179 color
= f
"#{255:02x}{intensity:02x}{intensity:02x}"
181 if self
.show_treasure_debug
and (r
, c
) == self
.ark_loc
:
182 color
= "#FFD700" # Dourado
186 # Click das localizações do mapa
187 def cell_click(self
, r
, c
):
188 sensor
= self
.sensor_var
.get()
189 cost
= self
.SENSOR_COSTS
[sensor
]
191 # Verifica o se sensor já foi usado na localização
192 if sensor
!= "DIG" and (r
, c
, sensor
) in self
.used_sensors
:
193 messagebox
.showwarning("Aviso", "Este sensor já foi usado aqui!")
196 # Verifica se há orçamento
197 if self
.budget
< cost
:
198 messagebox
.showwarning("Aviso", "Orçamento insuficiente!")
201 # Se o jogador utilizou "DIG" verifica se ganhou ou perdeu
203 if (r
, c
) == self
.ark_loc
:
204 messagebox
.showinfo("Vitória", f
"Encontrou o tesouro!\nPontuação final: {self.budget}")
206 messagebox
.showerror("Derrota", f
"O tesouro não está nesta localização.\nPerdeu o jogo!")
210 # Executa o sensor, com base na tabela utilizada
211 dist
= cityblock((r
, c
), self
.ark_loc
)
212 active_table
= self
.current_sensor_table
[sensor
]
214 # Determinar leitura baseada nas probabilidades
215 outcomes
= list(active_table
.keys())
216 max_idx
= len(next(iter(active_table
.values()))) - 1
217 idx
= min(dist
, max_idx
)
218 weights
= [active_table
[out
][idx
] for out
in outcomes
]
220 reading
= random
.choices(outcomes
, weights
=weights
, k
=1)[0]
223 # Actualiza orçamento
224 self
.used_sensors
.add((r
, c
, sensor
))
226 self
.budget_var
.set(f
"Orçamento: {self.budget}")
228 # Atualiza o resultado na localização
229 entry
= f
"{sensor}:{reading}"
231 # Actualiza o histórico
232 self
.cell_history
[(r
, c
)] = f
"{self.cell_history.get((r, c), '')}\n{entry}".strip()
233 self
.history_log
.config(state
='normal')
234 self
.history_log
.insert(tk
.END
, f
"{sensor} em ({r},{c}): {reading}\n")
235 self
.history_log
.see(tk
.END
)
236 self
.history_log
.config(state
='disabled')
238 self
.update_probabilities(sensor
, reading
, (r
, c
))
239 self
.update_grid_display()
241 # actualiza as probabilidades no tabuleiro
242 def update_probabilities(self
, sensor
, reading
, click_loc
):
243 new_probs
= np
.zeros((ROWS
, COLS
))
244 table_row
= self
.current_sensor_table
[sensor
][reading
]
245 max_idx
= len(table_row
) - 1
247 for r
in range(ROWS
):
248 for c
in range(COLS
):
249 d
= cityblock((r
, c
), click_loc
)
250 prob_evidence
= table_row
[min(d
, max_idx
)]
251 new_probs
[r
, c
] = self
.probs
[r
, c
] * prob_evidence
253 total
= np
.sum(new_probs
)
255 self
.probs
= new_probs
/ total
258 def reset_game(self
):
259 self
.budget
= self
.INITIAL_BUDGET
260 self
.budget_var
.set(f
"Orçamento: {self.budget}")
261 self
.ark_loc
= (random
.randint(0, ROWS
- 1), random
.randint(0, COLS
- 1))
262 self
.probs
= np
.full((ROWS
, COLS
), 1.0 / (ROWS
* COLS
))
263 self
.used_sensors
= set()
264 self
.cell_history
= {}
266 self
.history_log
.config(state
='normal')
267 self
.history_log
.delete('1.0', tk
.END
)
268 self
.history_log
.config(state
='disabled')
270 self
.update_grid_display()
273 if __name__
== "__main__":
275 game
= TreasureGame(root
)