Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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()
Ejemplo n.º 3
0
def init_game_state():
    r"""初始化游戏

    :return: 蛇对象,食物对象
    """
    snake = Snake(SNAKE_POS_X, SNAKE_POS_Y, SNAKE_INIT_LEN)
    food = gen_food(snake)

    return snake, food
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
    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()
Ejemplo n.º 7
0
    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: ")
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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()
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
Archivo: main.py Proyecto: konko2/snake
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:
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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()