123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- import pygame
- import time
- import datetime
- import os.path
- import json
- from pygame.locals import *
- from simulation.board import Board
- class Interface:
- FOOD_COLOR = (0, 150, 0)
- TOUCHED_COLOR = (50, 50, 0)
- BLOB_LOWER_COLOR = (255, 255, 0)
- BLOB_HIGHER_COLOR = (255, 0, 0)
- BACKGROUND = (0, 0, 0)
- BOARD_SEPARATOR = (120, 120, 120)
- def __init__(self, board, player, blob, scale, save_dir, mode, hidden=False, colors_file=None):
- """
- :type board: Board
- :type player: Player
- :type blob: Blob_Manager
- :type scale: float
- :type save_dir: str
- """
- pygame.init()
- # pygame.key.set_repeat(5, 50)
- if colors_file is not None:
- with open(colors_file, 'r') as file:
- colors = json.load(file)
- Interface.FOOD_COLOR = tuple(colors['FOOD_COLOR'])
- Interface.TOUCHED_COLOR = tuple(colors['TOUCHED_COLOR'])
- Interface.BLOB_LOWER_COLOR = tuple(colors['BLOB_LOWER_COLOR'])
- Interface.BLOB_HIGHER_COLOR = tuple(colors['BLOB_HIGHER_COLOR'])
- Interface.BACKGROUND = tuple(colors['BACKGROUND'])
- Interface.BOARD_SEPARATOR = tuple(colors['BOARD_SEPARATOR'])
- self.board = board
- self.player = player
- self.blob = blob
- self.scale = scale
- self.save_dir = save_dir
- self.debug_mode = False
- self.play = False
- self.do_step = False
- self.show_ants = True
- width = self.board.width * scale
- height = self.board.height * scale
- self.hidden = hidden
- if not self.hidden:
- self.window = pygame.display.set_mode((width, height), mode)
- self.window_surface = pygame.Surface((width, height))
- cross_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "cross.png")
- discovered_food = pygame.image.load(cross_file)
- if not self.hidden:
- discovered_food = discovered_food.convert()
- discovered_food.set_colorkey((255, 255, 255))
- self.discovered_food = pygame.transform.scale(discovered_food, (scale, scale))
- def draw(self):
- width = self.board.width * self.scale
- height = self.board.height * self.scale
- game_surface = pygame.Surface((self.board.width, self.board.height))
- pixel_array = pygame.PixelArray(game_surface)
- for x in range(self.board.width):
- for y in range(self.board.height):
- pixel_array[x, y] = Interface.BACKGROUND
- if self.board.has_food(x, y):
- pixel_array[x, y] = Interface.FOOD_COLOR
- if self.board.is_touched(x, y):
- pixel_array[x, y] = Interface.TOUCHED_COLOR
- val = self.board.get_blob(x, y)
- if val != Board.MIN_BLOB:
- val = (val - Board.MIN_BLOB) / (Board.MAX_BLOB - Board.MIN_BLOB)
- red = (Interface.BLOB_HIGHER_COLOR[0] - Interface.BLOB_LOWER_COLOR[0]) * val + \
- Interface.BLOB_LOWER_COLOR[0]
- green = (Interface.BLOB_HIGHER_COLOR[1] - Interface.BLOB_LOWER_COLOR[1]) * val + \
- Interface.BLOB_LOWER_COLOR[1]
- blue = (Interface.BLOB_HIGHER_COLOR[2] - Interface.BLOB_LOWER_COLOR[2]) * val + \
- Interface.BLOB_LOWER_COLOR[2]
- pixel_array[x, y] = (red, green, blue)
- if self.show_ants:
- for scouter in self.blob.scouters:
- pixel_array[scouter.x, scouter.y] = (255, 255, 255)
- del pixel_array
- game_window = pygame.transform.scale(game_surface, (width, height))
- pygame.draw.line(game_window, Interface.BOARD_SEPARATOR, (0, height / 2), (width, height / 2))
- self.window_surface.blit(game_window, (0, 0))
- for food in self.blob.knowledge['food']:
- self.window_surface.blit(self.discovered_food, (food[0] * self.scale, food[1] * self.scale))
- if not self.hidden:
- self.window.blit(self.window_surface, (0, 0))
- pygame.display.flip()
- def save(self, name=None):
- if name is None:
- name = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d_%H.%M.%S')
- print("Data saved at " + name)
- f = open(self.save_dir + name + ".board", 'w')
- f.write(self.board.save())
- f.close()
- f = open(self.save_dir + name + ".blob.json", 'w')
- f.write(self.blob.save())
- f.close()
- f = open(self.save_dir + name + ".player.json", 'w')
- f.write(self.player.save())
- f.close()
- if self.hidden:
- self.draw()
- pygame.image.save(self.window_surface, self.save_dir + name + ".jpg")
- return name
- def event_listener(self, event):
- # ADMIN ACTIONS
- if event.type == KEYDOWN and event.key == 100: # D Letter
- self.debug_mode = not self.debug_mode
- print("Debug Mode: " + str(self.debug_mode))
- elif event.type == KEYDOWN and event.key == K_UP:
- self.blob.knowledge["Global Decrease"] += 0.1
- print("Pheromone evaporation : " + str(self.blob.knowledge["Global Decrease"]))
- elif event.type == KEYDOWN and event.key == K_DOWN:
- self.blob.knowledge["Global Decrease"] -= 0.1
- print("Pheromone evaporation : " + str(self.blob.knowledge["Global Decrease"]))
- elif event.type == KEYDOWN and event.key == K_SPACE:
- self.show_ants = not self.show_ants
- elif event.type == KEYDOWN and event.key == 115: # S Letter
- self.save()
- # DEBUG ACTIONS
- elif self.debug_mode and event.type == MOUSEBUTTONDOWN and event.button == 1: # Right Click
- x = int(pygame.mouse.get_pos()[0] / self.scale)
- y = int(pygame.mouse.get_pos()[1] / self.scale)
- self.board.update_blob(x, y, 10)
- # PLAYER ACTIONS
- elif event.type == MOUSEBUTTONDOWN and event.button == 1: # Right Click
- x = int(pygame.mouse.get_pos()[0]/self.scale)
- y = int(pygame.mouse.get_pos()[1]/self.scale)
- if self.board.has_food(x, y):
- self.player.remove_food(x, y)
- else:
- self.player.set_food(x, y)
- elif event.type == KEYDOWN and event.key == 99: # C Letter
- self.player.clean_board()
- elif event.type == KEYDOWN and event.key == 114: # R Letter
- self.player.set_random_food(10, not self.player.clean_top)
- elif event.type == KEYDOWN and event.key == 104: # H Letter
- up_size_percent, down_size_percent = self.player.check_blob_cover()
- print("Blob covering:")
- print("\t{:.2f}% of the board.".format((up_size_percent + down_size_percent)/2))
- print("\t{:.2f}% of the upper board.".format(up_size_percent))
- print("\t{:.2f}% of the lower board.".format(down_size_percent))
- # BLOB ACTIONS
- elif event.type == KEYDOWN and event.key == 112: # P Letter
- self.play = not self.play
- elif event.type == KEYDOWN and event.key == K_RETURN:
- self.do_step = True
- elif event.type == KEYDOWN and event.key == 107: # K Letter
- if self.blob.knowledge["Scouters"]["Min"] > 0:
- self.blob.knowledge["Scouters"]["Min"] -= 1
- print("New minimal scouters : " + str(self.blob.knowledge["Scouters"]["Min"]) + " - Currently : "
- + str(len(self.blob.scouters)))
- elif event.type == KEYDOWN and event.key == 113: # A letter
- self.blob.knowledge["Scouters"]["Min"] += 1
- print("New minimal scouters : " + str(self.blob.knowledge["Scouters"]["Min"]) + " - Currently : "
- + str(len(self.blob.scouters)))
- elif event.type == KEYDOWN:
- print("Unrecognised key code : " + str(event.key))
- return False
- else:
- return False
- return True
|