見出し画像

Claudeでテトリスが作れるとは驚いた!

ふとテトリスをやってみたいなと思いましたので、Claudeでテトリスを作ってみました。


テトリス

1回のプロンプトではうまく行かずに、何回か実施してみて動くようになりました。


最初のプロンプト

コードが提示されましたが、実行してみるとエラーメッセージが出てくるので、そのエラーメッセージをそのままClaudeに貼り付けてみました。


エラーメッセージをそのままClaudeに貼り付け


修正されたコードを実行し、エラーが出たらそのままClaudeに貼り付けてを繰り返して、次のコードでテトリスが動くようになりました。

import pygame
import random

# 色の定義
colors = [
    (0, 0, 0),
    (120, 37, 179),
    (100, 179, 179),
    (80, 34, 22),
    (80, 134, 22),
    (180, 34, 22),
    (180, 34, 122),
]

# テトリミノの形状
tetrominos = [
    [[1, 5, 9, 13], [4, 5, 6, 7]],
    [[4, 5, 9, 10], [2, 6, 5, 9]],
    [[6, 7, 9, 10], [1, 5, 6, 10]],
    [[1, 2, 5, 9], [0, 4, 5, 6], [1, 5, 9, 8], [4, 5, 6, 10]],
    [[1, 2, 6, 10], [5, 6, 7, 9], [2, 6, 10, 11], [3, 5, 6, 7]],
    [[1, 4, 5, 6], [1, 4, 5, 9], [4, 5, 6, 9], [1, 5, 6, 9]],
    [[1, 2, 5, 6]],
]


class Tetris:
    def __init__(self, height, width):
        self.height = height
        self.width = width
        self.field = []
        self.score = 0
        self.level = 1
        self.state = "start"
        self.figure = None
        self.x = 0
        self.y = 0
        self.zoom = 20
        for i in range(height):
            new_line = []
            for j in range(width):
                new_line.append(0)
            self.field.append(new_line)

    def new_figure(self):
        self.figure = random.choice(tetrominos)
        self.color = random.randint(1, len(colors) - 1)
        self.x = int(self.width / 2 - len(self.figure[0]) / 2)
        self.y = 0
        self.rotation = 0

    def intersects(self):
        intersection = False
        for i in range(4):
            for j in range(4):
                if i * 4 + j in self.figure[self.rotation]:
                    if i + self.y > self.height - 1 or \
                       j + self.x > self.width - 1 or \
                       j + self.x < 0 or \
                       self.field[i + self.y][j + self.x] > 0:
                        intersection = True
        return intersection

    def freeze(self):
        for i in range(4):
            for j in range(4):
                if i * 4 + j in self.figure[self.rotation]:
                    self.field[i + self.y][j + self.x] = self.color
        self.break_lines()
        self.new_figure()
        if self.intersects():
            self.state = "gameover"

    def break_lines(self):
        lines = 0
        for i in range(1, self.height):
            zeros = 0
            for j in range(self.width):
                if self.field[i][j] == 0:
                    zeros += 1
            if zeros == 0:
                lines += 1
                for i1 in range(i, 1, -1):
                    for j in range(self.width):
                        self.field[i1][j] = self.field[i1 - 1][j]
        self.score += lines ** 2
        self.level = self.score // 10 + 1

    def go_space(self):
        while not self.intersects():
            self.y += 1
        self.y -= 1
        self.freeze()

    def go_down(self):
        self.y += 1
        if self.intersects():
            self.y -= 1
            self.freeze()

    def go_side(self, dx):
        old_x = self.x
        self.x += dx
        if self.intersects():
            self.x = old_x

    def rotate(self):
        old_rotation = self.rotation
        self.rotation = (self.rotation + 1) % len(self.figure)
        if self.intersects():
            self.rotation = old_rotation

# Pygameの初期化
pygame.init()

# ゲームウィンドウの設定
size = (400, 500)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Tetris")

# ゲームオブジェクトの初期化
game = Tetris(20, 10)
clock = pygame.time.Clock()
fps = 25
counter = 0
pressing_down = False

while True:
    if game.figure is None:
        game.new_figure()
    counter += 1
    if counter > 100000:
        counter = 0

    if counter % (fps // game.level // 2) == 0 or pressing_down:
        if game.state == "start":
            game.go_down()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                game.rotate()
            if event.key == pygame.K_DOWN:
                pressing_down = True
            if event.key == pygame.K_LEFT:
                game.go_side(-1)
            if event.key == pygame.K_RIGHT:
                game.go_side(1)
            if event.key == pygame.K_SPACE:
                game.go_space()
            if event.key == pygame.K_ESCAPE:
                pygame.quit()
                quit()
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_DOWN:
                pressing_down = False

    screen.fill((0, 0, 0))

    for i in range(game.height):
        for j in range(game.width):
            pygame.draw.rect(screen, (128, 128, 128), [game.x + game.zoom * j, game.y + game.zoom * i, game.zoom, game.zoom], 1)
            if game.field[i][j] > 0:
                pygame.draw.rect(screen, colors[game.field[i][j]],
                                 [game.x + game.zoom * j + 1, game.y + game.zoom * i + 1, game.zoom - 2, game.zoom - 1])

    if game.figure is not None:
        for i in range(4):
            for j in range(4):
                p = i * 4 + j
                if p in game.figure[game.rotation]:
                    pygame.draw.rect(screen, colors[game.color],
                                     [game.x + game.zoom * (j + game.x) + 1,
                                      game.y + game.zoom * (i + game.y) + 1,
                                      game.zoom - 2, game.zoom - 2])

    font = pygame.font.SysFont('Calibri', 25, True, False)
    font1 = pygame.font.SysFont('Calibri', 65, True, False)
    text_score = font.render("Score: " + str(game.score), True, (255, 255, 255))
    text_level = font.render("Level: " + str(game.level), True, (255, 255, 255))
    text_game_over = font1.render("Game Over", True, (255, 125, 0))
    text_game_over1 = font1.render("Press ESC", True, (255, 215, 0))

    screen.blit(text_score, [0, 0])
    screen.blit(text_level, [0, 30])
    if game.state == "gameover":
        screen.blit(text_game_over, [20, 200])
        screen.blit(text_game_over1, [25, 265])

    pygame.display.flip()
    clock.tick(fps)

上記をtest.pyとして、下記コマンドで実行してみます。

pip install pygame
python test.py

矢印キーで移動でき、上矢印で回転できます。


初期画面
終了画面

ESCキーをクリックすれば、終了します。


この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?