Files @ 6e77747319ab
Branch filter:

Location: led-matrix-software/demos/snake.py - annotation

matthewreed
Added base software to select and run demos/games, along with a couple demos
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
6e77747319ab
### snake.py
### Author: Matthew Reed
### Game of snake, uses the D-Pad
### Adapted from https://pythonspot.com/snake-with-pygame/ ###

import sys
import time
import signal
import logging
import configparser
from enum import Enum

import math
from random import randint
import matrix

class Snake:

    class Apple:
    
        def __init__(self, x, y):
            self.x = x
            self.y = y
     
        def draw(self, display):
            display.set_pixel(self.x, self.y, matrix.Colors.GREEN.value)
    
    class Player:

        class DIRECTION(Enum):
            NONE = 0
            UP = 1
            DOWN = 2
            LEFT = 3
            RIGHT = 4
     
        def __init__(self, length):
        
            self.length = length
            self.direction = self.DIRECTION.RIGHT
            
            self.updateCountMax = 4
            self.updateCount = 0

            # initial positions, no collision
            self.x = [2,1,0]
            self.y = [0,0,0]
            
            for i in range(0, 61):
                self.x.append(-100)
                self.y.append(-100)
     
        def update(self):
     
            self.updateCount = self.updateCount + 1
            if self.updateCount >= self.updateCountMax:
     
                # update previous positions
                for i in range(self.length, 0, -1):
                    self.x[i] = self.x[i-1]
                    self.y[i] = self.y[i-1]
     
                # update position of head of snake
                if self.direction == self.DIRECTION.RIGHT:
                    self.x[0] = self.x[0] + 1
                if self.direction == self.DIRECTION.LEFT:
                    self.x[0] = self.x[0] - 1
                if self.direction == self.DIRECTION.UP:
                    self.y[0] = self.y[0] - 1
                if self.direction == self.DIRECTION.DOWN:
                    self.y[0] = self.y[0] + 1
     
                self.updateCount = 0
                
        def is_overlaping(self, apple):
            for i in range(0, self.length):
                if apple.x == self.x[i] and apple.y == self.y[i]:
                    return True
            return False
     
        def draw(self, display):
            for i in range(0, self.length):
                #print("l: " + str(self.length) + " i: " + str(i) + " x: " + str(self.x[i]) + " y: " + str(self.y[i]))
                if self.x[i] > 7: self.x[i] = 7
                if self.x[i] < 0: self.x[i] = 0
                if self.y[i] > 7: self.y[i] = 7
                if self.y[i] < 0: self.y[i] = 0
                display.set_pixel(self.x[i], self.y[i], matrix.Colors.BLUE.value)

    def __init__(self, config, parent, matrix, controller):
        self.logger = logging.getLogger('snake')
        self.config = config
        self.parent = parent
        self.matrix = matrix
        self.controller = controller
        
    def reset(self):
        pass
        
    def splash(self):
        self.matrix.set_matrix(matrix.Colors.BLUE.value)
        self.matrix.update()
        
    def run(self):
    
        self.player = self.Player(3) 
        self.apple = self.Apple(5,5)
    
        #start timers and counters
        self.start_time = time.time()
        last_time = time.time()
        delay_time = 0.2
        
        led_iteration_count = 0
        frame_count = 0
        
        keep_going = True
        
        while keep_going:
            
            for event in self.controller.read_input():
                if event.code == 313 and event.value == 1:
                    keep_going = False
                elif event.code == 16:
                    if event.value == 1:
                        #dpad right
                        self.player.direction = self.player.DIRECTION.RIGHT
                    if event.value == 0:
                        #dpad none
                        pass
                    if event.value == -1:
                        #dpad left
                        self.player.direction = self.player.DIRECTION.LEFT
                elif event.code == 17:
                    if event.value == 1:
                        #dpad down
                        self.player.direction = self.player.DIRECTION.DOWN
                    if event.value == 0:
                        #dpad none
                        pass
                    if event.value == -1:
                        #dpad up
                        self.player.direction = self.player.DIRECTION.UP
            
            if time.time() > last_time + delay_time:
                last_time = time.time()
                
                #determine next move
                self.player.update()
         
                #does snake eat apple?
                if self.apple.x == self.player.x[0] and self.apple.y == self.player.y[0]:
                    self.player.length = self.player.length + 1
                    while self.player.is_overlaping(self.apple):
                        self.apple.x = randint(0, 7)
                        self.apple.y = randint(0, 7)
                    #go faster as the snake gets longer
                    delay_time = delay_time - 0.005
         
                #does snake collide with itself?
                for i in range(1, self.player.length):
                    if self.player.x[0] == self.player.x[i] and self.player.y[0] == self.player.y[i]:
                        print("You lose! Collision: ")
                        print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")")
                        print("x[" + str(i) + "] (" + str(self.player.x[i]) + "," + str(self.player.y[i]) + ")")
                        keep_going = False
                        
                #does snake go off the board?
                if self.player.x[0] < 0 or self.player.x[0] > 7 or self.player.y[0] < 0 or self.player.y[0] > 7:
                    print("You lose! Off Board: ")
                    print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")")
                    keep_going = False
                
                #update display
                self.matrix.set_matrix(matrix.Colors.OFF.value)
                self.player.draw(self.matrix)
                self.apple.draw(self.matrix)
                self.matrix.update()
                
                led_iteration_count = (led_iteration_count + 1) % self.matrix.NUM_LEDS
                frame_count = frame_count + 1
                
            time.sleep(0.01)
        
        #display score before exiting
        self.matrix.set_matrix(matrix.Colors.OFF.value)
        self.matrix.update()
        for i in range(0, self.player.length):
            self.matrix.set_pixel(i % self.matrix.WIDTH, math.floor(i / self.matrix.HEIGHT), matrix.Colors.WHITE.value)
        self.matrix.update()
        time.sleep(2)