From f91047a7f28a29f2586fb22801d651e358e2d583 Mon Sep 17 00:00:00 2001 From: DennisEckerskorn Date: Wed, 4 Dec 2024 22:21:53 +0100 Subject: [PATCH] Added Tetris Game to windows with start, pause and restart button --- .../__pycache__/tetris_game.cpython-312.pyc | Bin 0 -> 8468 bytes src/services/tetris_game.py | 136 ++++++++++++++++++ .../centered_window.cpython-312.pyc | Bin 8666 -> 10677 bytes src/ui/centered_window.py | 55 ++++++- 4 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 src/services/__pycache__/tetris_game.cpython-312.pyc create mode 100644 src/services/tetris_game.py diff --git a/src/services/__pycache__/tetris_game.cpython-312.pyc b/src/services/__pycache__/tetris_game.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3129ef51b1c18708bb7af2aac7a32fad0ecb2c37 GIT binary patch literal 8468 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", self.handle_keypress) + self.spawn_piece() + self.update_game() + + def spawn_piece(self): + shapes = [ + [[1, 1, 1], [0, 1, 0]], # T-shape + [[1, 1], [1, 1]], # Square + [[1, 1, 1, 1]], # Line + [[0, 1, 1], [1, 1, 0]], # S-shape + [[1, 1, 0], [0, 1, 1]], # Z-shape + ] + shape = random.choice(shapes) + self.current_piece = { + "shape": shape, + "row": 0, + "col": (self.cols - len(shape[0])) // 2, + } + + def draw_piece(self): + shape = self.current_piece["shape"] + row = self.current_piece["row"] + col = self.current_piece["col"] + for r, line in enumerate(shape): + for c, block in enumerate(line): + if block: + self.draw_cell(row + r, col + c, "cyan") + + def draw_cell(self, row, col, color): + x1 = col * self.cell_size + y1 = row * self.cell_size + x2 = x1 + self.cell_size + y2 = y1 + self.cell_size + self.create_rectangle(x1, y1, x2, y2, fill=color, outline="gray") + + def move_piece(self, drow, dcol): + if self.can_move(drow, dcol): + self.current_piece["row"] += drow + self.current_piece["col"] += dcol + + def rotate_piece(self): + """Rota la pieza actual en el sentido horario.""" + shape = self.current_piece["shape"] + rotated_shape = list(zip(*shape[::-1])) # Rotar la matriz en sentido horario + + # Verifica si la pieza rotada cabe en la posición actual + if self.can_place(rotated_shape, self.current_piece["row"], self.current_piece["col"]): + self.current_piece["shape"] = rotated_shape + + def can_place(self, shape, row, col): + for r, line in enumerate(shape): + for c, block in enumerate(line): + if block: + if row + r >= self.rows or col + c < 0 or col + c >= self.cols: + return False # Fuera de los límites del tablero + if self.grid[row + r][col + c]: + return False # Choca con otro bloque + return True + + def can_move(self, drow, dcol): + shape = self.current_piece["shape"] + row = self.current_piece["row"] + drow + col = self.current_piece["col"] + dcol + return self.can_place(shape, row, col) + + def place_piece(self): + shape = self.current_piece["shape"] + row = self.current_piece["row"] + col = self.current_piece["col"] + for r, line in enumerate(shape): + for c, block in enumerate(line): + if block: + self.grid[row + r][col + c] = 1 + self.clear_lines() + self.spawn_piece() + + def clear_lines(self): + self.grid = [line for line in self.grid if any(cell == 0 for cell in line)] + while len(self.grid) < self.rows: + self.grid.insert(0, [0] * self.cols) + + def handle_keypress(self, event): + if event.keysym == "Left": + self.move_piece(0, -1) + elif event.keysym == "Right": + self.move_piece(0, 1) + elif event.keysym == "Down": + self.move_piece(1, 0) + elif event.keysym == "Up": + self.rotate_piece() + + def update_game(self): + if self.running: + if not self.can_move(1, 0): + self.place_piece() + else: + self.move_piece(1, 0) + self.render() + self.after(500, self.update_game) + + def render(self): + self.delete("all") + for r, line in enumerate(self.grid): + for c, block in enumerate(line): + if block: + self.draw_cell(r, c, "blue") + self.draw_piece() + + def stop_game(self): + self.running = False + + def reset_game(self): + """Reinicia el estado del juego.""" + self.running = False # Detener el juego actual + self.grid = [[0] * self.cols for _ in range(self.rows)] # Reiniciar la cuadrícula + self.current_piece = None # Eliminar la pieza actual + self.delete("all") # Limpiar el lienzo + self.spawn_piece() # Generar una nueva pieza + self.running = True # Habilitar el juego nuevamente + self.update_game() # Reanudar el ciclo del juego diff --git a/src/ui/__pycache__/centered_window.cpython-312.pyc b/src/ui/__pycache__/centered_window.cpython-312.pyc index 678a6b6c08d66019f492bcae1878c5860a2dd978..e240a8ef7869320f9a97edf04da404156bb04dcf 100644 GIT binary patch delta 3525 zcma)9Uu+b|8K2#~y*uyi-K~ALvBCE3aR&Rqn35C-kOmw>fVTWe>_T;5F6-OH+;M;0 z**&nWLx&oqI%(3LJ5i0BR)ACqyEqCJipoPDQuUz^Z6#kZIcsSo9%v)fm&A~&>I?m5 z*Jm4utd7p#%zXR%zM1*v`!hDXKko7U+3OV$w2%LEbimU*=4&YY5N6{@MJkg*QO4@o zC};JKsKe^{C~x)7sMG3QQ5W=V%AKx?RxwnTO9^RD)MJeuDKYJhdKtu`{Yd36A=Rld z$tJq$)9nTa^D6j@`iGf_YwTwmwnZ3I=+z9I(Dy58ExsI2!L&U(2INPuWzE`dlvO=r z4?3Gv_azh+)GDAJRRAiEq9G>g?LiUoRui*_WqhQM`xoOS2OUj}@78I@Znn)2s!XqL zDAWGn;4b>uJ3RwhEebe>>Bw+^}Pv9bhw)0-XCGBK>_*&L2* zcq8yEv5QzH2ZSzW2YE;6U_#_~!td*MP({lTbiRvxByMMRl0SI10PK%?<5>BhRT-XWJ1-;BJy}wU8&(0(sxv z;8mGvp#oz_+7)!<`5O%RO?`_~<)%F_9I9(;cB*0?CF%7%)26*QI3lkKdTJ^klC@-P zO@Q}J`){yRw#}(ZAWLumnMP%8)&+OoO+q!bqOp>iYEaYgj1HJCQ&W|%`dT$xtlik6 z3^LYKl+dHv<2;J_7P%-(4QM0>%6&Obt+-G;x?M8$i8iz6seDK6Y$HV(6hPBtD zONM%R_f++DE(Z z`&V7we#gJ|L9=}2AE%5g`1hcK6*-Yf#1jgZwUnI9X#?5L-oudD(*QGFIG4#J zG6SY3H>fIxW_k5e1zK>D1VBgRijy2qWYp~W&gXo)FbFVx8<30WzCTd*2TT57+28gz zf7@K!#?ifHv8g0B&5EsaqGXTDVtYw!zbkI|f=5#O3Km)qO5ydfvPlX6vJB7+gQpBY zqhtB`Upow$f}S4_Q?gia7mj-tn9m*ex%fT@D4muNIBmFn)KT8#ZYa4M?z-g_4)PM< zmtFN=tE`M%fQJp6li}M_+s4{+H&@xXDL{;C#@An03KT8H^ul#ja>BCIGXglh7DzoD z!7Y}p{g>V0k~@6Yy$*+Nov3Z$3Y`G3Q~DMdnU3x=iUICJbLK-@V{kWRbC5lz?B@c0 zjWPs78!}??Y$}Vb+>8%U0Tl=&^i#Cs>{P#44@~F2%sKE=9EY#?yA%$-UX30)U^wFH zO6Ag-tc>>%sp0LyCg7Qlly;i#g;oJmIFFUVl$IGV&X}%bPB#*#hvAxO2D55TL|jPg zlyQVg@NXR4f1nq?P8l={<6g=Yx_i&|!ruF{LniZmY-N5?&85@BF(qy!vKf=diYqgq zMck0IgN=$urm}57Mna_6QZHg!$?W`j@z#fp+ZcEcK3GlI4fNQUhCQaH9Pu5J}J?zGU!uAUfSyr7lDeBJZ_?nO~CMwmgK_+6Tcm ztDlXNA`xYI>xWd7)|QLt?{4pmukEhe4&?}Ex)0@2MxtwQ@bh0x(DraQo&;pXM-+Ko z!3#rNM+uE@OiK}_sRq*k#MFx|t76y-!bKpaHx`Sh6kU&NsZ=ZmjuZs0^_t#emopcI zQbKiGx#&Na&{u3DFVAmt@g4Iub^M0;&UJk2{9$IlgWotWvV3IT&GPH##nt@Q`Ir3s z_J6Ns_=pw5mZpegdgI_u*|c#sLCd6Ndec>zB}p(O3sv?%29Qe0E1|AJt*+s7iMXbB zE{iw2_;cW2mf|U7FCxQM|LcA^omF!w?G=0*rZmUv^y%~k$1u!2wB{bFy@#r;U)4P% f{R6%D8QS_8+W6S1uuP=bGk$#R_*aOIEuH@ZwODQo delta 1814 zcmah}U2GIp6ux(6XLmdMN88>0Q0&eY%XUa<`71w)var-*T?*1Q#YM92?o8V)vpaBS z3T>g3m?pN-h?^S)V>F5hS|P@yG4X*HcrYZqV3dSRF%c6V8eg#d#E=+0ceWIs^k(wi zd(QpNIrpA>=6u&{#r@ZPJ`usV`oX?|uWL&FxrsUUsUwtZRvErm^agD z&+K`}b}s4%j^#7V3^CK@AW<`lF@s46v<3!{NEna=soV7|UPafq4q|C`+BL^X0ozbN zq88IcHS}SUQ_1SbW~WJ*PKrD5Ci;WeiY0nayj;J9IeMDGc%ZwUC8eY^gXAEU4PBfvi4?`Yk~;%)$#{}4dt3CpSF%ISqd zrl^oMkY+eiX3^XJP8_05f#+8;7U^bGK5G_@3Rt}R zRXlrTnFCi1AjN$ikMk$_UFc9XLgNnlV`VLEtg2Xs(YqlBvNv9|HzL(xo*Sy9rC^YT ztK5F2;-uqa^a-bkmpm7F8mS8B_)Ff4>~Ua#dCY-Ek?iY9${cA2)f12fvW_X%16WRV z44NP^GI@h;4sGuk^Tl1gYgFzfX z#+ZP$rsB7QwPzEh#AkJ1 zuK0Y#SGk`e>%V{DTJ<&I#@3!2uVsG@=B7Gtc`MI!Pj{c&In{mB8~#%OJ0i{AX=vmp z)mycarR54E7|Xmuba#@^BKa zkkv;le1IgG&Z`U;3Zv;v&dlpYOCT9naX^*b@OYm}8IRoqRsnA;LhpKOs1)(wzS-8u zCJfym*F-rFyEfq%tfja)=*hC>aRx`J)LfXb3zH=aE@Ri^Qf_4N$*C?Wu7^^ZIQ#UHrP?5#pcz55Pd69 z?|I_eplesn!#{ddsHYpEU6o5+Y0=^oeJ3i_Ofp9vfYa!<+jqksz3FZt61@_wciNr9 zLw}7nPp~FSf()7&L>aJD5eSRODFDltPUp0YVdPXzOQ)eo8bNEf*I2pqos7yrWE;%- zuSxWPs~4n&O)jBzp(-S-UT6z|*tA^eSlAK}Ha~2_f=nc|e9=<&SiT(8gkCTY=UKxi z33|Onq7PeQ2YGmK+x-jz3ou~s`N+Mkpew_g`Xc!PL{^7}3~-mn7|)@GIaFzX6~Chm Yzo3r$&J!5R@AsbVEA>4