Тема: тетріс + алгоритм який його проходетиме
Привіт!
Побачив відео як алгоритм грає в тетріс, захотілось і собі такий зробити. (так як програмувати трішки умію)
Ну до алгоритма мені ще далеко поки роблю тетріс.
(тема була створена для того що якщо кому буде потрбен погано зроблений тетріс, щоб виглядало як його робив неумілий студент, нехай беруть (код тетріса під спойлером))
▼тетріс на pygame
import pygame
from copy import deepcopy
from random import choice
#config
W, H = 10, 20
TILE = 30
GAME_RES = W * TILE, H * TILE
FPS = 120
SECOND_IN_MINUTE = 60
ANIMATION_SPEED = FPS * SECOND_IN_MINUTE #for y
COLOR = pygame.Color(30, 30, 30) #figure color
FIGURES_POS = [[(-1,  0), (-2,  0), ( 0, 0), ( 1,  0)],
               [( 0, -1), (-1, -1), (-1, 0), ( 0,  0)],
               [(-1,  0), (-1,  1), ( 0, 0), ( 0, -1)],
               [( 0,  0), (-1,  0), ( 0, 1), (-1, -1)],
               [( 0,  0), ( 0, -1), ( 0, 1), (-1, -1)],
               [( 0,  0), ( 0, -1), ( 0, 1), ( 1, -1)],
               [( 0,  0), ( 0, -1), ( 0, 1), (-1,  0)]]
FIGURES = [[pygame.Rect(x + W // 2, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in FIGURES_POS]
class Tetris:
    def __init__(self):
        pygame.init()
        self.sc = pygame.display.set_mode(GAME_RES)
        self.clock = pygame.time.Clock()
        self.grid = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(W) for y in range(H)]
        self.figure_rect = pygame.Rect(0, 0, TILE - 2, TILE - 2)
        self.figure, self.next_figure = deepcopy(choice(FIGURES)), deepcopy(choice(FIGURES))
    
    def check_borders(self, i):
        if self.figure[i].x < 0 or self.figure[i].x > W - 1:
            return False
        elif self.figure[i].y > H - 1 or self.field[self.figure[i].y][self.figure[i].x]:
            return False
        return True
    def control(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
            if event.type == pygame.KEYDOWN:
                if   event.key == pygame.K_LEFT : self.dx = -1
                elif event.key == pygame.K_RIGHT: self.dx =  1
                elif event.key == pygame.K_DOWN : self.anim_limit = -1
                elif event.key == pygame.K_UP   : self.rotate_check = True
    def move_x(self):
        self.figure_old = deepcopy(self.figure)
        for i in range(4):
                self.figure[i].x += self.dx
                if not self.check_borders(i):
                    self.figure = deepcopy(self.figure_old)
                    break
        self.dx = 0
    
    def move_y(self):
        self.anim_count, self.figure_old = 0, deepcopy(self.figure)
        for i in range(4):
            self.figure[i].y += 1
            if not self.check_borders(i):
                for i in range(4):
                    self.field[self.figure_old[i].y][self.figure_old[i].x] = COLOR
                self.figure, self.next_figure = self.next_figure, deepcopy(choice(FIGURES))
                self.anim_limit = ANIMATION_SPEED
                break
    
    def rotate(self):
        self.figure_old = deepcopy(self.figure)
        center = self.figure[0]
        for i in range(4):
            x = self.figure[i].y - center.y
            y = self.figure[i].x - center.x
            self.figure[i].x = center.x - x
            self.figure[i].y = center.y + y
            if not self.check_borders(i):
                self.figure = deepcopy(self.figure_old)
                break
        self.rotate_check = False
    def check_lines(self):
        line = H - 1
        for row in range(H - 1, -1, -1):
            count = 0
            for i in range(W):
                if self.field[row][i]:
                    count += 1
                self.field[line][i] = self.field[row][i]
            if count < W: line -= 1
    def restart_game(self):
        self.field = [[0 for i in range(W)] for i in range(H)]
        self.anim_count, self.anim_speed, self.anim_limit, self.dx, self.rotate_check = 0, FPS, ANIMATION_SPEED, 0, False
    
    def run(self):
        self.restart_game()
        while 1:
            self.sc.fill(pygame.Color("black"))
            [pygame.draw.rect(self.sc, (20, 20, 20), i_rect, 1) for i_rect in self.grid] #draw gride
            self.anim_count += self.anim_speed
            self.control()
            # dx = 1 -> move right | dx = -1 -> move left
            if self.dx != 0                      : self.move_x()
            if self.anim_count > self.anim_limit : self.move_y()
            if self.rotate_check                 : self.rotate()
            self.check_lines() #check and delete full lines
            # draw figure
            for i in range(4):
                self.figure_rect.x = self.figure[i].x * TILE
                self.figure_rect.y = self.figure[i].y * TILE
                pygame.draw.rect(self.sc, COLOR, self.figure_rect)
            # draw field
            for y, raw in enumerate(self.field):
                for x, col in enumerate(raw):
                    if col:
                        self.figure_rect.x, self.figure_rect.y = x * TILE, y * TILE
                        pygame.draw.rect(self.sc, col, self.figure_rect)
            # game over
            for i in range(W):
                if self.field[1][i]:
                    self.restart_game()
            pygame.display.flip()
            self.clock.tick(FPS)
def main():
    tetris = Tetris()
    tetris.run()
if __name__ == "__main__":
    main()ну тетріс ніби зробив час для алгоритму...
upd1:
щось той алгоритм погано працює, вчора проблему шукав...
ну незнаю, потім напишу якщо знайду
upd2: алгоритм буде працювати на основі цього:
▼всі можливі позиції фігурки в тетрісі які може зробити людине (не враховуючи повільний спуск)
u - поворот, r - рух в право, l - рух в ліво, d - моментальний спуск
offsets = [
    ['d'],
    ['r', 'd'],
    ['l', 'd'],
    ['r', 'r', 'd'],
    ['l', 'l', 'd'],
    ['r', 'r', 'r', 'd'],
    ['l', 'l', 'l', 'd'],
    ['r', 'r', 'r', 'r', 'd'],
    ['l', 'l', 'l', 'l', 'd'],
    ['u', 'd'],
    ['u', 'r', 'd'],
    ['u', 'l', 'd'],
    ['u', 'r', 'r', 'd'],
    ['u', 'l', 'l', 'd'],
    ['u', 'r', 'r', 'r', 'd'],
    ['u', 'l', 'l', 'l', 'd'],
    ['u', 'r', 'r', 'r', 'r', 'd'],
    ['u', 'l', 'l', 'l', 'l', 'd'],
    ['u', 'u', 'd'],
    ['u', 'u', 'r', 'd'],
    ['u', 'u', 'l', 'd'],
    ['u', 'u', 'r', 'r', 'd'],
    ['u', 'u', 'l', 'l', 'd'],
    ['u', 'u', 'r', 'r', 'r', 'd'],
    ['u', 'u', 'l', 'l', 'l', 'd'],
    ['u', 'u', 'r', 'r', 'r', 'r', 'd'],
    ['u', 'u', 'l', 'l', 'l', 'l', 'd'],
    ['u', 'u', 'u', 'd'],
    ['u', 'u', 'u', 'r', 'd'],
    ['u', 'u', 'u', 'l', 'd'],
    ['u', 'u', 'u', 'r', 'r', 'd'],
    ['u', 'u', 'u', 'l', 'l', 'd'],
    ['u', 'u', 'u', 'r', 'r', 'r', 'd'],
    ['u', 'u', 'u', 'l', 'l', 'l', 'd'],
    ['u', 'u', 'u', 'r', 'r', 'r', 'r', 'd'],
    ['u', 'u', 'u', 'l', 'l', 'l', 'l', 'd'],
]
 (кількість ліній залежать від рандома)