def step(self, action):
        pygame.time.delay(50)  # lower is faster
        self.clock.tick(self.speed)  # lower is slower

        current_reward = 0

        self.snake.move_ai(action)
        # self.snake.move_human()

        if self.snake.ate_itself():
            current_reward = -1
            self.game_over()

        self.step_without_apple += 1
        if self.step_without_apple == 250:
            self.game_over()

        if self.snake.body[0].pos == self.snack.pos:
            self.snake.add_cube()
            self.snack = Cube(self.random_snack(),
                              self.rows,
                              W,
                              color=(0, 255, 0))
            self.reward += 1
            current_reward = 1
            self.step_without_apple = 0

        self.redraw_window()

        obs = self.get_observation_space()

        return obs, current_reward, self.is_done, {}
    def __init__(self, draw=True, speed=10000, rows=20, animation=True):
        super(SnakeEnvironment, self).__init__()

        self.observation_space = gym.spaces.Box(low=-1,
                                                high=1,
                                                shape=(rows, rows),
                                                dtype=np.uint8)
        self.action_space = gym.spaces.Discrete(n=len(Actions))

        self.draw = draw
        self.speed = speed
        self.rows = rows
        self.animation = animation

        self.snake = Snake((255, 0, 0), (2, 2), self.rows, W)
        self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))

        self.is_done = False
        self.reward = 0
        self.step_without_apple = 0

        self.surf = pygame.display.set_mode((W, H))
        self.clock = pygame.time.Clock()

        if draw:
            pygame.init()
            self.font_game_over = pygame.font.SysFont("ani", 72)
    def reset(self):
        self.countdown()

        self.snake.reset((2, 2))
        self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
        self.is_done = False
        self.reward = 0
        self.step_without_apple = 0

        self.surf = pygame.display.set_mode((W, H))
        self.clock = pygame.time.Clock()

        obs, reward, is_done, _ = self.step(1)

        return obs
示例#4
0
    def add_cube(self):
        tail = self.body[-1]
        dx, dy = tail.dirnx, tail.dirny

        if dx == 1 and dy == 0:
            self.body.append(Cube((tail.pos[0] -1, tail.pos[1]), self.rows, self.w))
        elif dx == -1 and dy == 0:
            self.body.append(Cube((tail.pos[0] +1, tail.pos[1]), self.rows, self.w))
        elif dx == 0 and dy == 1:
            self.body.append(Cube((tail.pos[0], tail.pos[1] -1), self.rows, self.w))
        elif dx == 0 and dy == -1:
            self.body.append(Cube((tail.pos[0], tail.pos[1] +1), self.rows, self.w))

        self.body[-1].dirnx = dx
        self.body[-1].dirny = dy
示例#5
0
 def reset(self, pos):
     self.head = Cube(pos, self.rows, self.w)
     self.body = []
     self.body.append(self.head)
     self.turns = {}
     self.dirnx = 0
     self.dirny = 1
     self.add_cube()
     self.add_cube()
    def play_human(self):
        self.countdown()

        while(not self.is_done):
            pygame.time.delay(50)                      # lower is faster
            self.clock.tick(self.speed)                # lower is slower

            self.snake.move_human()

            if self.snake.ate_itself():
                self.game_over()

            if self.snake.body[0].pos == self.snack.pos:
                self.snake.add_cube()
                self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
                self.reward += 1

            self.redraw_window()
            self.get_observation_space()
    def step(self, action):
        pygame.time.delay(50)                      # lower is faster
        self.clock.tick(self.speed)                # lower is slower

        if isinstance(action, np.ndarray):
            idx = -1
            highest_idx = 0
            highest_val = -1
            for i in action:
                idx += 1
                if i > highest_val:
                    highest_idx = idx
                    highest_val = i
            action = highest_idx

        current_reward = 0

        self.snake.move_ai(action)
        # self.snake.move_human()

        if self.snake.ate_itself():
            current_reward = -1
            self.game_over()

        self.step_without_apple += 1
        if self.step_without_apple == 250:
            self.game_over()

        if self.snake.body[0].pos == self.snack.pos:
            self.snake.add_cube()
            self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
            self.reward += 1
            current_reward = 1
            self.step_without_apple = 0

        self.redraw_window()

        obs = self.get_observation_space()

        return obs, current_reward, self.is_done, None
示例#8
0
    def __init__(self, color, pos, rows, w):
        self.head = Cube(pos, rows, w)
        self.body.append(self.head)

        self.rows = rows
        self.w = w

        self.color = color

        self.dirnx = 0
        self.dirny = 0

        self.add_cube()
        self.add_cube()
class SnakeEnvironment(gym.Env):

    def __init__(self, draw=True, speed=10000, rows=20, animation=True):
        super(SnakeEnvironment, self).__init__()

        self.observation_space = gym.spaces.Discrete(n=rows * rows)
        self.action_space = gym.spaces.Discrete(n=len(Actions))

        self.draw = draw
        self.speed = speed
        self.rows = rows
        self.animation = animation

        self.snake = Snake((255, 0, 0), (2, 2), self.rows, W)
        self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
        
        self.is_done = False
        self.reward = 0
        self.step_without_apple = 0

        self.surf = pygame.display.set_mode((W, H))
        self.clock = pygame.time.Clock()

        if draw:
            pygame.init()
            self.font_game_over = pygame.font.SysFont("ani", 72)

    """ Must alwasy be calles in the beginning. """
    def reset(self):
        self.countdown()

        self.snake.reset((2, 2))
        self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
        self.is_done = False
        self.reward = 0
        self.step_without_apple = 0

        self.surf = pygame.display.set_mode((W, H))
        self.clock = pygame.time.Clock()

        obs, reward, is_done, _ = self.step(1)

        return obs

    def step(self, action):
        pygame.time.delay(50)                      # lower is faster
        self.clock.tick(self.speed)                # lower is slower

        if isinstance(action, np.ndarray):
            idx = -1
            highest_idx = 0
            highest_val = -1
            for i in action:
                idx += 1
                if i > highest_val:
                    highest_idx = idx
                    highest_val = i
            action = highest_idx

        current_reward = 0

        self.snake.move_ai(action)
        # self.snake.move_human()

        if self.snake.ate_itself():
            current_reward = -1
            self.game_over()

        self.step_without_apple += 1
        if self.step_without_apple == 250:
            self.game_over()

        if self.snake.body[0].pos == self.snack.pos:
            self.snake.add_cube()
            self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
            self.reward += 1
            current_reward = 1
            self.step_without_apple = 0

        self.redraw_window()

        obs = self.get_observation_space()

        return obs, current_reward, self.is_done, None

    def get_observation_space(self):

        new_obs = []

        # create 2d matrix
        for i in range(self.rows):
            new_obs.append([])
            for j in range(self.rows):
                new_obs[i].append(-1)

        # add apple
        x_apple = self.snack.pos[0]
        y_apple = self.snack.pos[1]
        new_obs[y_apple][x_apple] = 1

        # add snake
        x_snake = self.snake.head.pos[0]
        y_snake = self.snake.head.pos[1]
        if x_snake == -1 or x_snake == self.rows:
            print('Wtf, this error occured!')
            self.game_over()
            return
        if y_snake == -1 or y_snake == self.rows:
            print('Wtf, this error occured!')
            self.game_over()
            return
        new_obs[y_snake][x_snake] = 0.8

        # tail
        for i, c in enumerate(self.snake.body):
            x_snake = c.pos[0]
            y_snake = c.pos[1]

            if x_snake == -1 or x_snake == self.rows:
                print('Wtf, this error occured!')
                self.game_over()
                return
            if y_snake == -1 or y_snake == self.rows:
                print('Wtf, this error occured!')
                self.game_over()
                return

            new_obs[y_snake][x_snake] = 0.5

        current_obs = []
        for i in new_obs:
            for j in i:
                current_obs.append(j)

        # cnt = 0
        # for i in current_obs:
        #     cnt += 1
        #     print(' ', i, ' ', end='')
        #     if cnt % self.rows == 0:
        #         print('')
        # print('')

        return_obs = np.array(current_obs)

        return return_obs

    def draw_grid(self):
        size_btwn = W // self.rows

        x = 0
        y = 0

        for i in range(self.rows):
            x = x + size_btwn
            y = y + size_btwn

            pygame.draw.line(self.surf, (255, 255, 255), (x, 0), (x, W))
            pygame.draw.line(self.surf, (255, 255, 255), (0, y), (W, y))

    def redraw_window(self):
        if not self.draw:
            return 

        self.surf.fill((0, 0, 0))
        self.draw_grid()
        self.snake.draw(self.surf)
        self.snack.draw(self.surf)

        pygame.display.update()

    def random_snack(self):
        positions = self.snake.body
     
        while True:
            x = random.randrange(self.rows)
            y = random.randrange(self.rows)
            if len(list(filter(lambda z:z.pos == (x,y), positions))) > 0:
                continue
            else:
                break
        return (x,y)

    def countdown(self):
        if not self.draw or not self.animation:
            return
        for _ in range(3, 0, -1):
            self.write_text("Start in {}".format(_))
            time.sleep(0.3)

    def game_over(self):
        self.is_done = True
        if not self.draw or not self.animation:
            return
        self.write_text("Score {}".format(self.reward))
        time.sleep(1.5)

    def write_text(self, text):
        self.redraw_window()
        text_start = pygame.font.SysFont('dyuthi', 80). \
            render(text, True, (255, 255, 255))
        self.surf.blit(text_start,
                         (text_start.get_width() //
                          2, text_start.get_height() // 2))
        pygame.display.flip()

    def play_human(self):
        self.countdown()

        while(not self.is_done):
            pygame.time.delay(50)                      # lower is faster
            self.clock.tick(self.speed)                # lower is slower

            self.snake.move_human()

            if self.snake.ate_itself():
                self.game_over()

            if self.snake.body[0].pos == self.snack.pos:
                self.snake.add_cube()
                self.snack = Cube(self.random_snack(), self.rows, W, color=(0, 255, 0))
                self.reward += 1

            self.redraw_window()
            self.get_observation_space()