import sys import random from types import NoneType import pygame as pg from modules.agente import Agente from modules.mapa import Mapa import modules.estrategia as ModEstrategia import modules.interaccoes as ModInteraccoes # 0 para desactivar flags # pg.FULLSCREEN para fullscreen mode flags = pg.FULLSCREEN def devolveCor(agente: Agente) -> tuple[int, int, int, int]: if type(agente) is None: return (0, 0, 0, 0) else: match agente.estrategia: case "Neutro": return (255, 255, 255, 0) case "Tit4Tat": return (255, 255, 0, 0) case "Vingativo": return (255, 0, 0, 0) case "Lunatico": return (0, 0, 255, 0) case _: return (0, 0, 0, 0) def criarJanelaInfo(surface: pg.Surface) -> None: pass def criarTabuleiro( surface: pg.Surface, mapa: Mapa, ) -> None: dimensao_tabuleiro: tuple[int, int] = mapa.dimensao dimensoes_surface_principal: tuple[int, int] = surface.get_size() max_altura: int = int((dimensoes_surface_principal[1] - 20) / dimensao_tabuleiro[0]) # max_largura: int = int( # (dimensoes_surface_principal[0] - 20) / dimensao_tabuleiro[1] # ) tamanho_quadrado: int = max_altura # min([max_altura, max_largura]) cor_quadrado: tuple[int, int, int, int] for pos_y in range(0, dimensao_tabuleiro[0]): for pos_x in range(0, dimensao_tabuleiro[1]): agente: Agente | None = mapa.posicao((pos_x, pos_y)) cor_quadrado = devolveCor(agente) pg.draw.rect( surface, cor_quadrado, [ 10 + (tamanho_quadrado * pos_x), 10 + (tamanho_quadrado * pos_y), tamanho_quadrado, tamanho_quadrado, ], 0, ) def popularMapa(mapa: Mapa) -> None: for pos_y in range(0, mapa.dimensao[0]): for pos_x in range(0, mapa.dimensao[1]): # escolher uma estrategia aleatoria estrategia = random.choice(ModEstrategia.listaNomesEstrategias()) # criar Agente com estrategia aleatoria e colocar na posicao y e x mapa.mundo[pos_y][pos_x] = Agente(estrategia, (pos_x, pos_y)) def prepararEstatistica(mapa: Mapa | None) -> dict[str, int]: if mapa is None: print("SEM MAPA!!") else: stats_estrategias: dict[str, int] = {} n_total_agentes: int = 0 # print("estatisticas mapa:") for tipo_estrategia in ModEstrategia.lista_estrategias: stats_estrategias[tipo_estrategia] = 0 for pos_y in range(0, mapa.dimensao[0]): for pos_x in range(0, mapa.dimensao[1]): tmp_agente = mapa.posicao((pos_y, pos_x)) stats_estrategias[tmp_agente.estrategia] += 1 n_total_agentes += 1 # for tipo_estrategia in stats_estrategias: # print( # f"{tipo_estrategia}: { # (stats_estrategias[tipo_estrategia] / n_total_agentes) * 100:3.2f}" # ) return stats_estrategias return {} def mostrarMapa(mapa: Mapa | None) -> None: # verificacao if isinstance(mapa, NoneType): raise TypeError("objecto passado do tipo None") # mostrar mapa com pontuação em cada posição for pos_y in range(0, mapa.dimensao[0]): for pos_x in range(0, mapa.dimensao[1]): tmp_agente: Agente | None = mapa.posicao((pos_x, pos_y)) if not isinstance(tmp_agente, NoneType): print(f"{tmp_agente.estrategia[0]:2}", end="") print("") def main(mapa: Mapa | None, tamanho_mapa: tuple[int, int]): if isinstance(mapa, NoneType): raise TypeError("não foi passado mapa (tipo None)") pg.init() janela = pg.display.set_mode((1280, 800), flags) pg.display.set_caption("Game Theory of Life") clock = pg.time.Clock() running: bool = True # cor1: tuple[int, int, int, int] = (255, 0, 0, 0) # cor2: tuple[int, int, int, int] = (0, 255, 0, 0) # mostrarMapa(mapa) quadrado_seleccionado: pg.Rect | None = None while running: if quadrado_seleccionado: pg.draw.rect( janela, pg.Color(0, 0, 0, 0), quadrado_seleccionado, 2, border_radius=10, ) for event in pg.event.get(): if event.type == pg.QUIT: running = False if event.type == pg.KEYDOWN: # sair do mapa com 'q' (quit) if event.key == pg.K_q: running = False # mudar mapa com 'c' (change) if event.key == pg.K_c: novo_tamanho = int(input("tamanho do mapa: ")) tamanho_mapa = (novo_tamanho, novo_tamanho) janela.fill(0) mapa = Mapa(tamanho_mapa) popularMapa(mapa) # correr proxima iteração com 'n' (next) if event.key == pg.K_n: ModInteraccoes.correrInteraccoesEntreAgentes(mapa) # gerar novo mapa e popular (fazer reset) com 'r' if event.key == pg.K_r: mapa = Mapa(tamanho_mapa) popularMapa(mapa) if event.type == pg.MOUSEBUTTONDOWN: # botao 1 do rato clicado, seleccionar ou tirar selecao if pg.mouse.get_pressed(num_buttons=3)[0]: pos_rato: tuple[int, int] = pg.mouse.get_pos() tamanho_quadrado = int( (janela.get_size()[1] - 20) / mapa.dimensao[0] ) if pos_rato[0] < 10 or pos_rato[1] < 10: continue pos_x = int((pos_rato[0] - 10) / tamanho_quadrado) pos_y = int((pos_rato[1] - 10) / tamanho_quadrado) if pos_x >= mapa.dimensao[0] or pos_y >= mapa.dimensao[1]: continue quadrado_novo = pg.Rect( (pos_x * tamanho_quadrado) + 10, (pos_y * tamanho_quadrado) + 10, tamanho_quadrado, tamanho_quadrado, ) # limpar janela de info janela_info = pg.Surface((200, 200)) janela_info.fill(pg.Color(0, 0, 0, 0)) janela.blit(janela_info, (janela.get_size()[0] - 200, 500)) if quadrado_novo == quadrado_seleccionado: quadrado_seleccionado = None else: quadrado_seleccionado = quadrado_novo agente = mapa.posicao((pos_x, pos_y)) print(f"{agente.posicao} com {agente.estrategia}") criarTabuleiro(janela, mapa) # criar surface para apresentar info criarJanelaInfo(janela) # mostrar dimensão do mapa # mostrar borda da posicao seleccionado com o rato if quadrado_seleccionado: pg.draw.rect( janela, pg.Color(0, 0, 0, 0), quadrado_seleccionado, 2, border_radius=20, ) # limpar janela de info info_janela = pg.Surface((200, 200)) info_janela.fill(pg.Color(0, 0, 0, 0)) janela.blit(info_janela, (janela.get_size()[0] - 200, 500)) # mostrar informação sobre posicao seleccionada font = pg.font.Font(None, 20) info_posicao = font.render( f"{mapa.posicao((pos_x, pos_y)).estrategia}@{(pos_x, pos_y)}", False, pg.Color(255, 255, 255, 0), ) janela.blit(info_posicao, (janela.get_size()[0] - 200, 500)) # mostrar numero de iteração actual # mostrar estatisticas janela_stats = pg.Surface((200, 200)) janela_stats.fill(pg.Color(0, 0, 0, 0)) janela.blit(janela_stats, (janela.get_size()[0] - 200, 10)) font = pg.font.Font(None, 20) dict_estrat = prepararEstatistica(mapa) n_linhas = 0 for strat in dict_estrat: strat_label = font.render( f"{strat}: {(dict_estrat[strat] / mapa.dimensao[0] ** 2) * 100:3.2f}", False, pg.Color(255, 255, 255, 0), ) janela.blit(strat_label, (janela.get_size()[0] - 200, 10 + (30 * n_linhas))) n_linhas += 1 pg.display.flip() clock.tick(60) pg.quit() sys.exit() if __name__ == "__main__": mapa_mundo: Mapa = Mapa((128, 128)) app = main(mapa_mundo, tamanho_mapa=(128, 128))