import pygame, random, math, sys # Anzahl Quadrate in x-Richtung breite = 10 # Gewinn bei gewinnzahl = 32 # Seitenlänge eines Quadrats in Pixel laenge = 80 # Abstand zwischen Quadraten und am Rand abstand = 10 # Farbe nach Exponent, d.h. zum Beispiel: # * farbe[3] ist der Hexadezimalstring für Orange, die Farbe für "2 hoch 3 = 8". # * farbe[0] ist die Farbe eines leeren Feldes.# (von Abbildung auf deutsche Wikipedia-Seite von 2048 und von https://play2048.co/ mit grabc ermittelt) farbe = ['#cec1b5', '#efe5db', '#eee1c9', '#f2b37a', '#f59663', '#f67d5f', '#f66442', '#f2cf54', '#f4cb4a', '#f5c940', '#f7c430', '#ffb700'] farbe_ziffer = { # Farbe für Zahlen bis 4: 'klein' : '#776d64', # Farbe für Zahlen ab 8: 'gross' : '#f8f5f1' } hintergrundfarbe = '#bcafa1' start = { 'left' : [0, -1], 'right' : [breite-1, 1], } def schreibe(s, x, y, farbe = "white", groesse = 32): x = round(x) y = round(y) groesse = round(groesse) font = pygame.font.Font('freesansbold.ttf', groesse) # font = pygame.font.Font(None, groesse) text = font.render(s, True, farbe) text_rechteck = text.get_rect() text_rechteck.center = (x, y) fenster.blit(text, text_rechteck) def zeichne_quadrat(x, y, zahl): xx = abstand+x*(laenge+abstand) yy = fensterhoehe-(abstand+y*(laenge+abstand)) exponent = round(math.log2(zahl)) if zahl > 0 else 0 rechteck = pygame.Rect(xx, yy-laenge, laenge, laenge) pygame.draw.rect(surface=fenster, color=farbe[exponent], rect=rechteck) if zahl > 0: schriftfarbe = farbe_ziffer['klein'] if zahl <= 4 else farbe_ziffer['gross'] schreibe(str(zahl), xx+laenge/2, yy-laenge/2, schriftfarbe, groesse=laenge//3) def initialisiere_feld(): global feld # alle Felder auf 0 (für leer) setzen feld = [0 for x in range(breite+2)] # Randfelder werden auf -1 gesetzt. feld[-1] = -1 feld[breite] = -1 def setze_stein_zufaellig(p_dass_2=0.9): global feld frei = [] for x in range(breite): if feld[x] == 0: frei.append([x]) if len(frei) > 0: i = random.randrange(len(frei)) feld[frei[i][0]] = 2 if random.random() < p_dass_2 else 4 return True else: return False def male_spielfeld(): fenster.fill(hintergrundfarbe) for x in range(breite): zeichne_quadrat(x, 0, feld[x]) def verschiebe(bewegung): global feld startx, richtung = start[bewegung] aenderung = False a = startx while feld[a] != -1: if feld[a] >= 2: p = a while feld[p+richtung] == 0: p += richtung if p != a: feld[p] = feld[a] feld[a] = 0 aenderung = True a -= richtung return aenderung def fusioniere(bewegung): global feld startx, richtung = start[bewegung] aenderung = False a = startx while feld[a] != -1: if feld[a] >= 2: if feld[a] == feld[a+richtung]: feld[a+richtung] *= 2 feld[a] = 0 aenderung = True a -= richtung return aenderung def hoechste_kachel(): return max(feld) def zug_moeglich(): for x in range(breite): if feld[x] == 0: return True for x in range(breite-1): if feld[x] == feld[x+1]: return True return False initialisiere_feld() # Setze 2er-Kachel setze_stein_zufaellig(p_dass_2=1) # Setze 4er-Kachel setze_stein_zufaellig(p_dass_2=0) # Abmessungen des Spielfelds fensterbreite = breite*laenge+(breite+1)*abstand fensterhoehe = laenge+2*abstand # Initialisierungen pygame.init() pygame.display.set_caption("2048") clockobject = pygame.time.Clock() fensterdimensionen = (fensterbreite, fensterhoehe) fenster = pygame.display.set_mode(fensterdimensionen) pygame.key.set_repeat(500) bewegung = None spielende = False # Game loop while not spielende: for ereignis in pygame.event.get(): if ereignis.type == pygame.QUIT: spielende = True pygame.quit() sys.exit() elif ereignis.type == pygame.KEYDOWN: if ereignis.key == pygame.K_LEFT: print('left') bewegung = 'left' elif ereignis.key == pygame.K_RIGHT: print('right') bewegung = 'right' if bewegung != None: veraenderung = False if verschiebe(bewegung): veraenderung = True if fusioniere(bewegung): veraenderung = True if verschiebe(bewegung): veraenderung = True if veraenderung: male_spielfeld() pygame.display.flip() clockobject.tick(10) setze_stein_zufaellig() if hoechste_kachel() >= gewinnzahl: spielende = True ausgabe = 'Herzlichen Glückwunsch!' if not zug_moeglich(): spielende = True ausgabe = 'Spielende, kein Zug mehr möglich.' if spielende: male_spielfeld() schreibe(ausgabe, fensterbreite/2, fensterhoehe/2, farbe='#ff0000', groesse=laenge/4) pygame.display.flip() while True: for ereignis in pygame.event.get(): if ereignis.type == pygame.QUIT: pygame.quit() sys.exit() bewegung = None male_spielfeld() pygame.display.flip() clockobject.tick(10)