There are some nice demos that come with Pimoroni Unicorn HAT HD library but if you want something more fun you can have interactive applications.
How about GAMES ?
I stumbled over a thread Unicorn HAT Demo Ideas where someone was asking foe ideas of demos for the standard Unicorn HAT.
Two of the best demos delivered there by two users (Thank you guys !!!):
evilunix: CPU vs CPU game of pong with rainbow colours
Timcw (Tim Mulford): Battleships !!!
I ended up adapting them for the bigger matrix of the Unicorn HAT HD
CPU vs CPU game of pong with rainbow colours
Duble-Click to get the whole code.
# Adapted to Unicorn HD by George Voina
# blog.voina.org
import unicornhathd as UH
import time
import random
import colorsys as col
#UH.brightness(1) # max brightness :D
SPEED = 0.1
# convert hex to rgb tuple
def hex_to_rgb(value):
value = value.lstrip('#')
lv = len(value)
return tuple(int(value[i:i + lv // 3], 16) for i in range(0, lv, lv // 3))
class Player:
def __init__(self, hue):
self.hue = hue
direction_x = 0 # 1 = up, 2 = down
y = 0 # position of topmost pixel
def spawn(self):
self.y = random.randint(0,13)
def think(self, ball):
# change colour
if self.hue < 360:
self.hue = self.hue + 1
else:
self.hue = 0
rand = random.randint(0,19)
if(rand == 13):
derp = 1
else:
derp = 0
if ball.y > self.y + 1 and self.y < 13:
# ball is below player center - move down
if derp == 0:
self.y = self.y + 1
if ball.y < self.y + 1 and self.y > 0:
# ball is above player center - move up
if derp == 0:
self.y = self.y - 1
class Ball:
direction_x = 0 # 1 = up, 2 = down
direction_y = 0 # 1 = left, 2 = right
x = 0
y = 0
colour = hex_to_rgb('ffffff')
def spawn(self):
print 'spawning ball...'
# ball starting directions
self.direction_x = random.randint(1,2)
self.direction_y = random.randint(1,2)
# ball starting position
self.x = random.randint(3,4)
self.y = random.randint(3,4)
player1 = Player(0)
player2 = Player(90)
ball = Ball()
def update():
global ball, player1, player2
player1.think(ball)
player2.think(ball)
# check if ball hit upper or lower wall
if ball.y == 0:
#change direction
ball.direction_y = 2 # down
if ball.y == 15:
# change direction
ball.direction_y = 1 # up
if ball.direction_y == 2: # down
# move 1 cell down
ball.y = ball.y + 1
elif ball.direction_y == 1: #up
# move 1 cell up
ball.y = ball.y - 1
if ball.direction_x == 1: # moving left
ball.x = ball.x - 1
if ball.x == 0:
# check for collision
if ball.y >= player1.y and ball.y <= player1.y + 3:
print 'SAVE!'
#change direction
ball.direction_x = 2
ball.x = ball.x + 1
else:
# GOAL!
print 'GOAL!'
goal()
ball.spawn()
if ball.direction_x == 2: # moving right
ball.x = ball.x + 1
if ball.x == 15:
# check for collision
if ball.y >= player2.y and ball.y <= player2.y + 3:
print 'SAVE!'
# change direction
ball.direction_x = 1
ball.x = ball.x - 2
else:
# GOAL!
goal()
print 'GOAL!'
ball.spawn()
def goal():
global ball
draw()
time.sleep(SPEED)
set_pixel(ball.x, ball.y, hex_to_rgb('000000'))
UH.show()
time.sleep(SPEED)
set_pixel(ball.x, ball.y, ball.colour)
UH.show()
time.sleep(SPEED)
set_pixel(ball.x, ball.y, hex_to_rgb('000000'))
UH.show()
time.sleep(SPEED)
set_pixel(ball.x, ball.y, ball.colour)
UH.show()
time.sleep(SPEED)
def set_pixel(x, y, colour):
UH.set_pixel(x, y, colour[0], colour[1], colour[2])
def fill_hex(colour):
rgb = hex_to_rgb(colour)
for x in range(0, 16):
for y in range(0, 16):
set_pixel(x, y, rgb)
UH.show()
def set_pixel_hue(x, y, h):
hfloat = h / 255.0
rgb = col.hsv_to_rgb(hfloat, 0.5, 1.0)
r = int(rgb[0] * 255)
g = int(rgb[1] * 255)
b = int(rgb[2] * 255)
UH.set_pixel(x, y, r, g, b)
def draw():
global ball, player1, player2, BG_COLOUR
UH.off()
#fill_hex(BG_COLOUR)
# draw ball
set_pixel(ball.x, ball.y, ball.colour)
# draw player1
set_pixel_hue(0, player1.y, player1.hue)
set_pixel_hue(0, player1.y + 1, player1.hue)
set_pixel_hue(0, player1.y + 2, player1.hue)
# draw player2
set_pixel_hue(15, player2.y, player2.hue)
set_pixel_hue(15, player2.y + 1, player2.hue)
set_pixel_hue(15, player2.y + 2, player2.hue)
UH.show()
player1.spawn()
player2.spawn()
ball.spawn()
draw()
while True:
time.sleep(SPEED)
update()
draw()
Battleships:
Duble-Click to get the whole code.
# Battleships Unicorn Hat display
# Author: Tim Mulford
# Date: 28/08/2015
# Version: 0.5
# Changes:
# I have update the code to make the game area a class with methods for the game.
# Adapted to Unicorn HD by George Voina
# blog.voina.org
import unicornhathd as unicorn
import time, random
# initialise Unicornhat board
# Unless you are using a difusser keep brightness low
#unicorn.brightness(0.1)
unicorn.rotation(180)
# ocean stores the information about the game area and the methods required to
# interact with it
class ocean:
ships = 0
ammo = 0
water = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
# Reset the game board
def reset(self):
self.water = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]
# Display the current board state on the Unicorn hat
def display_water(self):
for y in range(16):
for x in range(16):
if self.water[y][x] == 0 or self.water[y][x] == 1:
unicorn.set_pixel(x,y,79,106,226)
elif self.water[y][x] == 2:
unicorn.set_pixel(x,y,0,0,0)
elif self.water[y][x] == 3:
unicorn.set_pixel(x,y,255,0,0)
unicorn.show()
# Set every light on the board to the set colour
def flood_colour(self,red,green,blue):
for x in range(16):
for y in range(16):
unicorn.set_pixel(x,y,red,green,blue)
unicorn.show()
# Animation for when a shot is a hit
def hit_flash(self,count):
for repeat in range(count):
self.flood_colour(255,0,0)
time.sleep(0.2)
self.flood_colour(255,255,0)
time.sleep(0.2)
self.flood_colour(0,0,255)
time.sleep(0.5)
# Animation for when a shot is a miss
def miss_flash(self):
self.flood_colour(255,255,255)
time.sleep(0.3)
for a in range(0,255,10):
self.flood_colour(0,0,a)
# Animation for targetting using passed co-ordinates
def target_flash(self,x,y):
for a in range(16):
unicorn.set_pixel(x,a,0,200,0)
unicorn.show()
time.sleep(0.05)
for a in range(16):
unicorn.set_pixel(a,y,0,200,0)
unicorn.show()
time.sleep(0.05)
time.sleep(1)
for a in range(0,255,10):
unicorn.set_pixel(x,y,a,a,a)
unicorn.show()
time.sleep(0.01)
for a in range(0,255,10):
unicorn.set_pixel(x,y,255-a,255-a,255-a)
unicorn.show()
time.sleep(0.01)
# Animation for when the game is lost
def defeated(self):
for fade in range(0,255):
for y in range(16):
for x in range(16):
unicorn.set_pixel(x,y,255,255-fade,255-fade)
unicorn.show()
time.sleep(0.01)
# Animation for when the game is won
def victory(self):
for fade in range(0,255):
for y in range(16):
for x in range(16):
unicorn.set_pixel(x,y,255-fade,255,255-fade)
unicorn.show()
time.sleep(0.01)
# Place a boat of the passed size on the game board
# There is no limit to the number of boats placed though
# if too many boats are placed it might not be possible to
# place more and the program will get stuck in an infinite loop
# A "1" is placed in the water 2D array for each part of the boat
# The ships variable is updated to reflect the number of boat parts
# on the game area in total after the boat it placed.
def boat(self, size):
boat_mask = []
for a in range(size):
boat_mask.append(0)
orientation = random.choice(["horizontal","vertical"])
if orientation == "horizontal":
x = random.randint(0,16-size)
y = random.randint(0,15)
placement = []
for a in range(size):
placement.append(self.water[y][x+a])
while placement != boat_mask:
x = random.randint(0,16-size)
y = random.randint(0,15)
placement = []
for a in range(size):
placement.append(self.water[y][x+a])
for a in range(size):
self.water[y][x+a] = 1
else:
x = random.randint(0,15)
y = random.randint(0,16-size)
placement = []
for a in range(size):
placement.append(self.water[y+a][x])
while placement != boat_mask:
x = random.randint(0,16-size)
y = random.randint(0,15)
placement = []
for a in range(size):
placement.append(self.water[y+a][x])
for a in range(size):
self.water[y+a][x]=1
self.ships += size
# Process a shot using the passed co-ordinates on the game area
# determine if the shot is a hit, miss or an already hit area.
# The game area is then updated and the updated game area is displayed
# on the unicorn hat.
def shot(self,x,y):
if self.water[y][x] == 1:
print("Hit")
self.water[y][x] = 3
self.hit_flash(3)
self.ships -= 1
elif self.water[y][x] == 2:
print("You have already hit this area.")
else:
print("Miss")
self.water[y][x] = 2
self.miss_flash()
self.ammo -= 1
self.display_water()
# Enter and validate a co-ordinate
def enter_coord(direction):
valid = False
while valid != True:
try:
co_ord = int(input("Enter the "+direction+"-cordinate for your shot: "))
if co_ord in range(1,17):
valid = True
else:
print("Must be a number between 1 and 16.")
except:
print("Must be an number between 1 and 16.")
if direction == "x":
co_ord = co_ord - 1
else:
co_ord = 16 - co_ord
return co_ord
# Main Program
# Declare an instance of the game area
ocean = ocean()
# Main program loop
while True:
# Initialise the game area
ocean.reset()
ocean.boat(5)
ocean.boat(3)
ocean.boat(3)
ocean.boat(2)
ocean.boat(2)
ocean.ammo = 20
game_over = False
# Display the initial game area to the Unicornhat
ocean.display_water()
# Loop until game over conditions are met
while game_over == False:
# Display current game stats to the screen
print("\nYou have",ocean.ammo,"shots left")
print("There are",ocean.ships,"targets in our waters.")
print("")
# Get x and y co-ordinates of the shot
x = enter_coord("x")
y = enter_coord("y")
# Targetting animation
ocean.target_flash(x,y)
# Process the shot
ocean.shot(x,y)
# Check if the game over conditions are met
if ocean.ships == 0 or ocean.ammo == 0:
game_over = True
# If the game is over because it is lost display game over
if ocean.ammo == 0:
print("\nOur fleet is defeated.")
ocean.defeated()
# Else if it is over because the game is won display victory
elif ocean.ships == 0:
print("\nOur fleet is victorious.")
ocean.victory()
# Ask if the player wants another game
repeat = input("\nDo you want a rematch? ").lower()
# If the player doesn't want to play again quit the program
if repeat in ["no","n"]:
print("Thanks for playing")
break
Have fun !!!
Contribute to this site maintenance !
This is a self hosted site, on own hardware and Internet connection. The old, down to earth way 🙂. If you think that you found something useful here please contribute. Choose the form below (default 1 EUR) or donate using Bitcoin (default 0.0001 BTC) using the QR code. Thank you !
€1.00

