#!/home/honney/Projects/tetris_gui/.venv/bin/python3 import sys, json, select, os import pygame WIDTH, HEIGHT = 1280, 720 CELL = 32 BOARD_H, BOARD_W = 20, 10 NEXT_H, NEXT_W = 4, 4 B1 = (304, 40, 320, 640) B2 = (656, 40, 320, 640) N1 = (88, 96, 128, 128) N2 = (1064, 96, 128, 128) S1 = (84, 454, 136, 32) S2 = (1060, 454, 136, 32) SCORE_FONT = [ [ # S [0,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,0,0], [0,1,1,1,0,0],[0,0,1,1,1,0],[0,0,0,0,1,1], [1,1,0,0,1,1],[0,1,1,1,1,0], ], [ # C [0,1,1,1,1,0],[1,1,1,0,1,1],[1,1,0,0,0,0], [1,1,0,0,0,0],[1,1,0,0,0,0],[1,1,0,0,0,0], [1,1,1,0,1,1],[0,1,1,1,1,0], ], [ # O [0,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,1,1], [1,1,0,0,1,1],[1,1,0,0,1,1],[1,1,0,0,1,1], [1,1,0,0,1,1],[0,1,1,1,1,0], ], [ # R [1,1,1,1,1,0],[1,1,0,0,1,1],[1,1,0,0,1,1], [1,1,1,1,1,0],[1,1,0,1,1,1],[1,1,0,0,1,1], [1,1,0,0,1,1],[1,1,0,0,1,1], ], [ # E [1,1,1,1,1,1],[1,1,0,0,0,0],[1,1,0,0,0,0], [1,1,1,1,1,1],[1,1,0,0,0,0],[1,1,0,0,0,0], [1,1,0,0,0,0],[1,1,1,1,1,1], ], ] PALETTE = [ (0,0,0),(0,255,255),(0,0,255),(255,128,0), (255,242,0),(0,255,0),(159,0,255),(255,0,0), ] PALETTE_ALT = [ (0,0,0),(0,134,243),(61,79,220),(253,171,1), (171,203,4),(2,189,205),(210,15,99),(254,75,15), ] def bevel_color(r, g, b, x, y, style): if style == 0: if 8 <= x < 24 and 8 <= y < 24: return (r, g, b) if 6 <= x < 26 and 6 <= y < 26: return (r & 0xB0, g & 0xB0, b & 0xB0) if x + y < 31: return (r, g, b) if x > y else (r & 0xEF, g & 0xEF, b & 0xEF) return (r & 0xD7, g & 0xD7, b & 0xD7) if x > y else (r & 0xC0, g & 0xC0, b & 0xC0) if x == 31 or y == 31: return (r >> 1, g >> 1, b >> 1) if (x == 0 or y == 0) else (r >> 2, g >> 2, b >> 2) if x == 0 or y == 0: return (r, g, b) return (r & 0xC0, g & 0xC0, b & 0xC0) def build_blocks(palette, style): tex = [] for clr in palette: surf = pygame.Surface((CELL, CELL)) for y in range(CELL): for x in range(CELL): surf.set_at((x, y), bevel_color(*clr, x, y, style)) tex.append(surf) return tex def build_background(): surf = pygame.Surface((WIDTH, HEIGHT)) for y in range(HEIGHT): for x in range(WIDTH): if (x + y) & 1: surf.set_at((x, y), (0, 0, 255)) else: v = (x + y) >> 3 surf.set_at((x, y), (v, 250 - v, 0)) return surf def build_score(): surf = pygame.Surface((136, 32)) surf.fill((0, 0, 0)) x_off = 0 for glyph in SCORE_FONT: for fy, row in enumerate(glyph): for fx, px in enumerate(row): if px: pygame.draw.rect(surf, (255, 255, 255), (x_off + fx * 4, fy * 4, 4, 4)) x_off += 28 return surf class Display: def __init__(self): pygame.init() self.screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Tetris") self.bg = build_background() self.score = build_score() self.b1_tex = build_blocks(PALETTE, 0) self.b2_tex = build_blocks(PALETTE_ALT, 0) self.n1_tex = build_blocks(PALETTE, 1) self.n2_tex = build_blocks(PALETTE_ALT, 1) self.board1 = [[0] * BOARD_W for _ in range(BOARD_H)] self.board2 = [[0] * BOARD_W for _ in range(BOARD_H)] self.next1 = [[0] * NEXT_W for _ in range(NEXT_H)] self.next2 = [[0] * NEXT_W for _ in range(NEXT_H)] def draw_grid(self, board, rect, textures): x, y, w, h = rect for row in range(h // CELL): for col in range(w // CELL): v = board[row][col] self.screen.blit(textures[v if 0 <= v <= 7 else 0], (x + col * CELL, y + row * CELL)) def render(self): self.screen.blit(self.bg, (0, 0)) self.draw_grid(self.board1, B1, self.b1_tex) self.draw_grid(self.board2, B2, self.b2_tex) self.draw_grid(self.next1, N1, self.n1_tex) self.draw_grid(self.next2, N2, self.n2_tex) self.screen.blit(self.score, (S1[0], S1[1])) self.screen.blit(self.score, (S2[0], S2[1])) pygame.display.flip() def close(self): pygame.quit() def main(): disp = Display() buf = "" clock = pygame.time.Clock() running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if not sys.stdin.isatty(): r, _, _ = select.select([sys.stdin], [], [], 0) if r: chunk = os.read(sys.stdin.fileno(), 65536) if not chunk: running = False else: buf += chunk.decode("utf-8") while "\n" in buf: line, buf = buf.split("\n", 1) line = line.strip() if not line: continue try: data = json.loads(line) if "b1" in data: disp.board1 = data["b1"] if "b2" in data: disp.board2 = data["b2"] if "n1" in data: disp.next1 = data["n1"] if "n2" in data: disp.next2 = data["n2"] except json.JSONDecodeError: pass disp.render() clock.tick(60) disp.close() sys.exit() if __name__ == "__main__": main()