def initialize_world(self, generation, population): self.world = HookableDict() self.world.hook('setitem', self.world_changed) self.buffer = dict() self.colors = dict() self.peaters = list() self.populate_world(generation, population) self.stale_ticks = 0 self.total_score = 0 self.king = None self.run()
class CursesApp(object): def __init__(self, screen): self._start_screen(screen) self.initialize_options() self.initialize_evolver() curses.init_pair(1, curses.COLOR_WHITE, -1) curses.init_pair(2, -1, curses.COLOR_GREEN) curses.init_pair(3, curses.COLOR_GREEN, -1) def start(self): self.ga.evolve(self.initialize_world) def initialize_options(self, **kwargs): self.king = None self.delay = o.app.render.delay self.draw = o.app.render.startup self.paused = False self.stale_ticks = 0 def initialize_evolver(self): # get all tiles keys = list(itertools.product(tiles.all(), repeat=4)) # create sample with all possible genome keys sample = GMap(keys, Peater.choices, nstates=8) sample.evaluator.set = GMapEvaluator # initialize evolver ga = GSimulationGA(sample) ga.setPopulationSize(o.ga.general.population) ga.setGenerations(o.ga.general.generations) ga.setCrossoverRate(o.ga.crossover.rate) ga.setMutationRate(o.ga.mutation.rate) ga.setElitismReplacement(o.ga.crossover.elites) ga.setElitism(o.ga.crossover.elites > 0) ga.selector.set(Selectors.GTournamentSelector) ga.minimax = Consts.minimaxType[o.ga.evaluator.minimax] self.ga = ga def initialize_world(self, generation, population): self.world = HookableDict() self.world.hook('setitem', self.world_changed) self.buffer = dict() self.colors = dict() self.peaters = list() self.populate_world(generation, population) self.stale_ticks = 0 self.total_score = 0 self.king = None self.run() def populate_world(self, generation, population): height, width = self.screen.getmaxyx() for y in range(height - 1): for x in range(width): tile = None if x == 0 or x == width - 1: tile = Wall() elif y == 0 or y == height - 2: tile = Wall() elif random.randint(0, 20) == 0: tile = Plant() if tile: self.world[(y, x)] = tile for individual in population: y = random.randint(2, height - 4) x = random.randint(2, width - 4) self.peaters.append(Peater(y, x, genome=individual)) self.buffer = dict() for key, val in self.world.items(): self.buffer[key] = val def _start_screen(self, screen): self.screen = screen curses.start_color() curses.use_default_colors() self.screen.nodelay(1) # don't echo keypresses curses.noecho() # handle keypresses immediately curses.cbreak() # enable color rendering curses.start_color() # hide the cursor self.orig_curs_mode = curses.curs_set(0) # handle special characters self.screen.keypad(1) def _stop_screen(self): self.screen.clear() curses.curs_set(self.orig_curs_mode) self.screen.keypad(0) curses.nocbreak() curses.echo() curses.endwin() self.screen = None def world_changed(self, coord, tile): self.buffer[coord] = tile def _render_buffer(self): for coord, tile in self.buffer.items(): y, x = coord self.screen.addch(y, x, ord(tile.char), curses.color_pair(1)) def _render_trail(self): if self.king and o.app.render.trail: for coord, draw in self.king.trail.iteritems(): if coord in self.buffer or draw: self.colors[coord] = o.app.render.trailcolor self.king.trail[coord] = False def _render_king(self): if self.king: coord = self.king.y, self.king.x self.colors[coord] = o.app.render.kingcolor def _render_colors(self): for coord, color in self.colors.items(): y, x = coord self.screen.chgat(y, x, 1, curses.color_pair(color)) def _reset_buffers(self): self.buffer = dict() self.colors = dict() def render(self): self._render_buffer() if o.app.render.trail: self._render_trail() if o.app.render.king: self._render_king() self._render_colors() self._reset_buffers() def handle_keys(self): self.paused = False c = self.screen.getch() if c == -1: return True # drawmode if c == o.app.binds.drawmode: self.draw = not self.draw self.screen.clear() elif c == o.app.binds.trail: if o.app.render.trail: o.app.render.trail = False else: o.app.render.trail = True # quit elif c == o.app.binds.quit: return False # delay up elif c == o.app.binds.delayup: self.delay = min(o.app.render.maxdelay, self.delay + o.app.render.delaydiff) # delay down elif c == o.app.binds.delaydown: self.delay = max(o.app.render.mindelay, self.delay - o.app.render.delaydiff) # pause elif c == o.app.binds.pause: self.paused = not self.paused return True def handle_timeout(self): new_total = sum(e.genome.simscore for e in self.peaters) if new_total == self.total_score: self.stale_ticks += 1 else: self.stale_ticks = 0 self.total_score = new_total if self.stale_ticks > o.ga.general.staleticks: return False return True def handle_agents(self): for p in self.peaters: p.update(self.world, self.colors) if self.king is None or p.genome.simscore > self.king.genome.simscore: if self.king: for y, x in self.king.trail: self.screen.chgat(y, x, 1, curses.color_pair(1)) self.king.trail[y, x] = True self.king = p for coord in self.king.trail: self.king.trail[coord] = True return True def run(self): iterations = 0 running = True if self.draw: self.screen.clear() while running: running = (self.handle_agents() and self.handle_keys() and self.handle_timeout()) if self.draw: self.render() self.screen.clearok(0) self.screen.refresh() sleep(self.delay) iterations += 1 if not self.draw: self.screen.move(0, 0) gen = self.ga.currentGeneration msg = self.ga.internalPop.printStats() self.screen.addstr(0, 0, "%s (%s): %s" % (gen, self.delay, msg)) self.screen.clearok(1) self.screen.refresh()