Skip to content

Instantly share code, notes, and snippets.

@les-peters
Last active December 27, 2019 18:43
Show Gist options
  • Save les-peters/6151e3bab7757a5046bfdc42a7124c5d to your computer and use it in GitHub Desktop.
Save les-peters/6151e3bab7757a5046bfdc42a7124c5d to your computer and use it in GitHub Desktop.
cassidoo-20191223
# Make the game Snake. Be as creative (or not) as you want!
import curses
import signal
from curses import wrapper
import math
import random
screenWidth = 80
class boardLocation:
def __init__(self, row, col, direction):
self.row = row
self.col = col
self.direction = direction
def drawSnake(snakeBody, snakeLength, fruit):
ateFruit = False
gameOver = False
pieceOfFruit = fruit[0]
# trim tail to match current length of snake
if len(snakeBody) > snakeLength:
snakeBody.pop(0)
for segment in snakeBody:
stdscr.addch(segment.row, segment.col, "S")
# did the snake eat the fruit?
if segment.row == pieceOfFruit.row and segment.col == pieceOfFruit.col:
ateFruit = True
nextFruitRow, nextFruitCol = findSafeFruitPlace(snakeBody, fruit)
fruit.append(boardLocation(nextFruitRow, nextFruitCol, 'X'))
fruit.pop(0)
break
# did the snake hit its own body?
for restOfBody in snakeBody:
if segment != restOfBody:
if segment.row == restOfBody.row and segment.col == restOfBody.col:
gameOver = True
# did the snake hit a wall?
if segment.row == 0 or segment.row == LINES or segment.col == 0 or segment.col >= screenWidth - 1:
gameOver = True
return ateFruit, gameOver
def findSafeFruitPlace(snakeBody, fruit):
while True:
# put next fruit in random locaiton, but not where snake exists
randomRow = random.randint(1, LINES - 1)
randomCol = random.randint(1, screenWidth - 2)
safePlaceForFruit = True
for segment in snakeBody:
if randomRow == segment.row and randomCol == segment.col:
safePlaceForFruit = False
if safePlaceForFruit:
break
return randomRow, randomCol
def drawFruit(fruit):
for segment in fruit:
stdscr.addch(segment.row, segment.col, "F")
return
def drawBoard(snakeBody, snakeLength, fruit):
stdscr.clear()
stdscr.addstr(0, 0, "=" * screenWidth)
stdscr.addstr(LINES - 1, 0, "=" * screenWidth)
for l in range(0, LINES):
stdscr.addstr(l, 0, "=")
stdscr.addstr(l, screenWidth - 1, "=")
stdscr.move(0, 0)
drawFruit(fruit)
ateFruit, gameOver = drawSnake(snakeBody, snakeLength, fruit)
stdscr.refresh()
return ateFruit, gameOver
def main(stdscr):
snakeLength = 20
snakeIncrease = 20
row = math.floor(LINES / 2)
col = 40
direction = 'R'
snakeBody = []
snakeBody.append(boardLocation(row, col, direction))
fruit = []
nextFruitRow, nextFruitCol = findSafeFruitPlace(snakeBody, fruit)
fruit.append(boardLocation(nextFruitRow, nextFruitCol, 'X'))
ateFruit, gameOver = drawBoard(snakeBody, snakeLength, fruit)
while True:
TIMEOUT = 1
signal.alarm(TIMEOUT)
try:
c = stdscr.getch()
if c == ord('a'):
direction = 'L'
elif c == ord('d'):
direction = 'R'
elif c == ord('w'):
direction = 'U'
elif c == ord('s'):
direction = 'D'
elif c == ord('q'):
break # Exit the while loop
if direction == 'L':
col = col - 1
elif direction == 'R':
col = col + 1
elif direction == 'U':
row = row - 1
elif direction == 'D':
row = row + 1
snakeBody.append(boardLocation(row, col, direction))
except:
c = ''
signal.alarm(0)
# if border wall is breached, break
# if row == 0 or row == LINES or col == 0 or col >= screenWidth - 1:
# break
ateFruit, gameOver = drawBoard(snakeBody, snakeLength, fruit)
if gameOver:
break
if ateFruit:
snakeLength += snakeIncrease
ateFruit = False
print('snake controls')
print('w - up a - left')
print('s - down d - right')
print('q - quit')
input("Press Enter to start...")
# set up curses
stdscr = curses.initscr()
LINES = curses.LINES
curses.noecho()
curses.cbreak()
curses.curs_set(0)
stdscr.keypad(True)
# keep a Ctrl-C from hosing your terminal session
def empty_handler():
return
signal.signal(signal.SIGALRM, empty_handler)
wrapper(main)
# tear down curses
curses.curs_set(1)
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
curses.endwin()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment