def check_collisions(snake: Snake, screen: pygame.Surface, goal: Goal, field: Field) -> bool: head = snake.head() if screen.get_at(head) == WHITE: if head in goal: goal.move_to(generate_goal_area(snake=snake, field=field)) snake.grow() else: return False return True
def threaded_client(conn, addr): global food, players players[addr] = Snake(5, 6, 20, (random.randint(0, 255), random.randint( 0, 255), random.randint(0, 255))) conn.send(pickle.dumps((players[addr], addr))) while True: try: data = pickle.loads(conn.recv(2048)) players[addr] = data if not data: print("Disconnecting") break else: for i in players: if players[i].bodies[0][0] == food[0] and players[ i].bodies[0][1] == food[1]: players[i].eat() food = (random.randint(1, 24), random.randint(1, 24)) for q in players: if players[q] != players[addr]: if players[addr].bodies[0] in players[q].bodies: quit() conn.sendall(pickle.dumps((players, food))) except: break players.pop(addr) conn.close()
def init_game_state(): r"""初始化游戏 :return: 蛇对象,食物对象 """ snake = Snake(SNAKE_POS_X, SNAKE_POS_Y, SNAKE_INIT_LEN) food = gen_food(snake) return snake, food
def __init__(self): super().__init__() self.timer = 0 self.is_paused = False self.has_crashed = False self.event_painted = False self.show_grid = False self.play_music() # Create background from random texture i = random.getrandbits(1) + 1 self.background = build_background( resources.get_image(f"snake-tile{i}")) # Create objects snake and apple if not settings.get_setting("classic"): apple_skin, snake_skin = self.split_sprites( resources.get_sprite("sheet")) else: apple_skin, snake_skin = None, None self.sneik = Snake() self.sneik.load_skin(snake_skin) self.apple = Apple(self.sneik.body, apple_skin)
def main(): pygame.init() screen = pygame.display.set_mode(SIZE) clock = pygame.time.Clock() noto_sans = pygame.font.Font('NotoSans-Regular.ttf', 12) field = Field(area=Rect(x=10, y=50, w=WIDTH - 20, h=HEIGHT - 60)) snake = Snake( starting_point=random_point(offset=100, area=field.client_area())) score = Score(font=noto_sans, position=Point(x=10, y=10)) goal = Goal(area=generate_goal_area(snake=snake, field=field)) controller = KeyboardController( snake=snake, start_direction=random_direction(), key_map=KeyMap( up=pygame.K_UP, down=pygame.K_DOWN, left=pygame.K_LEFT, right=pygame.K_RIGHT # up=pygame.K_w, down=pygame.K_s, left=pygame.K_a, right=pygame.K_d )) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False controller.handle_event(event) if not running: break score.update(score=len(snake)) screen.fill(BLACK) for go in [field, snake, score, goal]: go.draw_to(screen) pygame.display.flip() controller.update() running = check_collisions(snake, screen, goal, field) clock.tick(120) print(f'Game over! Your score: {len(snake)}') pygame.quit()
def __init__(self, caption, width, height, frame_rate): """ Args: caption(str): name of the game width(int): width of surface height(int): height of surface frame_rate(int): speed of the game """ pygame.init() self.score = 0 self.text = TextObject(0, 0, (0, 0, 0), 'Score: {}'.format(self.score), 'monaco', 36) self.width = width self.height = height self.side_of_square = 15 self.default_length = 3 body_snake = [ ((width // 100) * self.side_of_square - self.side_of_square * i, (height // 200) * self.side_of_square) for i in range(self.default_length) ] self.objects = { 'Snake': Snake(body_snake, self.side_of_square, 'RIGHT', (0, 255, 0)), 'Apple': Apple( random.randrange(0, width // self.side_of_square) * self.side_of_square, random.randrange(0, height // self.side_of_square) * self.side_of_square, self.side_of_square, (255, 0, 0), self.width, self.height) } self.surface = pygame.display.set_mode((width, height)) self.frame_rate = frame_rate self.game_over = False pygame.display.set_caption(caption) self.time = time.time() self.bonus_apple = False self.clock = pygame.time.Clock()
def __init__(self, rows): pygame.init() pygame.font.init() height = 500 width = 500 self._rows = rows self.__grid = GameGrid.GameGrid(rows) self.__wn = pygame.display.set_mode((height, width)) blockSize = height / rows block1 = Block.Block(rows / 2 * blockSize, rows / 2 * blockSize, "white", blockSize) block2 = Block.Block(rows / 2 * blockSize + blockSize, rows / 2 * blockSize, "white", blockSize) snakeBlocks = [block1, block2] self.__snake = Snake.Snake(snakeBlocks, width) self.__apple = Apple.Apple( int(random.random() * width / blockSize) * blockSize, int(random.random() * width / blockSize) * blockSize, blockSize, width) self.__score = Score.Score(width - blockSize * 1.2, 0, "black", "") self.__highScore = Score.Score(0, 0, "black", "High: ")
def run(): alpha = 0.15 #learning rate gamma = 0.7 #discount factor epsilon = 0 #exploration value demoEpsilon = 0 #Epsilon value for the demo mode dynamicEpsilon = False #If True, the exploration rate will be reducing as more of the state-space is dicovered, if False the rate will be static training_episodes = 1000000 deathAfter = 250 #Kill the snake after a certain number of moves to prevent it from getting stuck in a cycle qTableSave = os.path.join(os.sys.path[0], "saves", "QTable.txt") counterSave = os.path.join(os.sys.path[0], "saves", "GameCounter.txt") fps = 30 displayMode = "Demo" # Load existing Q-Table and episode counter or create new ones numberOfStates = init_state_dict() Q = np.zeros((numberOfStates, len(actions))) try: Q = np.loadtxt(qTableSave).reshape(numberOfStates, len(actions)) except: print("Could not load an existing Q-Table") try: counterFile = open(counterSave, "r") startEpisode = int(counterFile.read()) counterFile.close() except: startEpisode = 0 highscore = 0 for episode in range(startEpisode, training_episodes + 1): killApp = False try: if (episode % 100 == 0): count = 0 qFile = open(qTableSave, "w") for row in Q: if not "0. 0. 0." in str(row): count += 1 np.savetxt(qFile, row) qFile.close() counterFile = open(counterSave, "w") counterFile.write(str(episode)) counterFile.close exploredPercentage = count / (numberOfStates) if dynamicEpsilon: if exploredPercentage < 0.95: epsilon = ( 1 - exploredPercentage ) / 2 #Reduce exploration value as more states get explored else: epsilon = 0.05 print( str(exploredPercentage * 100) + "%" + " of state-space explored") except: print("Save error") # Initialise the game grid and the score counter score = 0 grid = [] for x in range(width): grid.append([]) for y in range(height): grid[x].append(0) # Create the snake and the apple head = Segment(width / 2, height / 5) body = Segment(head.X, head.Y + 1) tail = Segment(body.X, head.Y + 1) head.setNext(body) body.setNext(tail) snake = Snake(head, tail) apple = Apple(width, height) startStateID = state_dict[getState(snake, apple)] nextStateID = startStateID prevDistToApple = distanceToApple(snake, apple) deathCountdown = deathAfter #Game loop finished = False paused = False while not finished: for event in pygame.event.get(): if event.type == pygame.QUIT: killApp = True # Pause/unpause, switch the mode between training and demo keyPressed = pygame.key.get_pressed() if keyPressed[pygame.K_SPACE]: paused = True elif keyPressed[pygame.K_RETURN]: paused = False elif keyPressed[pygame.K_UP]: fps = 10000 displayMode = "Training" dynamicEpsilon = True elif keyPressed[pygame.K_DOWN]: fps = 30 displayMode = "Demo" dynamicEpsilon = False epsilon = demoEpsilon elif keyPressed[pygame.K_END]: killApp = True if not paused: reward = 0 stateID = nextStateID # Choose action if random.uniform(0, 1) < epsilon: unexplored = False for i in range( 0, 3 ): #Unlike classic Q-Learning, the algorithm prefers to go to a previously unexplored state, instead of choosing an action randomly if Q[stateID, i] == 0.: actionID = i unexplored = True break if not unexplored: #If no unexplored states were found, choose a random action actionID = random.randint(0, 2) else: actionID = np.argmax(Q[stateID]) # Change direction if actions[actionID] != "wait": if snake.direction == "up": snake.direction = actions[actionID] elif snake.direction == "down": if actions[actionID] == "right": snake.direction = "left" if actions[actionID] == "left": snake.direction = "right" elif snake.direction == "left": if actions[actionID] == "right": snake.direction = "up" if actions[actionID] == "left": snake.direction = "down" elif snake.direction == "right": if actions[actionID] == "right": snake.direction = "down" if actions[actionID] == "left": snake.direction = "up" snake.move() distToApple = distanceToApple(snake, apple) # Check if collected an apple if snake.head.X == apple.X and snake.head.Y == apple.Y: snake.grow() score += 1 if score > highscore: highscore = score reward += 500 deathCountdown = deathAfter appleGen = False while not appleGen: apple.generate() if grid[apple.X][apple.Y] == 0: appleGen = True prevDistToApple = distanceToApple(snake, apple) else: deathCountdown -= 1 distToApple = distanceToApple(snake, apple) if distToApple >= prevDistToApple: reward -= 5 else: reward += 1 prevDistToApple = distToApple # Death check if snake.isDead(height, width) or deathCountdown <= 0: finished = True reward -= 10000 nextStateID = startStateID oldQ = Q[stateID, actionID] nextMax = -10000 updatedQ = (1 - alpha) * oldQ + alpha * (reward + gamma * nextMax) Q[stateID, actionID] = updatedQ else: nextState = getState(snake, apple) nextStateID = state_dict[nextState] nextMax = np.max(Q[nextStateID]) oldQ = Q[stateID, actionID] updatedQ = (1 - alpha) * oldQ + alpha * (reward + gamma * nextMax) Q[stateID, actionID] = updatedQ draw(grid, snake, apple, score, episode, highscore, displayMode) clock.tick(fps) if killApp == True: break if killApp == True: break
def game(): # Setup score = 0 global highscore grid = [] for x in range(width): grid.append([]) for y in range(height): grid[x].append(0) head = Segment(width / 2, height / 5) body = Segment(head.X, head.Y + 1) tail = Segment(body.X, head.Y + 1) head.setNext(body) body.setNext(tail) snake = Snake(head, tail) apple = Apple(width, height) #Game loop finished = False while not finished: for event in pygame.event.get(): if event.type == pygame.QUIT: finished = True # Change direction keyPressed = pygame.key.get_pressed() if snake.direction == "up" or snake.direction == "down": if keyPressed[pygame.K_RIGHT]: snake.direction = "right" if keyPressed[pygame.K_LEFT]: snake.direction = "left" if snake.direction == "right" or snake.direction == "left": if keyPressed[pygame.K_UP]: snake.direction = "up" if keyPressed[pygame.K_DOWN]: snake.direction = "down" snake.move() # Check if collected an apple if snake.head.X == apple.X and snake.head.Y == apple.Y: snake.grow() score += 1 if score > highscore: highscore = score appleGen = False while not appleGen: apple.generate() if grid[apple.X][apple.Y] == 0: appleGen = True # Death check if snake.isDead(height, width): finished = True break draw(grid, snake, apple, score) clock.tick(fps) gameOver()
def run(): deathAfter = 250 #Kill the snake after a certain number of moves to prevent it from getting stuck in a cycle qTableSave = os.path.join(os.sys.path[0], "saves", "QTableDemo.txt") fps = 30 # Load existing Q-Table numberOfStates = init_state_dict() Q = np.zeros((numberOfStates, len(actions))) try: Q = np.loadtxt(qTableSave).reshape(numberOfStates, len(actions)) except: print("Failed to load the Q-Table") highscore = 0 killApp = False while not killApp: # Initialise the game grid and the score counter score = 0 grid = [] for x in range(width): grid.append([]) for y in range(height): grid[x].append(0) # Create the snake and the apple head = Segment(width / 2, height / 5) body = Segment(head.X, head.Y + 1) tail = Segment(body.X, head.Y + 1) head.setNext(body) body.setNext(tail) snake = Snake(head, tail) apple = Apple(width, height) startStateID = state_dict[getState(snake, apple)] nextStateID = startStateID prevDistToApple = distanceToApple(snake, apple) deathCountdown = deathAfter #Game loop finished = False paused = False while not finished: for event in pygame.event.get(): if event.type == pygame.QUIT: killApp = True # Pause/unpause keyPressed = pygame.key.get_pressed() if keyPressed[pygame.K_SPACE]: paused = True elif keyPressed[pygame.K_RETURN]: paused = False elif keyPressed[pygame.K_END]: killApp = True if not paused: reward = 0 stateID = nextStateID # Choose action actionID = np.argmax(Q[stateID]) # Change direction if actions[actionID] != "wait": if snake.direction == "up": snake.direction = actions[actionID] elif snake.direction == "down": if actions[actionID] == "right": snake.direction = "left" if actions[actionID] == "left": snake.direction = "right" elif snake.direction == "left": if actions[actionID] == "right": snake.direction = "up" if actions[actionID] == "left": snake.direction = "down" elif snake.direction == "right": if actions[actionID] == "right": snake.direction = "down" if actions[actionID] == "left": snake.direction = "up" snake.move() distToApple = distanceToApple(snake, apple) # Check if collected an apple if snake.head.X == apple.X and snake.head.Y == apple.Y: snake.grow() score += 1 if score > highscore: highscore = score reward += 500 deathCountdown = deathAfter appleGen = False while not appleGen: apple.generate() if grid[apple.X][apple.Y] == 0: appleGen = True prevDistToApple = distanceToApple(snake, apple) else: deathCountdown -= 1 distToApple = distanceToApple(snake, apple) if distToApple >= prevDistToApple: reward -= 5 else: reward += 1 prevDistToApple = distToApple # Death check if snake.isDead(height, width) or deathCountdown <= 0: finished = True else: nextState = getState(snake, apple) nextStateID = state_dict[nextState] draw(grid, snake, apple, score, highscore) clock.tick(fps) if killApp == True: break if killApp == True: break
from constraints import Direction from objects import Snake, Board from welcome_window import create_preference_window try: speed, length, height = create_preference_window() tk = Tk() tk.title("snake") tk.resizable(False, False) board = Board(tk, length, height, bg='white') board.pack() snake = Snake(board, board.find_center_field()) egg = None def finish_step(): tk.quit() snake.move() while True: tk.after(speed, finish_step) if egg and snake.is_eat(egg): snake.is_growing = True board.delete(egg) egg = None else:
class SceneGame(SceneBase): """Scene with snakes biting things.""" def __init__(self): super().__init__() self.timer = 0 self.is_paused = False self.has_crashed = False self.event_painted = False self.show_grid = False self.play_music() # Create background from random texture i = random.getrandbits(1) + 1 self.background = build_background( resources.get_image(f"snake-tile{i}")) # Create objects snake and apple if not settings.get_setting("classic"): apple_skin, snake_skin = self.split_sprites( resources.get_sprite("sheet")) else: apple_skin, snake_skin = None, None self.sneik = Snake() self.sneik.load_skin(snake_skin) self.apple = Apple(self.sneik.body, apple_skin) @staticmethod def play_music(): """Load and play epic music.""" resources.load_music("snake-music-Rafael_Krux.ogg") pygame.mixer.music.play(-1) @staticmethod def split_sprites( sheet: pygame.Surface) -> Tuple[pygame.Surface, pygame.Surface]: """Return apple and snake sprites already resized. Parameter sheet should contain 4x3 sprites, with the apple in the bottom rigth corner.""" apple = sheet.subsurface((SPRITE_BLOCK[0] * 3, SPRITE_BLOCK[1] * 2, SPRITE_BLOCK[0], SPRITE_BLOCK[1])) apple = pygame.transform.scale(apple, (BLOCK[0], BLOCK[1])) snake = sheet snake = pygame.transform.scale(snake, (BLOCK[0] * 4, BLOCK[1] * 3)) return apple, snake def pause(self): """Pause game.""" pygame.mixer.music.pause() self.is_paused = True self.event_painted = False def unpause(self): """Unpause game.""" pygame.mixer.music.unpause() self.is_paused = False @staticmethod def draw_grid(screen: pygame.Surface): """Draw grid on screen, BLOCK sized rectangles.""" width, height = pygame.display.get_surface().get_size() # Vertical lines for i in range(width // BLOCK[0]): pygame.draw.line(screen, WHITE, (i * BLOCK[0], 0), (i * BLOCK[0], height), 1) # Horizontal lines for i in range(height // BLOCK[1]): pygame.draw.line(screen, WHITE, (0, i * BLOCK[1]), (width, i * BLOCK[1]), 1) def process_input(self, events, pressed_keys): for event in events: if not self.has_crashed: if self.is_paused: if (event.type == pygame.KEYDOWN and event.key == settings.get_key("pause")): self.unpause() else: if event.type == pygame.KEYDOWN: # Snake control, add new direction to queue if event.key in settings.get_key("direction"): self.sneik.queue_direction( event, settings.get_key("direction")) # UI control elif event.key == settings.get_key("grid"): self.show_grid = not self.show_grid elif event.key == settings.get_key("pause"): self.pause() def update(self, now): if not self.is_paused and not self.has_crashed: # Move snake self.sneik.move(now) # Check if snake ate apple if self.sneik.get_head() == self.apple.pos: resources.get_sound("eat").stop() resources.get_sound("eat").play() self.sneik.growing = True self.apple.new(self.sneik.body) # Check if snake crashed if self.sneik.check_collision(): resources.get_sound("crash").play() self.has_crashed = True self.event_painted = False self.timer = now pygame.mixer.music.stop() # Wait for 3 seconds from crash then switch to gameover scene elif self.has_crashed and now - self.timer > 3000: score = len(self.sneik.body) - 2 self.switch_to_scene(lambda: SceneGameOver(score)) def render(self, screen): width, height = pygame.display.get_surface().get_size() if not self.is_paused and (not self.has_crashed or (self.has_crashed and not self.event_painted)): # Draw background if not settings.get_setting("classic"): screen.blit(self.background, (0, 0)) else: # Classic look screen.fill(BGCOLOR) # Draw snake, apple, grid self.sneik.draw(screen) self.apple.draw(screen) if self.show_grid: self.draw_grid(screen) if self.has_crashed: self.event_painted = True elif self.has_crashed: # Add snake blood self.sneik.draw_blood(screen) # Paint pause screen once elif not self.event_painted: # Darken the screen surf = get_surface((width, height), BLACK, 160) screen.blit(surf, (0, 0)) # Show pause message font = resources.get_font("title100") text_surf, text_rect = render_text("Paused", font, WHITE) text_rect.center = width // 2, 250 screen.blit(text_surf, text_rect) font = resources.get_font("round30") text_surf, text_rect = render_text( f"Score: {len(self.sneik.body) - 2}", font, WHITE) text_rect.center = width // 2, 330 screen.blit(text_surf, text_rect) self.event_painted = True
from objects import Canvas, Snake from pynput.keyboard import Listener, Key import os canvas = Canvas(40, 60) snake = Snake(canvas, length=15) def game_tick(): os.system("clear") # print(snake.action_queue) if snake.action_queue: snake.make_iteration() print(canvas) def on_keypress(key: Key): if key.name in ["up", "down", "left", "right"]: snake.queue_action(key.name) game_tick() if __name__ == "__main__": os.system("clear") with Listener(on_press=on_keypress) as listener: listener.join()