Skip to main content

A Python module for grid-based fire spread challenges

Project description

Fire Challenge

A Python module for creating grid-based fire spread challenges where players write code to strategically place walls to block fire propagation.

Overview

The fire challenge presents players with a grid containing:

  • Open cells (0): Can catch fire
  • Water cells (1): Block fire spread
  • Fire cells (2): Starting fire positions
  • Wall cells (3): Placed by player to block fire

Players must analyze the grid and place a limited number of walls to save as many cells as possible from the spreading fire.

Installation

pip install fire-challenge

Or using uv:

uv pip install fire-challenge

Usage

Recommended: Class-Based API

The new FireChallenge class provides a clean, object-oriented interface that makes it easy to test multiple strategies and manage game state.

Listing Available Maps

from fire_challenge import FireChallenge

# Get list of all maps
maps = FireChallenge.get_available_maps()
for num, name in maps:
    print(f"Map {num}: {name}")

Basic Example

from fire_challenge import FireChallenge

# Create a new game instance
game = FireChallenge(map=0)
print(f"Playing: {game.name}")
print(f"Max walls: {game.max_walls}")

# Analyze the grid (0=open, 1=water, 2=fire)
print(game.grid)

# Place walls at strategic positions
game.place_walls([(3, 0), (3, 1), (4, 1)])

# Test how many cells you saved
num_saved = game.test_result()
print(f"Saved {num_saved} cells!")

# Visualize the fire spread animation
game.visualize()

Comparing Multiple Strategies

The class-based API makes it easy to test different approaches:

from fire_challenge import FireChallenge

# Test different wall placements
strategies = [
    [(0, 1), (0, 2), (0, 3)],
    [(1, 0), (2, 0), (3, 0)],
    [(0, 1), (1, 1), (2, 1)],
]

best_score = 0
best_walls = []

for walls in strategies:
    # Each instance is independent!
    game = FireChallenge(map=0)
    game.place_walls(walls)
    score = game.test_result()
    
    print(f"Walls {walls}: saved {score} cells")
    
    if score > best_score:
        best_score = score
        best_walls = walls

print(f"Best solution: {best_walls} with {best_score} cells saved")

# Visualize the best solution
game = FireChallenge(map=0)
game.place_walls(best_walls)
game.visualize()

Using reset() for Multiple Attempts

from fire_challenge import FireChallenge

game = FireChallenge(map=0)

# Try first strategy
game.place_walls([(0, 0), (1, 0)])
score1 = game.test_result()
print(f"Strategy 1: {score1} cells saved")

# Reset and try another
game.reset()
game.place_walls([(4, 4), (5, 5)])
score2 = game.test_result()
print(f"Strategy 2: {score2} cells saved")

Inspecting Game State

from fire_challenge import FireChallenge

game = FireChallenge(map=0)

# Access useful properties
print(f"Map name: {game.name}")
print(f"Grid size: {game.grid.shape}")
print(f"Max walls: {game.max_walls}")
print(f"Walls remaining: {game.walls_remaining}")
print(f"Total open cells: {game.total_open_cells}")

game.place_walls([(1, 1), (2, 2)])
print(f"Walls placed: {game.walls_placed}")
print(f"Walls remaining: {game.walls_remaining}")

Printing Maps

from fire_challenge import FireChallenge

game = FireChallenge(map=0)

# Print as integer grid
print("Grid as integers:")
game.print_map('int')
# Output: [[0 0 0 ...] [0 0 0 ...] ...]

# Print as visual characters with border
print("\nGrid as characters:")
game.print_map('str')
# Output:
# ┌────────┐
# │        │
# │  ###   │
# │* # #   │
# │  ###   │
# │       *│
# └────────┘

# Place walls and see them in the output
game.place_walls([(1, 1), (2, 1)])
game.print_map('str')  # Shows 'W' for walls

# Get map as string for further processing
map_string = game.get_map_string('str')

Highlighting Cells

from fire_challenge import FireChallenge

game = FireChallenge(map=1)

# Find fire positions
fire_positions = [(x, y) for y in range(game.grid.shape[0]) 
                  for x in range(game.grid.shape[1]) if game.grid[y, x] == 2]

# Highlight cells of interest (level 1 = yellow frame)
game.highlight_cells(fire_positions, level=1)

# Mark candidate wall positions (level 2 = orange frame)
candidates = [(5, 5), (5, 6), (6, 5)]
game.highlight_cells(candidates, level=2)

# Place walls and visualize
game.place_walls(candidates)
game.visualize()

Creating Custom Maps

from fire_challenge import FireChallenge

# Create from a string representation
map_str = '''
*   #
    #
#####
   *
'''

game = FireChallenge.from_string(map_str, max_walls=3, name="My Custom Map")
game.place_walls([(1, 0), (2, 2)])
game.visualize()

# Or create from a numpy array
import numpy as np

custom_grid = np.array([
    [2, 0, 0, 1],
    [0, 0, 0, 1],
    [0, 0, 0, 0],
    [1, 1, 1, 2],
])

game = FireChallenge.from_custom_grid(custom_grid, max_walls=2, name="Array Map")
game.place_walls([(1, 0), (2, 2)])
game.visualize()

API Reference

FireChallenge Class

FireChallenge(map=0)

Create a new fire challenge game instance.

  • Parameters: map (int) - Map number (0-13, use FireChallenge.get_available_maps() to see all)
  • Example: game = FireChallenge(map=0)

Static Methods:

  • FireChallenge.get_available_maps() - Get list of all built-in maps as (number, name) tuples

Class Methods:

  • FireChallenge.from_custom_grid(grid, max_walls, name="Custom Map") - Create from numpy array
  • FireChallenge.from_string(map_string, max_walls, name="Custom Map") - Create from string representation

Instance Methods:

  • .place_walls(cells) - Place walls at (x, y) positions
  • .test_result() - Return number of cells saved
  • .visualize() - Display fire spread animation
  • .reset() - Remove all placed walls and highlights
  • .highlight_cells(cells, level) - Highlight cells (level 1=yellow, 2=orange)
  • .highlight_clear() - Clear all highlights
  • .print_map(format='int') - Print map to console ('int' for numbers, 'str' for characters)
  • .get_map_string(format='str') - Return map as string ('int' or 'str' format)

Properties (read-only):

  • .grid - Current grid state (numpy array copy)
  • .name - Map name
  • .map_number - Map number or None for custom maps
  • .max_walls - Maximum walls allowed
  • .walls_remaining - Walls that can still be placed
  • .walls_placed - List of wall positions placed
  • .total_open_cells - Total open cells in original grid

Challenge Maps

  • Map 0 - Two Fires: 8x8 grid with two fire sources, 5 walls allowed
  • Map 1 - Corner Fires: 10x10 grid with corner fires, 10 walls allowed
  • Map 2 - Diagonal Fires: 6x6 grid with diagonal fires, 3 walls allowed
  • Map 3 - Fire Row: 10x10 grid with multiple fires in a row, 8 walls allowed
  • Map 4 - Two Rooms: 10x10 two rooms with one door - block the door with 1 wall
  • Map 5 - Central Town: 10x10 central town with 3 entrances - seal it with 3 walls
  • Map 6 - Hallway Rooms: 7x12 hallway with multiple rooms - 1 wall to save the most
  • Map 7 - Big Funnel: 10x15 funnel shape with fire at both ends, 4 walls allowed
  • Map 8 - Fake Doors: 10x15 maze with multiple openings - find the real choke points, 4 walls allowed
  • Map 9 - Wide Open, Safe Corner: 10x15 wide open area with a safe corner, 7 walls allowed
  • Map 10 - Sams Bane (assisted corner): 10x15 assisted corner challenge, 7 walls allowed
  • Map 11 - Diagonal Corner with Blocked Fires: 15x15 diagonal pattern with blocked fires, 12 walls allowed
  • Map 12 - The Diabolical Five-Fire Maze: 30x30 complex maze with five fire sources, 8 walls allowed
  • Map 13 - Nightmare open map with complex water assists: 30x30 extremely challenging open map, 15 walls allowed

Examples

Beginner Tutorial

python beginner_tutorial.py

Starts with simple custom maps and teaches the basics of the FireChallenge API.

Browse Available Maps

python browse_maps.py

Interactive tool to preview all 14 built-in challenge maps.

Create Your Own Player

See the example player template in the "Leaderboard Competition" section below.

Leaderboard Competition

Compete against other players by creating your own player file!

Requirements to Participate

To have your player included in the leaderboard:

  1. Name your file: *_player.py or *_Player.py (e.g., alice_player.py, Bob_Player.py)

  2. Define the function:

    def solve_fire_challenge(map_num, visualize=True):
        # Your strategy here
        return score  # or return (score, other_data)
    
    • Parameters:
      • map_num (int) - The map number to solve
      • visualize (bool) - Whether to display visualization (default: True)
    • Returns: Either a single number (the score) or a tuple whose first element is the score
  3. Run the leaderboard:

    python leaderboard.py
    

The leaderboard will automatically:

  • Find all player files matching the naming pattern
  • Run each player against all 11 challenge maps
  • Display a results table showing each player's score on each map
  • Declare the overall winner based on total cells saved

Example Player Template

from fire_challenge import FireChallenge

def solve_fire_challenge(map_num, visualize=True):
    """Your strategy description here."""
    
    # Create game instance
    game = FireChallenge(map=map_num)
    
    # Your algorithm here
    # ...
    
    # Place walls
    wall_positions = [(x1, y1), (x2, y2)]  # Your wall positions
    game.place_walls(wall_positions)
    
    # Get score
    score = game.test_result()
    
    # Optional visualization
    if visualize:
        game.visualize()
    
    return score

Fire Spread Rules

  1. Fire starts at cells marked with value 2
  2. Each turn, fire spreads to adjacent open cells (4-directional: up, down, left, right)
  3. Fire cannot spread through water cells (1) or wall cells (3)
  4. The simulation continues until fire cannot spread further

Tips for Players

  1. Identify fire starting positions
  2. Find critical chokepoints where a few walls can block multiple spread paths
  3. Protect large areas of open space
  4. Use test_result() to iterate on your strategy
  5. Use highlight_cells() to visualize your analysis
  6. Water cells are your allies - use them as natural barriers

License

Part of the Hacker Dojo Python Group project materials.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fire_challenge-2.1.0.tar.gz (74.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fire_challenge-2.1.0-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file fire_challenge-2.1.0.tar.gz.

File metadata

  • Download URL: fire_challenge-2.1.0.tar.gz
  • Upload date:
  • Size: 74.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for fire_challenge-2.1.0.tar.gz
Algorithm Hash digest
SHA256 578ba54e542ccdf1b05d64547e1d58c8e469d47e875c28c7231d5ace3ac0221c
MD5 6db497c560483e35dd694b4bec5acd7c
BLAKE2b-256 c26d4d1980f11ce4dd640477cdce22d27f238ff3ab1aae2639ccdeeff714c353

See more details on using hashes here.

File details

Details for the file fire_challenge-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: fire_challenge-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for fire_challenge-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7cbe9c92f29947ad36e22a6b6f3ea52e8b07b5d00c9d7df0fe77ec52ff2f643e
MD5 1883197de2a1212d331ad4dbdcf4f304
BLAKE2b-256 a31da11ddaac4d6f481a257fb019fbda382c164d1790d12d9667388e20a5e8b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page