import pygame
import random
# 初期化
pygame.init()
WIDTH, HEIGHT = 300, 600
BLOCK_SIZE = 30
COLUMNS = WIDTH // BLOCK_SIZE
ROWS = HEIGHT // BLOCK_SIZE
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("テトリス風ゲーム")
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 24)
# 色
colors = [
(0, 0, 0), # 空
(255, 0, 0), # 赤
(0, 255, 0), # 緑
(0, 0, 255), # 青
(255, 255, 0), # 黄
(255, 165, 0), # オレンジ
(128, 0, 128), # 紫
(0, 255, 255) # シアン
]
# ブロック形状
shapes = [
[[1, 1, 1, 1]], # I
[[2, 2], [2, 2]], # O
[[0, 3, 0], [3, 3, 3]], # T
[[4, 0, 0], [4, 4, 4]], # L
[[0, 0, 5], [5, 5, 5]], # J
[[6, 6, 0], [0, 6, 6]], # S
[[0, 7, 7], [7, 7, 0]] # Z
]
class Block:
def __init__(self):
self.shape = random.choice(shapes)
self.color = max(max(row) for row in self.shape)
self.x = COLUMNS // 2 - len(self.shape[0]) // 2
self.y = 0
def rotate(self):
self.shape = [list(row) for row in zip(*self.shape[::-1])]
class Grid:
def __init__(self):
self.grid = [[0 for _ in range(COLUMNS)] for _ in range(ROWS)]
def is_valid(self, block):
for i, row in enumerate(block.shape):
for j, cell in enumerate(row):
if cell:
x = block.x + j
y = block.y + i
if x < 0 or x >= COLUMNS or y >= ROWS or self.grid[y][x]:
return False
return True
def place(self, block):
for i, row in enumerate(block.shape):
for j, cell in enumerate(row):
if cell:
self.grid[block.y + i][block.x + j] = block.color
def clear_lines(self):
cleared = 0
new_grid = []
for row in self.grid:
if all(cell != 0 for cell in row):
cleared += 1
else:
new_grid.append(row)
while len(new_grid) < ROWS:
new_grid.insert(0, [0 for _ in range(COLUMNS)])
self.grid = new_grid
return cleared
def draw(self):
for y in range(ROWS):
for x in range(COLUMNS):
color = colors[self.grid[y][x]]
pygame.draw.rect(screen, color, (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
pygame.draw.rect(screen, (50, 50, 50), (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)
class Game:
def __init__(self, high_score=0):
self.grid = Grid()
self.block = Block()
self.score = 0
self.lines_cleared = 0
self.fall_timer = 0
self.fall_delay = 500
self.key_timer = 0
self.key_delay = 50
self.game_over = False
self.high_score = high_score
def update(self, dt):
if self.game_over:
return
self.fall_timer += dt
self.key_timer += dt
if self.fall_timer > self.fall_delay:
self.block.y += 1
if not self.grid.is_valid(self.block):
self.block.y -= 1
self.grid.place(self.block)
cleared = self.grid.clear_lines()
self.score += cleared * 100
self.lines_cleared += cleared
self.block = Block()
if not self.grid.is_valid(self.block):
self.game_over = True
if self.score > self.high_score:
self.high_score = self.score
self.adjust_speed()
self.fall_timer = 0
keys = pygame.key.get_pressed()
if self.key_timer > self.key_delay:
if keys[pygame.K_DOWN]:
self.block.y += 1
if not self.grid.is_valid(self.block):
self.block.y -= 1
if keys[pygame.K_LEFT]:
self.block.x -= 1
if not self.grid.is_valid(self.block):
self.block.x += 1
if keys[pygame.K_RIGHT]:
self.block.x += 1
if not self.grid.is_valid(self.block):
self.block.x -= 1
self.key_timer = 0
def adjust_speed(self):
self.fall_delay = max(100, 500 - self.lines_cleared * 10)
def draw(self):
self.grid.draw()
for i, row in enumerate(self.block.shape):
for j, cell in enumerate(row):
if cell:
x = self.block.x + j
y = self.block.y + i
pygame.draw.rect(screen, colors[self.block.color], (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 0)
pygame.draw.rect(screen, (255, 255, 255), (x * BLOCK_SIZE, y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), 1)
score_text = font.render(f"Score: {self.score}", True, (255, 255, 255))
screen.blit(score_text, (10, 10))
hs_text = font.render(f"High Score: {self.high_score}", True, (255, 255, 0))
screen.blit(hs_text, (10, 40))
if self.game_over:
over_text = font.render("Game Over - Press Any Key", True, (255, 0, 0))
screen.blit(over_text, (WIDTH // 2 - over_text.get_width() // 2, HEIGHT // 2))
def main():
game = Game()
running = True
while running:
dt = clock.tick(60)
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if game.game_over:
game = Game(high_score=game.high_score)
else:
if event.key == pygame.K_UP:
game.block.rotate()
if not game.grid.is_valid(game.block):
game.block.rotate()
game.block.rotate()
game.block.rotate()
game.update(dt)
game.draw()
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()