def main(): display = Display(CONTROL_PORT, spi_channel=SPI_CHANNEL, spi_clock=SPI_CLOCK) graphics = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, 3000) static_graphics = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, NUM_COLS) static_mask = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, NUM_COLS) frame_index = 0 last_update = 0 for line in range(5): display.set_scroll_step_x(line, 0) display.set_scroll_interval_x(line, 0) display.set_scroll_width(line, 0, 0) display.set_blink_interval_on(line, 0) display.set_blink_interval_off(line, 0) display.set_scroll_position_x(line, 0) last_time = 0 while True: now = time.time() if (now - last_time > 1): graphics.clear() graphics.text("%H:%M:%S", font="NovaMono", size=80, timestring=True) display.send_graphics(graphics) last_time = now for line in range(5): display.set_scroll_step_x(line, 1) display.set_scroll_interval_x(line, 1) display.set_scroll_width(line, 240, 0) #display.set_blink_interval_on(line, 20) #display.set_blink_interval_off(line, 20) """ time.sleep(1) for line in range(5): display.set_scroll_stop_position_x(line, line*7+4, 1) """ """
class Game(object): ''' Handles a game instance ''' def __init__(self): ''' Initialize starting state''' self.graphics = Graphics() self.log = logging.getLogger("Game"); logging.basicConfig(filename='main.log', level=DEBUG_LEVEL) self.log_handler = CursesHandler(self.graphics.windows["log"]) self.log_handler.setLevel(DEBUG_LEVEL) self.log.addHandler(self.log_handler) self.commands = Commands(self) self.cursor_pos = [0,0] self.game_mode = GameModes.normal self.world = World(log_handler=self.log_handler) try: # Try to load a level from a text file and add it to the world # self.world.add_level(self.world.read_level('../data/testworld')) # self.world.get_current_level().add_entity(entity.creatures.SpaceOrk(5,5)) self.world.add_level( self.world.generate_level( self.graphics.max_x, self.graphics.world_height)) #Place player at spawn self.player = entity.creatures.Player(1,1) for ent in self.world.get_current_level().entities: if ent.__class__ == entity.world.PlayerSpawn: self.player = entity.creatures.Player(ent.position[0],ent.position[1]) self.world.get_current_level().add_entity(self.player) except Exception: # use better exception self.exit(1) self.log.debug("Game started") def run(self): ''' Draw the world and get input ''' try: self.graphics.draw_world(self.world) self.graphics.show_stats(self.player) self.graphics.update() while True: self.parse_command(self.graphics.get_input()) if self.game_mode == GameModes.cursor or self.game_mode == GameModes.look: self.graphics.clear() self.graphics.draw_world(self.world) self.graphics.draw_cursor(self.cursor_pos) if self.game_mode == GameModes.look: for ent in self.world.get_current_tile(self.cursor_pos): self.log.info(ent.name) self.graphics.show_stats(self.player) self.graphics.update() except (Exception, KeyboardInterrupt): self.exit(1) def turn(self): ''' Take a turn; redraw world, run ai... ''' try: for ent in self.world.get_current_level().entities: if hasattr(ent, "die"): if ent.die(): continue if issubclass(ent.__class__, entity.base.Creature): ent.turn(self.player) self.graphics.clear() self.graphics.draw_world(self.world) except (Exception, KeyboardInterrupt): self.exit(1) def exit(self, status): ''' Shutdown curses, close files, and print errors if any''' self.log.debug("exiting") self.graphics.exit() if sys.exc_info()[2] is not None: print(traceback.format_exc()) sys.exit(status) def parse_command(self, command): ''' Executes the function associated with a command string ''' self.log.debug(command) if hasattr(self.commands, command): try: self.commands.__class__.__dict__[command](self.commands) except (Exception, KeyboardInterrupt): self.exit(1) else: self.log.error("Command not found")
def main(): display = Display(CONTROL_PORT, spi_channel=SPI_CHANNEL, spi_clock=SPI_CLOCK) graphics = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, 3000) static_graphics = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, NUM_COLS) static_mask = Graphics(NUM_COLS, NUM_ROWS, NUM_LINES, NUM_COLS) # Set up the Google Calendar API # The file token.json stores the user's access and refresh tokens, and is # created automatically when the authorization flow completes for the first # time. store = file.Storage('gapi_token.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets('gapi_credentials.json', SCOPES) creds = tools.run_flow(flow, store) service = build('calendar', 'v3', http=creds.authorize(Http())) for line in range(5): display.set_scroll_step_x(line, 1) display.set_scroll_interval_x(line, 1) display.set_scroll_width(line, 30, 1) display.set_blink_interval_on(line, 0) display.set_blink_interval_off(line, 0) display.set_scroll_position_x(line, 0) display.set_scroll_enabled_x(line, 0) display.set_auto_scroll_enabled_x(line, 1) display.set_auto_scroll_reset_enabled_x(line, 1) last_display_update = 0 # Last display update timestamp last_calendar_update = 0 # Last calendar update timestamp last_calendar_entry_cycle = 0 # Timestamp when the displayed calendar entry last changed current_calendar_entry_page = 0 # Which of the upcoming calendar entries are currently being displayed calendar_entries_per_page = 4 # How many lines of calendar entries to show event_texts = [] displayed_event_texts = [] while True: now = time.time() if now - last_calendar_update > 600: last_calendar_update = now # Call the Google Calendar API dt_now = datetime.datetime.utcnow().isoformat( ) + 'Z' # 'Z' indicates UTC time events_result = service.events().list( calendarId='primary', timeMin=dt_now, maxResults=12, singleEvents=True, orderBy='startTime').execute() calendar_events = events_result.get('items', []) for event in calendar_events: event_start = event.get('start') has_start_time = 'dateTime' in event_start if has_start_time: start_dt = datetime.datetime.strptime( event_start.get('dateTime')[:19] + event_start.get('dateTime')[19:].replace(":", ""), "%Y-%m-%dT%H:%M:%S%z") else: start_dt = datetime.datetime.strptime( event_start.get('date'), "%Y-%m-%d") event_end = event.get('end') has_end_time = 'dateTime' in event_end if has_end_time: end_dt = datetime.datetime.strptime( event_end.get('dateTime')[:19] + event_end.get('dateTime')[19:].replace(":", ""), "%Y-%m-%dT%H:%M:%S%z") else: # Substract one day because the API reports the end as one day later than it actually is... end_dt = datetime.datetime.strptime( event_end.get('date'), "%Y-%m-%d") - datetime.timedelta(days=1) event_text = "" if has_start_time: event_text += start_dt.strftime("%d.%m. %H:%M") else: event_text += start_dt.strftime("%d.%m.") if has_end_time: if end_dt.date() == start_dt.date(): event_text += "-" + end_dt.strftime("%H:%M") else: event_text += "-" + end_dt.strftime("%d.%m. %H:%M") else: if end_dt.date() != start_dt.date(): event_text += "-" + end_dt.strftime("%d.%m.") event_text += " " + unidecode(event.get('summary')).upper() event_texts.append(event_text) if now - last_calendar_entry_cycle > 5: current_calendar_entry_page += 1 if ((current_calendar_entry_page + 1) * calendar_entries_per_page ) - len(event_texts) >= calendar_entries_per_page: current_calendar_entry_page = 0 last_calendar_entry_cycle = now base_index = current_calendar_entry_page * calendar_entries_per_page displayed_event_texts = event_texts[base_index:base_index + calendar_entries_per_page] if now - last_display_update > 1: last_display_update = now graphics.clear() graphics.text("%H:%M:%S", halign='left', valign='top', font="Luminator7_Bold", timestring=True) graphics.text("INFOSCREEN", halign='center', valign='top', font="Luminator7_Bold") graphics.text("%d.%m.%Y", halign='right', valign='top', font="Luminator7_Bold", timestring=True) for i, event_text in enumerate(displayed_event_texts): graphics.text(event_text, halign='left', top=7 * (i + 1), font="Luminator7_Bold") display.send_graphics(graphics)
class App: def __init__(self, settings): ### NAME OF SAVE ### self.savename = "NN" self.simulation = False self.settings = settings ### INIT WINDOW ### self.window = pyglet.window.Window(fullscreen=True, resizable=True) self.window.set_caption("NEURAL NETWORK RACING by Tomas Brezina") if not self.window.fullscreen: self.window.set_size(settings["WIDTH"], settings["HEIGHT"]) ### LOAD ICON ### try: icon = pyglet.image.load("graphics/icon.ico") self.window.set_icon(icon) except: print("Error >>> Loading icon") ### MODULES ### self.simulation = None self.graphics = Graphics(self.window) ### LABELS ### self.graphics.labels["name"].text = self.savename ### VARIABLES ### self.show = False # show track, cps, etc. self.pause = False # pause the simulation self.timer = 0 # number of ticks self.timer_limit = self.settings["timeout_seconds"] // self.settings["render_timestep"] # max ticks ### BIND EVENTS ### self.window.event(self.on_key_release) self.window.event(self.on_close) self.window.event(self.on_resize) self.window.event(self.on_draw) # when key is released def on_key_release(self,symbol, modifiers): # save the nn if symbol == key.S: if self.savename and self.simulation.best_nn: _save_stg = self.simulation.save_stg _save_stg["generations"] = self.simulation.gen_count _save_stg["best_result"] = self.simulation.max_score save_neural_network( name=self.savename, weigts=self.simulation.best_nn.weights, settings=self.simulation.save_stg, folder="saves" ) # fullscreen on/off if symbol == key.F: self.window.set_fullscreen(not self.window.fullscreen) if not self.window.fullscreen: self.window.set_size(self.settings["WIDTH"], self.settings["HEIGHT"]) # pause on/off if symbol == key.P: self.pause = not self.pause # show on/off if symbol == key.O: self.show = not self.show # when closed (unnecessary) def on_close(self): pyglet.clock.unschedule(self.update) # when resized def on_resize(self, width, height): _scale = width / self.settings["WIDTH"] self.graphics.change_scale(_scale) self.simulation.track.change_scale(_scale) # every frame def on_draw(self): self.graphics.clear() if self.simulation.track.bg: self.graphics.draw_bg(self.simulation.track.bg) self.graphics.car_batch.draw() self.graphics.draw_labels() # draw hidden details if self.show: for car in self.simulation.cars: self.graphics.draw_car_sensors(car) # draw checkpoints self.graphics.draw_cps(self.simulation.track.cps_dict) # draw edge of the track self.graphics.draw_lines(self.simulation.track.vertex_list) else: if not self.simulation.track.bg: self.graphics.draw_lines(self.simulation.track.vertex_list) # create new generation from best nns def new_generation(self): self.graphics.labels["gen"].text = "Generation: " + str(int(self.simulation.gen_count)) self.graphics.clear_batch() self.simulation.new_generation( best_nns=self.simulation.get_best_nns(), population=self.settings["population"], mutation_rate=self.settings["mutation_rate"], images=self.graphics.car_images, batch=self.graphics.car_batch ) self.graphics.update_sprites(self.simulation.cars) self.graphics.labels["max"].text = "Best score: " + str(self.simulation.max_score) # every frame def update(self,dt): if not self.pause: # car behaviour active = self.simulation.behave(dt) if not active: self.timer = 0 self.new_generation() self.simulation.update(dt) # update sprites position and rotation self.graphics.update_sprites(self.simulation.cars) self.timelimit() # each tick def timelimit(self): self.timer += 1 if self.timer >= self.timer_limit: self.timer = 0 self.new_generation() seconds = int(self.timer * self.settings["render_timestep"]) self.graphics.labels["time"].text = "Time: " + str(seconds) + " / " + str(self.settings["timeout_seconds"]) # start of simulation def start_simulation(self, track, nn_stg, nn_weights=False, name="New NN"): # init simulation self.savename = name self.simulation = Simulation(track, nn_stg) self.simulation.friction = self.settings["friction"] # set labels self.graphics.labels["name"].text = self.savename[:10] self.graphics.labels["gen"].text = "Generation: " + str(int(self.simulation.gen_count)) self.graphics.labels["max"].text = "Best score: " + str(self.simulation.max_score) # new save or loaded one if nn_weights == False: self.simulation.first_generation( shape=self.simulation.save_stg["SHAPE"], population=self.settings["population"], mutation_rate=self.settings["mutation_rate"], images=self.graphics.car_images, batch=self.graphics.car_batch ) else: nn = NeuralNetwork(self.simulation.save_stg["SHAPE"]) nn.set_weights(nn_weights) self.simulation.load_generation( nn=nn, population=self.settings["population"], mutation_rate=self.settings["mutation_rate"], images=self.graphics.car_images, batch=self.graphics.car_batch ) self.graphics.update_sprites(self.simulation.cars) self.on_resize(self.window.width, self.window.height) pyglet.clock.schedule_interval(self.update, self.settings["render_timestep"]) pyglet.app.run() def end_simulation(self): pyglet.clock.unschedule(self.update) statistics = self.simulation.statistics self.simulation = False return statistics # end def exit(self): pyglet.app.exit()
class Game: def __init__(self, port): self.running = False self.pid = 0 self.pids = [] self.nbPlayer = 0 self.players = {} self.entities = {} self.moves = [] self.shoot = False self.shoots = [] self.deads = [] self.killed = [] self.input = Input() self.graphics = Graphics() self.velocity = Constant.VELOCITY self.id = 0 self.port = port self.players_socket = {} self.players_socket_awaiting = {} self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind(('', self.port)) self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.listen(5) def init(self, name, nbEntity, nbPlayer = 1, pids = None): self.id = nbPlayer self.players[self.id] = Player(name) self.nbPlayer = nbPlayer self.pids = pids if pids else list(range(1, nbEntity + 1)) self.pid = self.pids[random.randrange(len(self.pids))] self.pids.remove(self.pid) def connect(self, ip, port, name): print("Connecting to ({}, {})...".format(ip, port)) player_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) player_socket.connect((ip, port)) message = self.receive(player_socket) if message.type & Message.OK and message.type & Message.INIT: (nbPlayer, pids, entities) = message.data self.init(name, 0, nbPlayer, pids) for (pid, position) in entities: self.entities[pid] = self.entity(position.x, position.y) n = nbPlayer - 2 self.players_socket[message.id] = player_socket self.notify(player_socket, Message.OK | Message.PORT, self.port) while n: player_socket, addr = self.socket.accept() print("Accepting new connection from", addr) self.notify(player_socket, Message.OK | Message.ID, None) message = self.receive(player_socket) if message.type & Message.OK and message.type & Message.ID: self.players_socket[message.id] = player_socket else: print("Can't join") self.disconnect() return self.notify(player_socket, Message.OK | Message.DONE, None) n -= 1 self.run() def connectTo(self, ip, port): print("Connecting to ({}, {})...".format(ip, port)) player_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) player_socket.connect((ip, port)) self.players_socket_awaiting[self.nbPlayer] = player_socket def disconnect(self): print("Disconnecting...") self.socket.close() if self.nbPlayer > 1: player_socket = next(iter(self.players_socket.values())) data = [[(pid, entity.position) for (pid, entity) in self.entities.items()]] self.notify(player_socket, Message.OK | Message.MOVE, data) time.sleep(0.05) # NEEDED : Wait at least one loop from the remote player self.notify(player_socket, Message.OK | Message.INIT, self.pids + [self.pid]) time.sleep(0.05) self.notifyAll(Message.OK | Message.DISCONNECT | Message.STRING, "Disconnecting...") for s in self.players_socket.values(): s.shutdown(socket.SHUT_WR) while len(self.players_socket): self.handleMessages(self.handleDisconnected) self.running = False print("Disconnected") def new(self, name, nbEntity): print("Game created") print("Listening on port", self.port) self.init(name, nbEntity) for i in range(1, nbEntity + 1): self.entities[i] = self.entity(random.randrange(Constant.WIDTH), random.randrange(Constant.HEIGHT)) self.run() def run(self): self.running = True self.graphics.createWindow(Constant.WIDTH, Constant.HEIGHT) t = time.time() while self.running: dt, t = self.getDt(t) self.clear() self.handleConnections() self.handleMessages(self.handleMessage) self.handleInputs(dt) self.update(dt) self.sendMessages() self.render() # NETWORK HANDLER def handleConnection(self, connection): player_socket, addr = connection.accept() self.nbPlayer += 1 player_pids, self.pids = self.pids[:len(self.pids)//2+1], self.pids[len(self.pids)//2+1:] data = (self.nbPlayer, player_pids, [(pid, self.entities[pid].position) for pid in player_pids]) self.notify(player_socket, Message.OK | Message.INIT, data) self.players_socket_awaiting[self.nbPlayer] = player_socket print("Accepting new connection from", addr) def handleConnections(self): connections, wlist, xlist = select.select([self.socket], [], [], 0.05) for connection in connections: self.handleConnection(connection) def handleMessage(self, player_socket): message = self.receive(player_socket) if message.type & Message.OK: if message.type & Message.CONNECT: self.nbPlayer += 1 (host, port) = message.data self.connectTo(host, port) elif message.type & Message.INIT: self.pids.extend(message.data) elif message.type & Message.DISCONNECT: self.nbPlayer -= 1 self.notify(player_socket, Message.OK | Message.DISCONNECTED, None) player_socket.shutdown(socket.SHUT_RDWR) player_socket.close() del self.players_socket[message.id] elif message.type & Message.ID: self.notify(player_socket, Message.OK | Message.ID, None) elif message.type & Message.PORT: self.notifyAll(Message.OK | Message.CONNECT, (player_socket.getpeername()[0], message.data)) self.players_socket[message.id] = self.players_socket_awaiting[message.id] del self.players_socket_awaiting[message.id] elif message.type & Message.DONE: self.players_socket[message.id] = self.players_socket_awaiting[message.id] del self.players_socket_awaiting[message.id] if message.type & Message.MOVE: for (pid, position) in message.data[0]: if pid in self.entities: self.entities[pid].position = position else: self.entities[pid] = self.entity(position.x, position.y) if message.type & Message.SHOOT: self.shoots.append(message.id) if message.type & Message.DEAD: self.killed.extend(message.data[1]) #elif message.type & Message.STRING: # print(message) def handleDisconnected(self, player_socket): message = self.receive(player_socket) if message.type & Message.OK and message.type & Message.DISCONNECTED: player_socket.close() del self.players_socket[message.id] def handleMessages(self, f): players_socket = [] if len(self.players_socket) + len(self.players_socket_awaiting): try: players_socket, wlist, xlist = select.select(list(self.players_socket.values()) + list(self.players_socket_awaiting.values()), [], [], 0.05) for player_socket in players_socket: f(player_socket) except select.error as e: #print(e) pass # GAME HANDLER def handleInputs(self, dt): # Get keyboard inputs actionKeys = self.input.update() # Create action for (actionType, obj) in actionKeys: if actionType == pygame.QUIT: self.disconnect() elif actionType == pygame.KEYDOWN: if obj == pygame.K_ESCAPE: self.disconnect() elif obj == pygame.K_SPACE: self.shoot = True # Get player action dx = 0 dy = 0 if self.input.getKeyDown(pygame.K_LEFT): dx = int(-self.velocity * dt) if self.input.getKeyDown(pygame.K_RIGHT): dx += int(self.velocity * dt) if self.input.getKeyDown(pygame.K_UP): dy = int(-self.velocity * dt) if self.input.getKeyDown(pygame.K_DOWN): dy += int(self.velocity * dt) if self.input.getKeyDown(pygame.K_w): self.velocity = max(self.velocity - 5, 5) if self.input.getKeyDown(pygame.K_x): self.velocity = min(self.velocity + 5, 80) if dx != 0 or dy != 0: self.entities[self.pid].move(dx, dy, Constant.WIDTH, Constant.HEIGHT) self.moves.append(self.pid) # NETWORK UTILITY def notify(self, player, type, data): try: player.sendall(pickle.dumps(Message(self.id, type, data))) #print("Sending -> ", Message(self.id, type, data)) except: pass def notifySome(self, players, type, data): for player in players: self.notify(player, type, data) def notifyAll(self, type, data): self.notifySome(self.players_socket.values(), type, data) def receive(self, s): BUFFER_SIZE = 4096 data = b'' while True: data += s.recv(BUFFER_SIZE) if not data: return Message(0, Message.ERROR, None) else: if data.endswith(b'.'): m = pickle.loads(data) print(m) return m def sendMessages(self): data = [[], []] data_move = [] move = Message.NOTHING data_shoot = [] shoot = Message.NOTHING data_deads = [] deads = Message.NOTHING if len(self.moves): move = Message.MOVE data[0] = [(pid, self.entities[pid].position) for pid in self.moves] if self.shoot: shoot = Message.MOVE | Message.SHOOT data_shoot = [(self.pid, self.entities[self.pid].position)] if len(self.deads): deads = Message.DEAD data_deads = [pid for pid in self.deads] data[0].extend(data_move) data[0].extend(data_shoot) data[1].extend(data_deads) if move or shoot or deads: self.notifyAll(Message.OK | move | shoot | deads, data) # GAME UTILITY def getDt(self, lastTime): t = time.time() dt = t - lastTime return dt, t def entity(self, x, y): return Entity(x, y, (random.randrange(256), random.randrange(256), random.randrange(256))) def clear(self): self.shoot = False self.moves.clear() self.shoots.clear() self.deads.clear() self.killed.clear() def update(self, dt): for pid in self.pids: if self.entities[pid].behave(dt, Constant.WIDTH, Constant.HEIGHT): self.moves.append(pid) for pid_shoot in self.shoots: for pid in self.pids: if self.entities[pid].collide(self.entities[pid_shoot], Constant.DEFAULT_RADIUS, Constant.FIRING_RADIUS): del self.entities[pid] self.deads.append(pid) for pid in self.killed: del self.entities[pid] def render(self): self.graphics.clear() self.graphics.renderEntities(self.entities, self.pid, self.shoot, self.shoots) self.graphics.displayTopScore(self.players) self.graphics.displayOverlay(Constant.VELOCITY, Constant.HEIGHT) self.graphics.flip()
class Master: frames = 0 def __init__(self, snake_picker=None, snake_getter=None): self.master = tk.Tk() canvas = tk.Canvas( self.master, width=WINDOW_SIZE[0], height=WINDOW_SIZE[1]) self.pick_snake = snake_picker self.get_snake_number = snake_getter self.init_snake() self.free_space = [] self.calculate_free_space() self.food = Food(self.free_space) self.graphics = Graphics(canvas) self.bind_events() def bind_events(self): self.graphics.bind_event( "<Up>", lambda event: events.move_up(self.snake)) self.graphics.bind_event( "<Right>", lambda event: events.move_right(self.snake)) self.graphics.bind_event( "<Left>", lambda event: events.move_left(self.snake)) self.graphics.bind_event( "<Down>", lambda event: events.move_down(self.snake)) self.graphics.bind_event( "<Return>", lambda event: events.eat(self.snake)) def calculate_free_space(self): snake_body = self.snake.get_body() self.free_space = [] for i in range(DIMENSIONS[0][0], DIMENSIONS[0][1]+1, self.snake.get_grid()): for j in range(DIMENSIONS[1][0], DIMENSIONS[1][1]+1, self.snake.get_grid()): if [i, j] not in snake_body: self.free_space.append([i, j]) def init_snake(self): if self.pick_snake is None: self.snake = Snake( [DEFAULT_LOCATION[0], DEFAULT_LOCATION[1]], DEFAULT_LENGHT) else: self.snake = self.pick_snake() self.reset_food() self.snake.bind_death_event(self.init_snake) self.snake.bind_eat_event(self.handle_feed) def handle_feed(self, food_location): self.calculate_free_space() self.food.respawn_piece(self.free_space, food_location) def reset_food(self): self.calculate_free_space() self.food = Food(self.free_space) def start(self): self.loop() self.master.mainloop() def update_food(self): if self.frames == 2000: self.reset_food() self.frames = 0 self.frames += 1 def loop(self): self.graphics.clear() self.draw() self.snake.move(DIMENSIONS, self.food.get_locations()) self.master.after(MIL_SEC_PER_FRAME, self.loop) def draw(self): snake_body = self.snake.get_body() snake_size = self.snake.get_size() self.graphics.draw(snake_body, snake_size, "white") self.graphics.draw(self.food.get_locations(), snake_size, "red") # self.graphics.see(self.snake.get_location(), # self.snake.get_grid(), # DIMENSIONS) self.graphics.write(str(self.snake.get_score()), [20, 20]) if self.get_snake_number is not None: self.graphics.write(str(self.get_snake_number()), [40, 20])