0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Sonnet 4にマリオっぽいやつ作らせてみた

Last updated at Posted at 2025-05-28

はじめに

最近発表されたClaude Sonnet 4があんまり盛り上がってない気がするのですが、気のせいでしょうか。
それはさておき、今回のモデルの性能をマリオを作らせて検証してみました。

コード

python
import pygame
import sys

# 初期化
pygame.init()

# 画面サイズ
WIDTH = 800
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("マリオゲーム")

# 色の定義
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
BROWN = (139, 69, 19)
SKY_BLUE = (135, 206, 235)
YELLOW = (255, 255, 0)

# ゲームクロック
clock = pygame.time.Clock()

class Mario:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 40
        self.vel_x = 0
        self.vel_y = 0
        self.on_ground = False
        self.speed = 5
        self.jump_power = -15
        self.gravity = 0.8
        self.max_fall_speed = 10
        
    def update(self):
        # 重力を適用
        if not self.on_ground:
            self.vel_y += self.gravity
            if self.vel_y > self.max_fall_speed:
                self.vel_y = self.max_fall_speed
        
        # 位置を更新
        self.x += self.vel_x
        self.y += self.vel_y
        
        # 画面端での処理
        if self.x < 0:
            self.x = 0
        elif self.x > WIDTH - self.width:
            self.x = WIDTH - self.width
            
        # 地面との衝突判定
        self.check_ground_collision()
        
        # プラットフォームとの衝突判定
        self.check_platform_collision()
        
    def check_ground_collision(self):
        # 地面(画面下部)との衝突
        if self.y + self.height >= HEIGHT - 50:
            self.y = HEIGHT - 50 - self.height
            self.vel_y = 0
            self.on_ground = True
        else:
            self.on_ground = False
            
    def check_platform_collision(self):
        mario_rect = pygame.Rect(self.x, self.y, self.width, self.height)
        
        for platform in platforms:
            platform_rect = pygame.Rect(platform['x'], platform['y'], platform['width'], platform['height'])
            
            if mario_rect.colliderect(platform_rect):
                # 上から落ちてきた場合
                if self.vel_y > 0 and self.y < platform['y']:
                    self.y = platform['y'] - self.height
                    self.vel_y = 0
                    self.on_ground = True
                # 下から来た場合
                elif self.vel_y < 0 and self.y > platform['y']:
                    self.y = platform['y'] + platform['height']
                    self.vel_y = 0
                # 横から来た場合
                elif self.vel_x > 0:  # 右に移動中
                    self.x = platform['x'] - self.width
                elif self.vel_x < 0:  # 左に移動中
                    self.x = platform['x'] + platform['width']
    
    def jump(self):
        if self.on_ground:
            self.vel_y = self.jump_power
            self.on_ground = False
    
    def move_left(self):
        self.vel_x = -self.speed
    
    def move_right(self):
        self.vel_x = self.speed
    
    def stop_horizontal(self):
        self.vel_x = 0
    
    def draw(self, screen):
        # マリオの体(赤い帽子と青いオーバーオール)
        # 帽子
        pygame.draw.rect(screen, RED, (self.x, self.y, self.width, 15))
        # 顔
        pygame.draw.rect(screen, (255, 220, 177), (self.x + 5, self.y + 10, self.width - 10, 15))
        # オーバーオール
        pygame.draw.rect(screen, BLUE, (self.x + 3, self.y + 20, self.width - 6, 20))
        # 足
        pygame.draw.rect(screen, BROWN, (self.x + 5, self.y + 35, 8, 5))
        pygame.draw.rect(screen, BROWN, (self.x + 17, self.y + 35, 8, 5))

class Enemy:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 25
        self.height = 25
        self.speed = 2
        self.direction = -1  # -1は左、1は右
        
    def update(self):
        self.x += self.speed * self.direction
        
        # 画面端で方向転換
        if self.x <= 0 or self.x >= WIDTH - self.width:
            self.direction *= -1
            
        # プラットフォームの端で方向転換
        on_platform = False
        for platform in platforms:
            if (self.y + self.height >= platform['y'] and 
                self.y + self.height <= platform['y'] + platform['height'] + 10 and
                self.x + self.width > platform['x'] and 
                self.x < platform['x'] + platform['width']):
                on_platform = True
                break
                
        if not on_platform and self.y + self.height < HEIGHT - 50:
            self.direction *= -1
    
    def draw(self, screen):
        # 敵(茶色のクリボー風)
        pygame.draw.ellipse(screen, BROWN, (self.x, self.y, self.width, self.height))
        # 目
        pygame.draw.circle(screen, WHITE, (self.x + 8, self.y + 8), 3)
        pygame.draw.circle(screen, WHITE, (self.x + 17, self.y + 8), 3)
        pygame.draw.circle(screen, (0, 0, 0), (self.x + 8, self.y + 8), 1)
        pygame.draw.circle(screen, (0, 0, 0), (self.x + 17, self.y + 8), 1)

class Coin:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 20
        self.height = 20
        self.collected = False
        
    def draw(self, screen):
        if not self.collected:
            pygame.draw.circle(screen, YELLOW, (self.x + 10, self.y + 10), 10)
            pygame.draw.circle(screen, (255, 215, 0), (self.x + 10, self.y + 10), 8)

# ゲームオブジェクトの初期化
mario = Mario(50, HEIGHT - 100)

# プラットフォーム
platforms = [
    {'x': 200, 'y': 450, 'width': 150, 'height': 20},
    {'x': 400, 'y': 350, 'width': 150, 'height': 20},
    {'x': 600, 'y': 250, 'width': 150, 'height': 20},
    {'x': 100, 'y': 300, 'width': 80, 'height': 20},
]

# 敵
enemies = [
    Enemy(250, 425),
    Enemy(450, 325),
    Enemy(650, 225),
]

# コイン
coins = [
    Coin(220, 420),
    Coin(270, 420),
    Coin(420, 320),
    Coin(470, 320),
    Coin(620, 220),
    Coin(670, 220),
]

# スコア
score = 0
font = pygame.font.Font(None, 36)

# ゲームループ
running = True
while running:
    # イベント処理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    # キー入力処理
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] or keys[pygame.K_a]:
        mario.move_left()
    elif keys[pygame.K_RIGHT] or keys[pygame.K_d]:
        mario.move_right()
    else:
        mario.stop_horizontal()
    
    if keys[pygame.K_SPACE] or keys[pygame.K_UP] or keys[pygame.K_w]:
        mario.jump()
    
    # ゲームオブジェクトの更新
    mario.update()
    
    for enemy in enemies:
        enemy.update()
    
    # 衝突判定
    mario_rect = pygame.Rect(mario.x, mario.y, mario.width, mario.height)
    
    # 敵との衝突
    for enemy in enemies:
        enemy_rect = pygame.Rect(enemy.x, enemy.y, enemy.width, enemy.height)
        if mario_rect.colliderect(enemy_rect):
            # ゲームオーバー(リスタート)
            mario.x = 50
            mario.y = HEIGHT - 100
            mario.vel_x = 0
            mario.vel_y = 0
            score = max(0, score - 10)
    
    # コインとの衝突
    for coin in coins:
        if not coin.collected:
            coin_rect = pygame.Rect(coin.x, coin.y, coin.width, coin.height)
            if mario_rect.colliderect(coin_rect):
                coin.collected = True
                score += 10
    
    # 描画
    screen.fill(SKY_BLUE)
    
    # 地面
    pygame.draw.rect(screen, GREEN, (0, HEIGHT - 50, WIDTH, 50))
    
    # プラットフォーム
    for platform in platforms:
        pygame.draw.rect(screen, BROWN, (platform['x'], platform['y'], platform['width'], platform['height']))
    
    # ゲームオブジェクトの描画
    mario.draw(screen)
    
    for enemy in enemies:
        enemy.draw(screen)
    
    for coin in coins:
        coin.draw(screen)
    
    # スコア表示
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))
    
    # 操作説明
    controls_text = font.render("←→/AD: Move, Space/↑/W: Jump", True, WHITE)
    screen.blit(controls_text, (10, HEIGHT - 30))
    
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()

結果

スクリーンショット 2025-05-28 022948.png

いい感じに動作しました。見た目もぽい。
左上の茶色の台h何目的で作ったんだろう。。

感想

  • 1回の実行でエラー起こさずに生成できるのがすごい
  • 生成のスピードが速いと感じた
  • SWE-benchで、GPT-4.1やGemini 2.5 Proを大幅に超える性能を示していただけあって、正確性が高い
  • 新しくコードを書きたいときの一発目に使うのが効果を実感できそう
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?