Introduction
This week, I challenged myself to recreate a classic: Bomberman, using Python, Pygame, and the Amazon Q Developer CLI. My goal was to see how much of the heavy lifting AI could do—from generating complex class structures to automating repetitive code and even suggesting gameplay effects. The result is a feature-rich, modern take on Bomberman, with code that’s clean, modular, and easy to expand.
Why Bomberman?
Bomberman is a timeless game with simple rules but endless replayability. I picked it because:
- It’s easy to prototype but leaves room for advanced features (power-ups, AI enemies, special bombs).
- The grid-based logic is perfect for AI-generated code.
- It’s a great way to test how AI handles both game logic and visual effects.
Effective Prompting Techniques
Working with Amazon Q CLI, I learned a few key prompting strategies:
- Be specific: Instead of “write a Player class,” I’d ask, “write a Player class for Bomberman with shield, armor, and speed boost effects, and a draw method using Pygame.”
- Break down features: I prompted for each effect (shield, armor, slow, remote bombs) separately, then merged the code.
- Ask for explanations: When AI generated something clever, I’d ask for a code comment or explanation to ensure I understood it.
How AI Tackled Classic Programming Challenges
- Complex class design: AI generated the full Player, Enemy, Bomb, and Explosion classes, each with their own state, timers, and effects.
- State management: Timers for shield, armor, and slow immunity were handled with simple decrement logic, making status effects easy to manage.
- AI enemy logic: The Enemy class includes bomb avoidance and random movement, with difficulty scaling for bomb types and range.
- Visual effects: The draw methods for each class use Pygame surfaces, alpha blending, and animation for shield, armor, speed, and slow effects.
Development Automation That Saved Me Time
- Boilerplate code: AI scaffolded all the sprite classes, update/draw methods, and even the power-up floating animation.
- Refactoring: When I wanted to add new bomb types or effects, I just described the feature and let AI generate the code.
- Testing ideas: I could quickly prototype new mechanics (like remote bombs or ice immunity) by prompting for just those features.
Interesting AI-Generated Code Examples
Player class with shield, armor, speed boost, and slow immunity:
class Player:
def __init__(self, x, y, image):
self.x = x
self.y = y
self.image = image
self.lives = 3
self.health = 5
self.bomb_types = [BombType.FIRE]
self.current_bomb_type = BombType.FIRE
self.active_bomb = False
# Power-up attributes
self.speed_boost = 0
self.max_bombs = 1
self.bomb_range = 2
self.shield = False
self.shield_time = 0
self.armor = 0
self.armor_time = 0
self.has_remote_bomb = False
self.remote_bombs = []
self.slow_immune = 0
def draw(self, screen):
screen.blit(self.image, (self.x * TILE_SIZE, self.y * TILE_SIZE))
if self.shield:
shield_surf = pygame.Surface((TILE_SIZE, TILE_SIZE), pygame.SRCALPHA)
pygame.draw.circle(shield_surf, (100, 200, 255, 100), (TILE_SIZE//2, TILE_SIZE//2), TILE_SIZE//2)
pygame.draw.circle(shield_surf, (150, 220, 255, 150), (TILE_SIZE//2, TILE_SIZE//2), TILE_SIZE//2, 2)
screen.blit(shield_surf, (self.x * TILE_SIZE, self.y * TILE_SIZE))
if self.armor > 0:
armor_surf = pygame.Surface((TILE_SIZE, TILE_SIZE), pygame.SRCALPHA)
armor_color = (255, 215, 0, 50 + self.armor * 30)
pygame.draw.rect(armor_surf, armor_color, (2, 2, TILE_SIZE-4, TILE_SIZE-4), 2)
for corner in [(4, 4), (TILE_SIZE-4, 4), (4, TILE_SIZE-4), (TILE_SIZE-4, TILE_SIZE-4)]:
pygame.draw.circle(armor_surf, armor_color, corner, 3)
screen.blit(armor_surf, (self.x * TILE_SIZE, self.y * TILE_SIZE))
if self.speed_boost > 0:
for i in range(3):
offset = random.randint(5, 15)
pygame.draw.line(screen, (255, 255, 255, 150),
((self.x * TILE_SIZE) + TILE_SIZE//2, (self.y * TILE_SIZE) + TILE_SIZE//2),
((self.x * TILE_SIZE) - offset + TILE_SIZE//2, (self.y * TILE_SIZE) + TILE_SIZE//2),
2)
elif self.speed_boost < 0:
slow_surf = pygame.Surface((TILE_SIZE, TILE_SIZE), pygame.SRCALPHA)
for i in range(4):
x = random.randint(4, TILE_SIZE-4)
y = random.randint(4, TILE_SIZE-4)
size = random.randint(2, 4)
pygame.draw.circle(slow_surf, (150, 220, 255, 200), (x, y), size)
screen.blit(slow_surf, (self.x * TILE_SIZE, self.y * TILE_SIZE))
if self.slow_immune > 0:
immune_surf = pygame.Surface((TILE_SIZE, TILE_SIZE), pygame.SRCALPHA)
pygame.draw.circle(immune_surf, (0, 150, 255, 100), (TILE_SIZE//2, TILE_SIZE//2), TILE_SIZE//2, 1)
screen.blit(immune_surf, (self.x * TILE_SIZE, self.y * TILE_SIZE))
Enemy AI that avoids bombs and adapts to difficulty:
class Enemy:
def move_random(self, game):
if self.frozen > 0:
self.frozen -= 1
return
directions = [(1, 0), (-1, 0), (0, 1), (0, -1)]
random.shuffle(directions)
for dx, dy in directions:
new_x, new_y = self.x + dx, self.y + dy
if (0 <= new_x < game.grid_size and
0 <= new_y < game.grid_size and
game.grid[new_y][new_x] == EMPTY and
not any(bomb.x == new_x and bomb.y == new_y for bomb in game.bombs)):
if self.is_dangerous_tile(new_x, new_y, game):
continue
self.x, self.y = new_x, new_y
break
Bomb with pulsing animation and remote detonation:
class Bomb:
def update(self):
self.timer -= 1
self.pulse_scale += 0.01 * self.pulse_direction
if self.pulse_scale > 1.2:
self.pulse_direction = -1
elif self.pulse_scale < 0.8:
self.pulse_direction = 1
if self.timer <= 0:
self.exploded = True
self.owner.active_bomb = False
if isinstance(self.owner, Enemy):
self.owner.bomb_cooldown = 120
Screenshots & Short Demo
.
Conclusion
Amazon Q Developer CLI helped me automate repetitive coding, generate complex class logic, and focus on creative gameplay. If you want to build games faster and smarter, try combining Pygame with Amazon Q CLI—you’ll be amazed at how much AI can accelerate your workflow!
Check out the full code on GitHub
Share your own projects with #AmazonQCLI!
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.