lehrkraefte:blc:informatik:glf20:oxotetris

Tetris auf der OxoCard

Erläuterungen zum Code gibt es als Videos:

oxotetris.py
from oxocard import *
from ivobuttons import *
from random import randrange  # Funktion randrange importieren
 
ivobuttons.delay=300            # Tasten nach 300ms repetieren repetieren beginnen
ivobuttons.repeat_delay=100     # Tasten danach 10x pro Sekunde repetieren
 
# Gamestate als Dictionary, d.h. wie eine Liste aber mit Namen als Indizes
tetris = {
    "feld": [[False for y in range(8)] for x in range(8)],   # Pixel belegt oder nicht (wenn belegt, dann Farbe)
    "steine": list(map(lambda x:list(map(lambda y: [y%4,y//4],x)), [(0,1,2,3),(0,1,2,5), (0,1,4,5), (0,1,5,6), (4,5,1,2), (0,1,2,6), (4,0,1,2)])),
    "farben": [(255,0,0), (0,255,0), (0,0,255), (255,255,0), (255,0,255), (0,255,255),(255,255,255)],
    "stein": None,  # Positionen der Steinpixel
    "farbe": None,
    "empty" : (10,10,10),  # Hintergrundfarbe, damit das Spielfeld sichtbar ist.
    "x": None,     # Untere linke Ecke der Boundingbox des Steins
    "y": None,     # Untere linke Ecke der Boundingbox des Steins
    "last": 0,     # Zeit bis der Stein weiter fällt.
    "score": 0,
}
 
 
# Ergibt True, wenn der Stein platziert werden kann,
# False sonst.
def platzierbar(stein,x,y):
    global tetris
    return all((pt[0]+x>=0 and pt[0]+x<=7 and pt[1]+y<=7 and 
             (pt[1]+y<0 or tetris['feld'][pt[0]+x][pt[1]+y]==False)) for pt in stein)
 
 
# Generiert einen neuen Stein und gibt
# True zurück, wenn das möglich ist, und sonst
# False, wenn der Stein nicht mehr platziert werden kann.
def neuerStein():
    global tetris
    # Zufälligen Stein kopieren
    stein = randrange(len(tetris["steine"]))
    tetris["stein"] = [[pt[0], pt[1]] for pt in tetris["steine"][stein]]
    tetris["farbe"] = tetris["farben"][stein]
 
    tetris["x"]=3  # Koordinaten vom Stein
    tetris["y"]=-max(pt[1] for pt in tetris["stein"])
 
    tetris["last"] = getms()  # Zeit der Letzten Aktion, damit der Stein selber fällt
    tetris['score']+=1
    print("Score %d" % tetris['score'])
    return platzierbar(tetris["stein"], tetris["x"], tetris["y"])
 
# Generiert ein neues Array mit Koordinaten des gedrehten Steins
# Die richtung ist +1 oder -1
def drehen(richtung):
    global tetris
    # Gedrehte Koordinaten
    res = [[pt[1]*richtung,-pt[0]*richtung] for pt in tetris["stein"]]
    # Untere linke Ecke
    mins = [min([pt[0] for pt in res]), max([pt[1] for pt in res])]
    for pt in res:
        for i in range(2):
            pt[i]-=mins[i]
    return res
 
# Aktuellen Stein zeichnen (evtl. mit Farbe)
def steinZeichnen(farbe=None):
    global tetris
    if farbe==None:
        farbe = tetris['farbe']
    for pt in tetris['stein']:
        if (pt[1]+tetris['y'] >=0):
            if farbe==BLACK:
                black(pt[0]+tetris['x'], pt[1]+tetris['y'])
            else:
                fastDot(pt[0]+tetris['x'], pt[1]+tetris['y'], farbe)
    fastRepaint()
 
# y ist ein Array mit True/False, welche Linien zu blinken sind
def blinkLines(y):
    for i in range(5):
        for farbe in (WHITE, BLACK):
            for yy in range(8):
                if y[yy]:
                    for xx in range(8):
                        fastDot(xx,yy, farbe)
            fastRepaint()
            sleep(0.1)
 
# Lässt Linien verschwinden, wobei y ein Array mit True/False für jede Linie ist.
def removeLines(y):
    global tetris
    count = 0
    for yy in range(8):
        if y[yy]:
            count+=1
            for yyy in range(yy,-1,-1):
                for x in range(8):
                    f = BLACK
                    if yyy>0:
                        tetris['feld'][x][yyy] = tetris['feld'][x][yyy-1]
                    else:
                        tetris['feld'][x][yyy] = False
                    if tetris['feld'][x][yyy]:
                        fastDot(x,yyy,tetris['feld'][x][yyy])
                    else:   
                        black(x,yyy);
                fastRepaint()
            sleep(0.1)
    tetris['score']+= [0,5,20,100,500][count]
    print("Score %d" % tetris['score'])
 
# Überprüft, ob volle Zeilen da sind und löscht diese    
def checkLines():
    global tetris
    # Array mit True, False, für volle Zeilen True
    y = [all(tetris['feld'][x][y] for x in range(8)) for y in range(8)]
    # Volle Zeilen?
    if any(y):
        blinkLines(y)
        removeLines(y)
 
 
# Stein runter, evtl. Linien löschen, neuer Stein generieren
# Liefert False, wenn das Spiel weiter geht
# True, wenn GameOver ist.    
def steinDown():
    global tetris
    tetris['last'] = zeit
    if platzierbar(tetris['stein'], tetris['x'], tetris['y']+1):
        steinZeichnen(BLACK)
        tetris['y']+=1
        steinZeichnen()
        return False
    else:
        # Stein definitiv platzieren:
        for pt in tetris['stein']:
            if (pt[1]+tetris['y']>=0):
                tetris['feld'][pt[0]+tetris['x']][pt[1]+tetris['y']] = tetris['farbe']
        checkLines()
        return not neuerStein()
 
 
# Richtung ist +1 oder -1
def steinMove(richtung):
    global tetris
    if platzierbar(tetris['stein'], tetris['x']+richtung, tetris['y']):
        steinZeichnen(BLACK)
        tetris['x']+=richtung
        steinZeichnen()
 
# Richtung ist +1 oder -1        
def steinRotate(richtung):
    global tetris
    gedreht = drehen(richtung)
    if platzierbar(gedreht, tetris['x'], tetris['y']):
        steinZeichnen(BLACK)
        tetris['stein']=gedreht
        steinZeichnen()
 
def black(x,y):
    fastDot(x,y, (4,4,4));
 
def init():
    for x in range(8):
        for y in range(8):
            black(x,y)
    neuerStein();    
    steinZeichnen();
 
bigTextScroll(" Oxo Tetris ", (10,40,200), BLACK)
init()
 
#############
# Game Loop #
#############
gameOver = False
 
while not gameOver:
    zeit = getms()
    s = ivobuttons.states()
    if zeit-tetris['last']>800 or s & IVO_R3:
        gameOver = steinDown();
    if s & IVO_L2:
        steinMove(-1)
    if s & IVO_R2:
        steinMove(1)
    if s & IVO_R1:
        steinRotate(1)
    if s & IVO_L1:
        steinRotate(-1)
 
 
# Game Over
 
print("Game over")
while True:    
    bigTextScroll((" %d " % tetris['score']), (100,0,0), BLACK)

Was folgt sind Notizen, um von der OxoCard die Highscores auf dem Web zu publizieren.

from tcpcom import *
# See dcoumentation directly in the code of the OxoCard modules files
Wlan.connect("stopbuepf", "stopbuepf")
client = HTTPClient()  # Pass True for debugging...
client._isSSL=True
if client.connect("tech-lab.ch", 443):  # Host is used in HTTP-Query
    response = client.sendPostRequest("/scores/index.php", "name="+HTTPClient.toUrl("Hase")+"&score=123")
    print(response)
    client.closeConnection()
  • lehrkraefte/blc/informatik/glf20/oxotetris.txt
  • Last modified: 2020/12/17 14:02
  • by Ivo Blöchliger