Created
February 29, 2016 22:23
-
-
Save ali1234/d605f51eb597a77d6508 to your computer and use it in GitHub Desktop.
A teletext game
This file contains 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
#!/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