import pygame
import random
import sys

# 初期化
pygame.init()

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

# 色の定義
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)

# フォント設定
font = pygame.font.SysFont(None, 36)

# FPS設定
clock = pygame.time.Clock()
FPS = 60

# プレイヤー設定
player_width, player_height = 60, 20
player_x = (WIDTH - player_width) // 2
player_y = HEIGHT - 50
player_speed = 5

# 弾設定
bullet_width, bullet_height = 5, 10
bullet_speed = 7
bullets = []

# 敵設定
enemy_width, enemy_height = 40, 30
enemy_speed = 1
enemy_direction = 1 # 1:右, -1:左
enemies = []
enemy_rows = 3
enemy_cols = 7
enemy_padding = 20
enemy_offset_x = 100
enemy_offset_y = 50

# UFO設定
ufo_width, ufo_height = 60, 30
ufo_speed = 3
ufo = None
ufo_timer = 0
UFO_INTERVAL = 10 * FPS # 10秒ごとにUFO出現

# スコアとステージ
score = 0
stage = 1

# ゲームオーバーフラグ
game_over = False

def create_enemies():
    new_enemies = []
    # グローバル変数のenemy_speedをここで参照しないように注意(create_enemiesが呼ばれる前に設定されている)
    for row in range(enemy_rows):
        for col in range(enemy_cols):
            x = enemy_offset_x + col * (enemy_width + enemy_padding)
            y = enemy_offset_y + row * (enemy_height + enemy_padding)
            new_enemies.append(pygame.Rect(x, y, enemy_width, enemy_height))
    return new_enemies

# ゲーム開始時に一度敵を作成
enemies = create_enemies()

def draw_player(x, y):
    pygame.draw.rect(screen, WHITE, (x, y, player_width, player_height))

def draw_bullets(bullets):
    for bullet in bullets:
        pygame.draw.rect(screen, RED, bullet)

def draw_enemies(enemies):
    for enemy in enemies:
        pygame.draw.rect(screen, WHITE, enemy)

def draw_ufo(ufo):
    if ufo:
        pygame.draw.rect(screen, GREEN, ufo)

def draw_score(score, stage):
    text = font.render(f"Score: {score} Stage: {stage}", True, WHITE)
    screen.blit(text, (10, 10))

def draw_game_over():
    text = font.render("GAME OVER", True, RED)
    text_rect = text.get_rect(center=(WIDTH // 2, HEIGHT // 2))
    screen.blit(text, text_rect)

# メインループ
running = True
while running:
    clock.tick(FPS)
    screen.fill(BLACK)

    # イベント処理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    if not game_over:
        # キー入力処理
        keys = pygame.key.get_pressed()
        # プレイヤーの移動制限を考慮
        if keys[pygame.K_LEFT]:
            player_x -= player_speed
            if player_x < 0: # 画面左端に制限
                player_x = 0
        if keys[pygame.K_RIGHT]:
            player_x += player_speed
            if player_x > WIDTH - player_width: # 画面右端に制限
                player_x = WIDTH - player_width
        
        # スペースキーは押しっぱなしではなく、押された瞬間に弾を発射するように変更(連続発射防止)
        # ただし、現在のコードでは長押しで連続発射されているので、その挙動を維持
        # もし1発ずつにしたい場合は event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE で判定する
        if keys[pygame.K_SPACE]:
            # 画面上に弾が5発未満の場合に発射
            if len(bullets) < 5:
                bullet = pygame.Rect(player_x + player_width // 2 - bullet_width // 2,
                                     player_y, bullet_width, bullet_height)
                bullets.append(bullet)

        # 弾の移動
        for bullet in bullets[:]: # リストをコピーして要素削除中のエラーを防ぐ
            bullet.y -= bullet_speed
            if bullet.y < 0:
                bullets.remove(bullet)

        # 敵の移動ロジック (修正箇所)
        move_down = False
        for enemy in enemies:
            enemy.x += enemy_speed * enemy_direction
            
            # 画面端での位置調整
            if enemy.right >= WIDTH:
                enemy.right = WIDTH # 画面右端に強制的に固定
                move_down = True
            elif enemy.left <= 0:
                enemy.left = 0 # 画面左端に強制的に固定
                move_down = True

        if move_down:
            enemy_direction *= -1 # 方向転換
            for enemy in enemies:
                enemy.y += enemy_height # Y座標を下げる

        # 弾と敵の衝突判定
        for bullet in bullets[:]:
            for enemy in enemies[:]:
                if bullet.colliderect(enemy):
                    bullets.remove(bullet)
                    enemies.remove(enemy) # 敵をリストから削除
                    score += 100
                    break # 1つの弾は1つの敵にしか当たらないため、内側のループを抜ける

        # 敵が画面下部に到達したかチェック
        for enemy in enemies:
            if enemy.bottom >= player_y: # プレイヤーのY座標まで到達したらゲームオーバー
                game_over = True
                break
        
        # 敵を全滅させた場合
        if not enemies:
            stage += 1
            enemy_speed += 0.5 # 敵の速度を上げる
            # 次のステージのために新しい敵を生成
            enemies = create_enemies()
            # 敵のY座標がリセットされるが、念のため敵の方向も初期化
            enemy_direction = 1 # 新しいステージは常に右からスタート

        # UFOの出現管理
        ufo_timer += 1
        if ufo_timer >= UFO_INTERVAL:
            ufo_timer = 0
            ufo_y = 50
            ufo_direction_choice = random.choice([-1, 1]) # UFOの進行方向を決定
            if ufo_direction_choice == 1: # 右から左へ
                ufo_x = -ufo_width
                ufo_speed = 3 # 正の方向
            else: # 左から右へ
                ufo_x = WIDTH
                ufo_speed = -3 # 負の方向

            ufo = pygame.Rect(ufo_x, ufo_y, ufo_width, ufo_height)
            # ufo_speedは上で設定済みなので、ここでは設定しない

        # UFOの移動
        if ufo:
            ufo.x += ufo_speed
            # UFOが画面外に出たら消滅させる
            if (ufo_speed > 0 and ufo.left > WIDTH) or \
               (ufo_speed < 0 and ufo.right < 0):
                ufo = None

        # 弾とUFOの衝突判定
        if ufo: # UFOが存在する場合のみ判定
            for bullet in bullets[:]:
                if bullet.colliderect(ufo):
                    bullets.remove(bullet)
                    ufo = None # UFOを消滅させる
                    score += 500
                    break # 弾がUFOに当たったら、その弾は消えるのでループを抜ける

        # 描画
        draw_player(player_x, player_y)
        draw_bullets(bullets)
        draw_enemies(enemies)
        draw_ufo(ufo)
        draw_score(score, stage)
    else:
        # ゲームオーバー画面の描画
        draw_game_over()
        # ゲームオーバー時のキー入力で再スタートなどを実装するならここに追記
        # 今回は特に再スタートロジックは追加していません

    pygame.display.flip() # 画面を更新

# Pygameの終了処理
pygame.quit()
sys.exit()