🎮
Amazon Q CLI でVibe Codingしてゲームを作ってみた
この記事はAmazon Q CLI でゲームを作ろう Tシャツキャンペーン のチャレンジ記事です。
開発環境
PC(M4 Macbook Pro)
Python3(Brew install)
PyGame(pip install)
Amazon Q CLI(User Guideを参考)
ゲーム
「作ってみた」なのでシンプルなトランプゲームにしました。
内容としては画面中央に裏向きで並ぶ2枚のトランプを選び、めくって数字勝負をするものです。
高い数字のカードを引き当てればスコアが伸びて「Next」ボタンで次の挑戦へ。外すとゲームオーバー。
シンプルですがはまりやすいゲームです。
プロンプト
Amazon Q CLIへ入力するプロンプトは下記となります。
プロンプト
You are an expert Python game developer.
TASK
Write one runnable Python-3 script with Pygame that implements this “Higher Card” mini-game.
1. ✦ Window
• 800 × 600 px, green-felt background.
2. ✦ Cards
• Two rectangles (120 × 160) side-by-side, centered.
• At the start of each round they are face-down (solid blue, white border, centered “?”).
• When flipped face-up they show **only the rank text** (“2”–“10”, “J”, “Q”, “K”, “A”) in blue.
• No suit symbols or extra graphics.
3. ✦ Gameplay flow
a. Wait for a left-click on either card.
b. Immediately flip **both** cards face-up.
c. If the chosen card’s value is higher → **do NOT auto-advance**.
• Display a centered “Next” button directly **below the bottom edge of the cards**.
• Clicking that button starts a fresh face-down round (score + 1).
d. If the chosen card’s value is lower or a tie → enter **Game Over state** (see §4).
4. ✦ Game Over state
• Leave the revealed cards on screen.
• Centered under the cards: large “Game Over!” text.
• Under that, a “Restart” button.
• Clicking “Restart” resets the score to 0 and begins a new face-down round.
• Window close still exits; no keyboard shortcuts are required.
5. ✦ UI elements
• Top-left persistent label: “Correct Guesses: <n>”.
• Center-top instruction “Click on the higher card!” appears only while waiting for the first click of each round.
6. ✦ Code quality
• Organize with a `Game` class and helper methods.
• Use constants for colors, sizes, etc.
• Clear inline comments; follow PEP-8 spacing.
• Depend only on Pygame and the Python standard library.
OUTPUT
Return **only** the full Python script—no explanations, no extra text.
プロンプトの日本語訳は以下のとおりです。
日本語訳
あなたは Python ゲーム開発のエキスパートです。
【タスク】
Pygame を使い、次の仕様の「ハイヤーカード」ミニゲームを 1 本の Python-3 スクリプトとして実装してください。
1. ✦ ウィンドウ
• 800×600 px、背景は緑のフェルト。
2. ✦ カード
• 120×160 の矩形 2 枚を中央に横並び。
• ラウンド開始時は裏向き(青塗り+白枠+中央に “?”)。
• 表向きでは **ランク文字のみ**(“2”〜“10”/J/Q/K/A)を青色で表示。
• 絵柄やスートは一切描かない。
3. ✦ ゲーム進行
a. プレイヤーがカードを 1 枚クリック。
b. ただちに両カードを表向きに反転。
c. 選んだカードが高ければ **自動で次ラウンドへ進まず**、
• **カードの下端直下**に中央揃えで「Next」ボタンを表示。
• ボタンがクリックされたらスコアを +1 し、新ラウンド(裏向き)へ。
d. 低い(または同値)場合は **Game Over 状態**へ(§4)。
4. ✦ Game Over 状態
• 表になったカードをそのまま表示。
• カードの直下に大きく中央で “Game Over!” と表示。
• さらにその下に「Restart」ボタンを表示。
• Restart をクリックするとスコアを 0 にリセットし、新しいラウンドを開始。
• ウィンドウを閉じれば終了。キーボード操作は不要。
5. ✦ UI
• 左上に「Correct Guesses: <n>」を常時表示。
• ラウンド待機中のみ、画面上部中央に “Click on the higher card!” を表示。
6. ✦ コード品質
• `Game` クラスと補助メソッドで構造化。
• 色・サイズ等は定数化。
• 主要部にコメント、PEP-8 準拠。
• 依存は Pygame と標準ライブラリのみ。
【出力形式】
説明文は一切書かず、完成した Python スクリプトだけを返してください。
Amazon Q CLI でVibe Coding
Macのターミナルを起動後q chat
でAmazon Q CLIを立ち上げます。
Amazon Q CLI
% q chat
⢠⣶⣶⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣶⣦⡀⠀
⠀⠀⠀⣾⡿⢻⣿⡆⠀⠀⠀⢀⣄⡄⢀⣠⣤⣤⡀⢀⣠⣤⣤⡀⠀⠀⢀⣠⣤⣤⣤⣄⠀⠀⢀⣤⣤⣤⣤⣤⣤⡀⠀⠀⣀⣤⣤⣤⣀⠀⠀⠀⢠⣤⡀⣀⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⢠⣿⣿⠋⠀⠀⠀⠙⣿⣿⡆
⠀⠀⣼⣿⠇⠀⣿⣿⡄⠀⠀⢸⣿⣿⠛⠉⠻⣿⣿⠛⠉⠛⣿⣿⠀⠀⠘⠛⠉⠉⠻⣿⣧⠀⠈⠛⠛⠛⣻⣿⡿⠀⢀⣾⣿⠛⠉⠻⣿⣷⡀⠀⢸⣿⡟⠛⠉⢻⣿⣷⠀⠀⠀⠀⠀⠀⣼⣿⡏⠀⠀⠀⠀⠀⢸⣿⣿
⠀⢰⣿⣿⣤⣤⣼⣿⣷⠀⠀⢸⣿⣿⠀⠀⠀⣿⣿⠀⠀⠀⣿⣿⠀⠀⢀⣴⣶⣶⣶⣿⣿⠀⠀⠀⣠⣾⡿⠋⠀⠀⢸⣿⣿⠀⠀⠀⣿⣿⡇⠀⢸⣿⡇⠀⠀⢸⣿⣿⠀⠀⠀⠀⠀⠀⢹⣿⣇⠀⠀⠀⠀⠀⢸⣿⡿
⢀⣿⣿⠋⠉⠉⠉⢻⣿⣇⠀⢸⣿⣿⠀⠀⠀⣿⣿⠀⠀⠀⣿⣿⠀⠀⣿⣿⡀⠀⣠⣿⣿⠀⢀⣴⣿⣋⣀⣀⣀⡀⠘⣿⣿⣄⣀⣠⣿⣿⠃⠀⢸⣿⡇⠀⠀⢸⣿⣿⠀⠀⠀⠀⠀⠀⠈⢿⣿⣦⣀⣀⣀⣴⣿⡿⠃
⠚⠛⠋⠀⠀⠀⠀⠘⠛⠛⠀⠘⠛⠛⠀⠀⠀⠛⠛⠀⠀⠀⠛⠛⠀⠀⠙⠻⠿⠟⠋⠛⠛⠀⠘⠛⠛⠛⠛⠛⠛⠃⠀⠈⠛⠿⠿⠿⠛⠁⠀⠀⠘⠛⠃⠀⠀⠘⠛⠛⠀⠀⠀⠀⠀⠀⠀⠀⠙⠛⠿⢿⣿⣿⣋⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⢿⡧
╭─────────────────────────────── Did you know? ────────────────────────────────╮
│ │
│ You can use /editor to edit your prompt with a vim-like experience │
│ │
╰──────────────────────────────────────────────────────────────────────────────╯
/help all commands • ctrl + j new lines • ctrl + s fuzzy search
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🤖 You are chatting with claude-4-sonnet
今回はClaude 4 Sonnetで開発をするためモデルを明示的に指定しました。
> /model
✔ Select a model for this chat session · claude-4-sonnet (active)
Using claude-4-sonnet
プロンプトを貼り付けます
Amazon Q CLI
>You are an expert Python game developer.
TASK
Write one runnable Python-3 script with Pygame that implements this “Higher Card” mini-game.
1. ✦ Window
• 800 × 600 px, green-felt background.
2. ✦ Cards
• Two rectangles (120 × 160) side-by-side, centered.
• At the start of each round they are face-down (solid blue, white border, centered “?”).
• When flipped face-up they show **only the rank text** (“2”–“10”, “J”, “Q”, “K”, “A”) in blue.
• No suit symbols or extra graphics.
3. ✦ Gameplay flow
a. Wait for a left-click on either card.
b. Immediately flip **both** cards face-up.
c. If the chosen card’s value is higher → **do NOT auto-advance**.
• Display a centered “Next” button directly **below the bottom edge of the cards**.
• Clicking that button starts a fresh face-down round (score + 1).
d. If the chosen card’s value is lower or a tie → enter **Game Over state** (see §4).
4. ✦ Game Over state
• Leave the revealed cards on screen.
• Centered under the cards: large “Game Over!” text.
• Under that, a “Restart” button.
• Clicking “Restart” resets the score to 0 and begins a new face-down round.
• Window close still exits; no keyboard shortcuts are required.
5. ✦ UI elements
• Top-left persistent label: “Correct Guesses: <n>”.
• Center-top instruction “Click on the higher card!” appears only while waiting for the first click of each round.
6. ✦ Code quality
• Organize with a `Game` class and helper methods.
• Use constants for colors, sizes, etc.
• Clear inline comments; follow PEP-8 spacing.
• Depend only on Pygame and the Python standard library.
OUTPUT
Return **only** the full Python script—no explanations, no extra text.
プロンプトを入力するとAmazon Q CLIがソースコードを生成してくれました
生成されたコード
import pygame
import random
import sys
# Initialize Pygame
pygame.init()
# Constants
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
CARD_WIDTH = 120
CARD_HEIGHT = 160
CARD_SPACING = 40
# Colors
GREEN_FELT = (34, 139, 34)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0)
GRAY = (128, 128, 128)
# Card values and their numeric equivalents
CARD_RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
CARD_VALUES = {rank: i + 2 for i, rank in enumerate(CARD_RANKS)}
class Game:
def __init__(self):
self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Higher Card Game")
self.clock = pygame.time.Clock()
self.font = pygame.font.Font(None, 36)
self.large_font = pygame.font.Font(None, 48)
# Game state
self.score = 0
self.game_state = "waiting" # "waiting", "revealed", "game_over"
self.left_card = None
self.right_card = None
self.chosen_card = None
# UI elements
self.next_button_rect = None
self.restart_button_rect = None
self.new_round()
def new_round(self):
"""Start a new round with face-down cards"""
self.left_card = random.choice(CARD_RANKS)
self.right_card = random.choice(CARD_RANKS)
self.game_state = "waiting"
self.chosen_card = None
def get_card_rects(self):
"""Calculate card positions"""
total_width = 2 * CARD_WIDTH + CARD_SPACING
start_x = (WINDOW_WIDTH - total_width) // 2
card_y = (WINDOW_HEIGHT - CARD_HEIGHT) // 2
left_rect = pygame.Rect(start_x, card_y, CARD_WIDTH, CARD_HEIGHT)
right_rect = pygame.Rect(start_x + CARD_WIDTH + CARD_SPACING, card_y, CARD_WIDTH, CARD_HEIGHT)
return left_rect, right_rect
def draw_card(self, rect, rank=None, face_up=False):
"""Draw a single card"""
# Draw card background
pygame.draw.rect(self.screen, BLUE, rect)
pygame.draw.rect(self.screen, WHITE, rect, 3)
if face_up and rank:
# Draw rank text
text = self.font.render(rank, True, BLUE)
text_rect = text.get_rect(center=rect.center)
# Fill background with white first
pygame.draw.rect(self.screen, WHITE, rect.inflate(-6, -6))
pygame.draw.rect(self.screen, WHITE, rect, 3)
self.screen.blit(text, text_rect)
else:
# Draw question mark for face-down card
text = self.font.render("?", True, WHITE)
text_rect = text.get_rect(center=rect.center)
self.screen.blit(text, text_rect)
def draw_button(self, text, x, y, width=120, height=40):
"""Draw a button and return its rect"""
button_rect = pygame.Rect(x - width//2, y, width, height)
pygame.draw.rect(self.screen, GRAY, button_rect)
pygame.draw.rect(self.screen, BLACK, button_rect, 2)
button_text = self.font.render(text, True, BLACK)
text_rect = button_text.get_rect(center=button_rect.center)
self.screen.blit(button_text, text_rect)
return button_rect
def handle_card_click(self, pos):
"""Handle clicking on a card"""
if self.game_state != "waiting":
return
left_rect, right_rect = self.get_card_rects()
if left_rect.collidepoint(pos):
self.chosen_card = "left"
elif right_rect.collidepoint(pos):
self.chosen_card = "right"
else:
return
# Reveal both cards
self.game_state = "revealed"
# Check if chosen card is higher
chosen_value = CARD_VALUES[self.left_card if self.chosen_card == "left" else self.right_card]
other_value = CARD_VALUES[self.right_card if self.chosen_card == "left" else self.left_card]
if chosen_value > other_value:
# Correct guess - show Next button
pass
else:
# Wrong guess or tie - game over
self.game_state = "game_over"
def handle_next_click(self):
"""Handle clicking the Next button"""
self.score += 1
self.new_round()
def handle_restart_click(self):
"""Handle clicking the Restart button"""
self.score = 0
self.new_round()
def draw(self):
"""Draw the entire game"""
self.screen.fill(GREEN_FELT)
# Draw score
score_text = self.font.render(f"Correct Guesses: {self.score}", True, WHITE)
self.screen.blit(score_text, (10, 10))
# Draw instruction text (only when waiting)
if self.game_state == "waiting":
instruction_text = self.font.render("Click on the higher card!", True, WHITE)
instruction_rect = instruction_text.get_rect(centerx=WINDOW_WIDTH//2, y=50)
self.screen.blit(instruction_text, instruction_rect)
# Draw cards
left_rect, right_rect = self.get_card_rects()
face_up = self.game_state in ["revealed", "game_over"]
self.draw_card(left_rect, self.left_card, face_up)
self.draw_card(right_rect, self.right_card, face_up)
# Draw buttons based on game state
if self.game_state == "revealed":
chosen_value = CARD_VALUES[self.left_card if self.chosen_card == "left" else self.right_card]
other_value = CARD_VALUES[self.right_card if self.chosen_card == "left" else self.left_card]
if chosen_value > other_value:
# Show Next button
button_y = max(left_rect.bottom, right_rect.bottom) + 20
self.next_button_rect = self.draw_button("Next", WINDOW_WIDTH//2, button_y)
elif self.game_state == "game_over":
# Show Game Over text and Restart button
game_over_text = self.large_font.render("Game Over!", True, WHITE)
game_over_rect = game_over_text.get_rect(centerx=WINDOW_WIDTH//2,
y=max(left_rect.bottom, right_rect.bottom) + 20)
self.screen.blit(game_over_text, game_over_rect)
button_y = game_over_rect.bottom + 20
self.restart_button_rect = self.draw_button("Restart", WINDOW_WIDTH//2, button_y)
def run(self):
"""Main game loop"""
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # Left click
pos = event.pos
if self.game_state == "waiting":
self.handle_card_click(pos)
elif self.game_state == "revealed":
if self.next_button_rect and self.next_button_rect.collidepoint(pos):
self.handle_next_click()
elif self.game_state == "game_over":
if self.restart_button_rect and self.restart_button_rect.collidepoint(pos):
self.handle_restart_click()
self.draw()
pygame.display.flip()
self.clock.tick(60)
pygame.quit()
sys.exit()
if __name__ == "__main__":
game = Game()
game.run()
Amazon Q CLIで生成したコードをhigher_card_game.py
として保存後、Amazon Q CLIを終了
Amazon Q CLI
/quit
動作確認
pythonコマンドでhigher_card_game.pyを実行します。
python
python higher_card_game.py
実行後、別画面でゲームが表示されました。
どちらのカードを選択して数字が大きいほうを選択すると【NEXT】ボタンが表示されます。
数字が小さいほうを選択するとゲームオーバーとなります。
プロンプト通りのゲームができていることを確認しました。
まとめ
Amazon Q CLIでVibe Codingをしたことがなかったので大変勉強になりました。
Discussion