Created
September 2, 2017 23:01
-
-
Save riyazpanjwani/4458d3cdd4234d6551f2cea85ef2b143 to your computer and use it in GitHub Desktop.
Simple implementation of Snake game in python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import curses | |
from curses import KEY_RIGHT, KEY_LEFT, KEY_DOWN, KEY_UP | |
from random import randint | |
WIDTH = 120 | |
HEIGHT = 30 | |
MAX_X = WIDTH - 2 | |
MAX_Y = HEIGHT - 2 | |
SNAKE_LENGTH = 5 | |
SNAKE_X = SNAKE_LENGTH + 1 | |
SNAKE_Y = 3 | |
TIMEOUT = 100 | |
class Snake(object): | |
REV_DIR_MAP = { | |
KEY_UP: KEY_DOWN, KEY_DOWN: KEY_UP, | |
KEY_LEFT: KEY_RIGHT, KEY_RIGHT: KEY_LEFT, | |
} | |
def __init__(self, x, y, window): | |
self.body_list = [] | |
self.hit_score = 0 | |
self.timeout = TIMEOUT | |
# Create snake body | |
for i in range(SNAKE_LENGTH, 0, -1): | |
self.body_list.append(Body(x - i, y)) | |
self.body_list.append(Body(x, y, '@')) | |
self.window = window | |
self.direction = KEY_RIGHT | |
self.last_head_coor = (x, y) | |
self.direction_map = { | |
KEY_UP: self.move_up, | |
KEY_DOWN: self.move_down, | |
KEY_LEFT: self.move_left, | |
KEY_RIGHT: self.move_right | |
} | |
@property | |
def score(self): | |
return 'Score : {}'.format(self.hit_score) | |
def add_body(self, body_list): | |
self.body_list.extend(body_list) | |
def eat_food(self, food): | |
food.reset() | |
body = Body(self.last_head_coor[0], self.last_head_coor[1]) | |
self.body_list.insert(-1, body) | |
self.hit_score += 1 | |
if self.hit_score % 3 == 0: | |
self.timeout -= 5 | |
self.window.timeout(self.timeout) | |
@property | |
def complete(self): | |
return any([body.coor == self.head.coor | |
for body in self.body_list[:-1]]) | |
def update(self): | |
# for idx, body in enumerate(self.body_list[:-1]): | |
# body.x = self.body_list[idx+1].x | |
# body.y = self.body_list[idx+1].y | |
last_body = self.body_list.pop(0) | |
last_body.x = self.body_list[-1].x | |
last_body.y = self.body_list[-1].y | |
self.body_list.insert(-1, last_body) | |
self.last_head_coor = (self.head.x, self.head.y) | |
self.direction_map[self.direction]() | |
def change_direction(self, direction): | |
if direction != Snake.REV_DIR_MAP[self.direction]: | |
self.direction = direction | |
def render(self): | |
for body in self.body_list: | |
self.window.addstr(body.y, body.x, body.char) | |
@property | |
def head(self): | |
return self.body_list[-1] | |
@property | |
def coor(self): | |
return self.head.x, self.head.y | |
def move_up(self): | |
self.head.y -= 1 | |
if self.head.y < 1: | |
self.head.y = MAX_Y | |
def move_down(self): | |
self.head.y += 1 | |
if self.head.y > MAX_Y: | |
self.head.y = 1 | |
def move_left(self): | |
self.head.x -= 1 | |
if self.head.x < 1: | |
self.head.x = MAX_X | |
def move_right(self): | |
self.head.x += 1 | |
if self.head.x > MAX_X: | |
self.head.x = 1 | |
class Body(object): | |
def __init__(self, x, y, char='#'): | |
self.x = x | |
self.y = y | |
self.char = char | |
@property | |
def coor(self): | |
return self.x, self.y | |
class Food(object): | |
def __init__(self, window, char='*'): | |
self.x = randint(1, MAX_X) | |
self.y = randint(1, MAX_Y) | |
self.char = char | |
self.window = window | |
def render(self): | |
self.window.addstr(self.y, self.x, self.char) | |
def reset(self): | |
self.x = randint(1, MAX_X) | |
self.y = randint(1, MAX_Y) | |
if __name__ == '__main__': | |
curses.initscr() | |
window = curses.newwin(HEIGHT, WIDTH, 0, 0) | |
window.timeout(TIMEOUT) | |
window.keypad(1) | |
curses.noecho() | |
curses.curs_set(0) | |
window.border(0) | |
snake = Snake(SNAKE_X, SNAKE_Y, window) | |
food = Food(window, '&') | |
while True: | |
window.clear() | |
window.border(0) | |
snake.render() | |
food.render() | |
window.addstr(0, 5, snake.score) | |
event = window.getch() | |
if event == 27: | |
break | |
if event in [KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT]: | |
snake.change_direction(event) | |
if snake.head.x == food.x and snake.head.y == food.y: | |
snake.eat_food(food) | |
if event == 32: | |
key = -1 | |
while key != 32: | |
key = window.getch() | |
snake.update() | |
if snake.complete: | |
break | |
curses.endwin() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment