Skip to content

Instantly share code, notes, and snippets.

@ali1234
Created February 29, 2016 22:23
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ali1234/d605f51eb597a77d6508 to your computer and use it in GitHub Desktop.
Save ali1234/d605f51eb597a77d6508 to your computer and use it in GitHub Desktop.
A teletext game
#!/usr/bin/env python
# Pipe the output of this script to raspi-teletext or any teletext emulator that
# supports t42 packet streams.
#
# ./teletextgame | ./teletext -
#
# Features:
#
# * 3D graphics.
# * Procedurally generated levels.
# * Control with Fastext buttons.
from random import shuffle, randrange
import numpy
import sys
def hamming8_encode(d):
d1 = d&1
d2 = (d>>1)&1
d3 = (d>>2)&1
d4 = (d>>3)&1
p1 = (1 + d1 + d3 + d4) & 1
p2 = (1 + d1 + d2 + d4) & 1
p3 = (1 + d1 + d2 + d3) & 1
p4 = (1 + p1 + d1 + p2 + d2 + p3 + d3 + d4) & 1
return (p1 | (d1<<1) | (p2<<2) | (d2<<3)
| (p3<<4) | (d3<<5) | (p4<<6) | (d4<<7))
def mrag_encode(m, r):
a = (m&0x7) | ((r&0x1) << 3)
b = r>>1
return numpy.array([hamming8_encode(a), hamming8_encode(b)], dtype=numpy.uint8)
def page_subpage_encode(page=0xff, subpage=0, control=0):
return numpy.array([hamming8_encode(page&0xf),
hamming8_encode(page>>4),
hamming8_encode(subpage&0xf),
hamming8_encode(((subpage>>4)&0x7)|((control&1)<<3)),
hamming8_encode((subpage>>8)&0xf),
hamming8_encode(((subpage>>12)&0x3)|((control&6)<<1)),
hamming8_encode((control>>3)&0xf),
hamming8_encode((control>>7)&0xf)], dtype=numpy.uint8)
def page_link_encode(page=0xff, subpage=0, magazine=0):
return numpy.array([hamming8_encode(page&0xf),
hamming8_encode(page>>4),
hamming8_encode(subpage&0xf),
hamming8_encode(((subpage>>4)&0x7)|((magazine&1)<<3)),
hamming8_encode((subpage>>8)&0xf),
hamming8_encode(((subpage>>12)&0x3)|((magazine&6)<<1))], dtype=numpy.uint8)
parity_tab = numpy.array([
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,
0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1
], dtype=numpy.uint8)
def parity_encode(d):
return d | (parity_tab[d] << 7)
class Game(object):
def __init__(self, w=15, h=15):
self.w = w
self.h = h
self.data = numpy.zeros(((w*2)+1,(h*2)+1), dtype=numpy.uint8)
def walk(x, y):
self.visit(x, y)
d = [(-1, 0), (0, 1), (1, 0), (0, -1)]
shuffle(d)
for (xx, yy) in d:
if self.visited(x+xx, y+yy): continue
self.connect(x, y, xx, yy)
walk(x+xx, y+yy)
walk(randrange(w), randrange(h))
def visited(self, x, y):
if x < 0 or x >= self.w or y < 0 or y >= self.h:
return True
return self.data[(y*2)+1][(x*2)+1]
def visit(self, x, y):
self.data[(y*2)+1][(x*2)+1] = 1
def connect(self, x, y, xx, yy):
self.data[(y*2)+1+yy][(x*2)+1+xx] = 1
def connections(self, x, y, d):
d = [(-1, 0), (0, -1), (1, 0), (0, 1), (-1, 0), (0, -1), (1, 0), (0, 1), (-1, 0), (0, -1), (1, 0), (0, 1)][d:]
c = (self.data[(y*2)+1+d[0][1]][(x*2)+1+d[0][0]],
self.data[(y*2)+1+d[1][1]][(x*2)+1+d[1][0]],
self.data[(y*2)+1+d[2][1]][(x*2)+1+d[2][0]],
self.data[(y*2)+1+d[3][1]][(x*2)+1+d[3][0]])
return c
def display(self):
for row in self.data:
print ''.join([' ' if x else '@@' for x in row])
def view(self, x, y, d):
d = d%4
dl = (d+3)%4
dr = (d+1)%4
buf = numpy.full((26, 42), 0x20, dtype=numpy.uint8)
dd = [(0, -1), (1, 0), (0, 1), (-1, 0)][d]
for i in range(24):
buf[i][:2] = mrag_encode(d+1, i)
buf[i][2] = 0x17
buf[0][2:10] = page_subpage_encode(x|(y<<4), 0, 0)
buf[0][10:] = [ord(c) for c in ' <<< \x07Goal: Reach page\x071ee (%1d%02x)'%(d+1, x|(y<<4))]
con = self.connections(x, y, d)
buf[25][:2] = mrag_encode(d+1, 24)
buf[25][2] = 0x17
buf[24][:2] = mrag_encode(d+1, 27)
buf[24][2] = hamming8_encode(0)
buf[24][3:9] = page_link_encode(x|(y<<4), 0x3f7f, ((d+1)^(dl+1)))
buf[24][15:21] = page_link_encode(x|(y<<4), 0x3f7f, ((d+1)^(dr+1)))
buf[24][9:15] = page_link_encode(0xff, 0x3f7f, 0)
buf[24][21:27] = page_link_encode(0xff, 0x3f7f, 0)
buf[24][27:33] = page_link_encode(0xff, 0x3f7f, 0)
buf[24][33:39] = page_link_encode(0xff, 0x3f7f, 0)
buf[24][39] = hamming8_encode(0xf)
if con[1]:
buf[25][2:] = [ord(c) for c in '\x01 <<<<< \x02 ^^^^^ \x03 >>>>> ']
buf[24][9:15] = page_link_encode((x+dd[0])|((y+dd[1])<<4), 0x3f7f, 0)
else:
buf[25][2:] = [ord(c) for c in '\x01 <<<<< \x02 \x03 >>>>> ']
if con[0] == 0:
buf[1][4] = 0x22
buf[1][5] = 0x64
buf[23][4] = 0x60
buf[23][5] = 0x26
else:
buf[1][3] = 0x70
buf[1][4] = 0x70
buf[1][5] = 0x70
buf[23][3] = 0x23
buf[23][4] = 0x23
buf[23][5] = 0x23
if con[0] == con[1]:
for i in range(2, 23):
buf[i][5] = 0x6a
if con[2] == 0:
buf[1][40] = 0x21
buf[1][39] = 0x38
buf[23][40] = 0x30
buf[23][39] = 0x29
else:
buf[1][41] = 0x70
buf[1][40] = 0x70
buf[1][39] = 0x70
buf[23][41] = 0x23
buf[23][40] = 0x23
buf[23][39] = 0x23
if con[2] == con[1]:
for i in range(2, 23):
buf[i][39] = 0x35
if con[1] == 0:
for i in range(6, 39):
buf[1][i] = 0x70
buf[23][i] = 0x23
return buf
x += dd[0]
y += dd[1]
con = self.connections(x, y, d)
buf[2][6] = 0x29
buf[2][7] = 0x30
buf[3][7] = 0x22
buf[3][8] = 0x64
buf[22][6] = 0x38
buf[22][7] = 0x21
buf[21][7] = 0x60
buf[21][8] = 0x26
buf[2][38] = 0x26
buf[2][37] = 0x60
buf[3][37] = 0x21
buf[3][36] = 0x38
buf[22][38] = 0x64
buf[22][37] = 0x22
buf[21][37] = 0x30
buf[21][36] = 0x29
if con[0] == 0:
buf[4][9] = 0x29
buf[4][10] = 0x30
buf[5][10] = 0x22
buf[5][11] = 0x64
buf[6][12] = 0x29
buf[6][13] = 0x30
buf[7][13] = 0x22
buf[7][14] = 0x64
buf[20][9] = 0x38
buf[20][10] = 0x21
buf[19][10] = 0x60
buf[19][11] = 0x26
buf[18][12] = 0x38
buf[18][13] = 0x21
buf[17][13] = 0x60
buf[17][14] = 0x26
else:
for i in range(4, 21):
buf[i][8] = 0x6a
for i in range(9, 15):
buf[7][i] = 0x70
buf[17][i] = 0x23
if con[0] == con[1]:
for i in range(8, 17):
buf[i][14] = 0x6a
if con[2] == 0:
buf[4][35] = 0x26
buf[4][34] = 0x60
buf[5][34] = 0x21
buf[5][33] = 0x38
buf[6][32] = 0x26
buf[6][31] = 0x60
buf[7][31] = 0x21
buf[7][30] = 0x38
buf[20][35] = 0x64
buf[20][34] = 0x22
buf[19][34] = 0x30
buf[19][33] = 0x29
buf[18][32] = 0x64
buf[18][31] = 0x22
buf[17][31] = 0x30
buf[17][30] = 0x29
else:
for i in range(4, 21):
buf[i][36] = 0x35
for i in range(30, 36):
buf[7][i] = 0x70
buf[17][i] = 0x23
if con[2] == con[1]:
for i in range(8, 17):
buf[i][30] = 0x35
if con[1] == 0:
for i in range(15, 30):
buf[7][i] = 0x70
buf[17][i] = 0x23
return buf
x += dd[0]
y += dd[1]
con = self.connections(x, y, d)
buf[8][15] = 0x29
buf[8][16] = 0x30
buf[16][15] = 0x38
buf[16][16] = 0x21
buf[8][29] = 0x26
buf[8][28] = 0x60
buf[16][29] = 0x64
buf[16][28] = 0x22
if con[0] == 0:
buf[9][16] = 0x22
buf[9][17] = 0x64
buf[10][18] = 0x29
buf[10][19] = 0x30
buf[11][19] = 0x22
buf[15][16] = 0x60
buf[15][17] = 0x26
buf[14][18] = 0x38
buf[14][19] = 0x21
buf[13][19] = 0x60
else:
for i in range(9, 16):
buf[i][16] = 0x35
for i in range(17, 20):
buf[11][i] = 0x23
buf[13][i] = 0x70
buf[11][16] = 0x37
buf[13][16] = 0x75
if con[0] == con[1]:
if con[1]:
buf[11][19] = 0x6b
buf[12][19] = 0x6a
buf[13][19] = 0x7a
else:
buf[11][19] = 0x6a
buf[12][19] = 0x6a
buf[13][19] = 0x6a
if con[2] == 0:
buf[9][28] = 0x21
buf[9][27] = 0x38
buf[10][26] = 0x26
buf[10][25] = 0x60
buf[11][25] = 0x21
buf[15][28] = 0x30
buf[15][27] = 0x29
buf[14][26] = 0x64
buf[14][25] = 0x22
buf[13][25] = 0x30
else:
for i in range(9, 16):
buf[i][28] = 0x6a
for i in range(25, 28):
buf[11][i] = 0x23
buf[13][i] = 0x70
buf[11][28] = 0x6b
buf[13][28] = 0x7a
if con[2] == con[1]:
if con[1]:
buf[11][25] = 0x37
buf[12][25] = 0x35
buf[13][25] = 0x75
else:
buf[11][25] = 0x35
buf[12][25] = 0x35
buf[13][25] = 0x35
if con[1] == 0:
for i in range(20, 25):
buf[11][i] = 0x23
buf[13][i] = 0x70
return buf
buf[11][20] = 0x64
buf[13][20] = 0x26
buf[12][21] = 0x35
buf[11][24] = 0x38
buf[13][24] = 0x29
buf[12][23] = 0x6a
return buf
if __name__ == '__main__':
def dump_buf(b):
parity_encode(b).tofile(sys.stdout)
g = Game()
#m.display()
while True:
for y in range(15):
for x in range(15):
for d in range(4):
dump_buf(g.view(x, y, d))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment