MiniLibX-powered 2D exploration gane with animated sprite work, full map validation, with a built-in Tester.
- About
- Subject Compliance
- Custom Tester
- Repository Layout
- Build & Integration
- Usage Guidelines
- Feature Deep Dive
- Input & Animation
- Rendering & HUD
- Internal Architecture
- Tester Workflow
- Results & Reporting
Highlights: Mandatory compliance, bonus animations, and repeatable validation in a single codebase.
- Mandatory source lives in
src/, matching the subject's structure; bonus content lives insrcb/and keeps API parity for easy swapping. - Map safety hinges on rectangular checks, perimeter walls, required components, and a flood-fill reachability pass before the game even opens.
- Assets are all local (
assets/), so the build stays portable across 42 evaluation hosts and personal setups. - The Makefile wraps compilation, guided map selection, and automated tests so setup-to-play is a two-command workflow.
# Compile the animated build and launch a sample map
make bonus && ./so_long assets/maps/valid/demo.ber- The game parses
.berlayouts, validates them, spins up MiniLibX, and reacts to keyboard inputs through the routines insrc/game/game_init.candsrc/game/game_input.c. - Directional animation, mining loops, and enemy patrol failures come from the bonus pipeline (
srcb/game/game_animations_bonus.c,srcb/game/game_input_bonus.c). - Collectibles, exits, and enemies are all configured from tile metadata, so map changes flow straight into gameplay without code edits.
- Libft (including
ft_printf,get_next_line, and utility helpers) ships inside the repository, removing external dependencies for evaluators or teammates.
Every rule in the subject is explicitly validated before the game starts, ensuring predictable and safe gameplay.
Map validation
- Must be rectangular (
src/map/map_validation.c). - Must be fully enclosed by walls (
src/map/map_validation.c). - Accepts only the allowed characters:
0→ empty space1→ wallC→ collectibleE→ exitP→ player (implemented insrcb/map/map_validation_utils_bonus.c:48)
Required components
- Exactly one player and one exit.
- At least one collectible.
- Verified with
check_components_errors()(srcb/map/map_validation_utils_bonus.c:21).
Pathfinding
is_map_solvable()duplicates the map and performs a flood-fill check.- Confirms that all collectibles and exits are reachable before gameplay begins (
srcb/map/map_pathfinding_bonus.c:49).
Gameplay rules
- Movement with WASD.
- Player cannot pass through walls.
- Move count is displayed after each step (terminal in mandatory, HUD overlay in bonus).
- Win the game by exiting the door after mining all the collectibles.
- Quit the game by using
ESCor window close (srcb/game/game_input_utils_bonus.c:36).
Error handling
- Any misconfiguration (duplicate exits, invalid chars, broken walls, unreachable areas)
→ exits cleanly with
Error\nfollowed by an explicit descriptive message.
Bonus extensions
- Sprite animation, HUD-based move counter, and enemy patrols build on top of the mandatory rules,
keeping validation intact and consistent.
Directory Cheat Sheet
inc/ - Shared headers (`so_long.h`, `so_long_bonus.h`) describing structs, keycodes, and prototypes.
src/ - Mandatory gameplay: static sprites, HUD-free movement, and core validation.
srcb/ - Bonus gameplay: animated sprites, mining cycles, HUD overlay, and enemy collisions.
assets/ - Tiles, player sprites, mining sequences, and curated maps (valid + invalid suites).
docs/ - Subject PDF and capture assets (WEBM sources + README GIFs).
mlx/ - MiniLibx Library already compiled to ease use
libft/ - Custom 42 Library with helper functions (printf, gnl, libft/ft_*)
Tip:
rg --files srcb/gameis a quick way to trace each bonus-specific helper from animation to input handling.
Self-contained tooling: clone, build, test- no extra environment work.
make # mandatory build (clones libft if absent)
make bonus # animated build with mining + enemy logic
make start # interactive map chooser with optional launch
make tester # runs invalid-map sweep + texture permissions suite
make fclean # removes binaries, objects, and the libft clonemakepulls in libft (if missing), builds MiniLibX, and links the mandatory binary.make bonuscompiles the bonus objects and still outputsso_long, so launching maps never changes between builds.make startoffers an ncurses-like prompt that copies a map to the working directory, optionally runs it, and cleans up the copy afterwards (Makefile:64).make testerorchestrates both test targets sequentially, with exit codes bubbling up so CI can flag failures instantly.
Playbook: load a map, explore, and exit without leaving artifacts behind.
- Launch the mandatory build with
./so_long <map.ber>or compile the bonus branch first for animated sprites. - Movement is WASD-driven; ESC and the window close button call
close_game()for a graceful teardown (srcb/game/game_input_utils_bonus.c:36). - Expect rectangular, fully walled maps with one player, one exit, collectibles, and optional enemies; anything else is rejected with a formatted error.
- Collectibles trigger a mining animation and decrement counters before updating the HUD (
srcb/game/game_input_utils_bonus.c:53). - Enemy contact prints a game-over message and closes the window immediately, keeping the loss state tight (
srcb/game/game_input_bonus.c:31).
Gameplay Systems
| Element | What Happens | Key Implementation |
|---|---|---|
| Map parsing | Streams .ber files into memory with get_next_line, keeping allocation defensive. |
srcb/map/map_parser_bonus.c:52 (read_map) |
| Component accounting | Counts players, exits, and collectibles before the flood-fill step. | srcb/map/map_validation_utils_bonus.c:21 (check_components_errors) |
| Pathfinding | Duplicates the map and flood-fills reachable space, ensuring loot and exits are accessible. | srcb/map/map_pathfinding_bonus.c:49 (is_map_solvable) |
| Static rendering | Repaints every tile each frame and layers sprites on top of the floor. | srcb/game/game_render_bonus.c:17 (draw_tile) |
| Movement animation | Interpolates frames between tiles with direction-aware sprites. | srcb/game/game_animations_bonus.c:37 (play_move_anim) |
| Mining animation | Plays frame sequences in place before the collectible disappears. | srcb/game/game_animations_bonus.c:69 (play_mining_anim) |
| HUD overlay | Writes the live move counter directly to the window. | srcb/game/game_render_bonus.c:35 (draw_move_counter) |
Controls & Motion
- Input funnels through
handle_input()with a compact key map, branching intoset_direction()andmove_player()(srcb/game/game_input_utils_bonus.c:23). - Direction indices (0 up, 1 down, 2 left, 3 right) drive both animation arrays and enemy collision handling, so sprites and logic stay in sync (
inc/so_long_bonus.h:67). play_move_anim()interpolates sprite placement in pixel space, redrawing origin and destination tiles each step to avoid ghosting.- Mining uses a slightly longer delay per frame (
delay = 130) to make the sequence readable without freezing the main loop (srcb/game/game_assets_bonus.c:44).
Presentation Layer
- Tiles always render the floor first, then layer the appropriate sprite so movement feels grounded (
srcb/game/game_render_bonus.c:17). - The move counter is drawn via
mlx_string_put()in the upper-left corner, updating after each successful move (srcb/game/game_render_bonus.c:35). - Window size scales from the map dimensions and the fixed
TILE_SIZEconstant (64 px), keeping the viewport pixel-perfect for any valid map.
Data Flow
Ownership and teardown paths are explicit to avoid leaking MiniLibX resources.
t_gamecarries the live map, player state, counters, and at_graphicsinstance that wraps MLX pointers and texture banks (inc/so_long_bonus.h:36).- Animation metadata (
t_animandt_anim_ctx) isolates timing, frame pointers, and interpolation math so movement logic stays declarative (inc/so_long_bonus.h:12). - Texture loading relies on
load_anim()+load_image(), producing detailed error messages when a sprite fails to load (srcb/game/game_assets_bonus.c:8). - Cleanup frees static textures, animation arrays, and the duplicated map before destroying the MLX window and display (
srcb/game/game_init_bonus.c:23).
Automation flow: compile once, sweep invalid maps, lock down textures, and surface leaks immediately.
test_invaliditerates through every.berstored underassets/maps/invalid, capturing the first two output lines to ensure the standard "Error" header and explanation are intact (Makefile:190).- Valgrind runs in the background for each invalid map, forcing an error exit code on leaks so memory hygiene is verified alongside messaging.
test_textureschmods each.xpmto000, runs the game with a known-good map, confirms the error mentions the missing file, and restores original permissions (Makefile:240).make testerreturns non-zero if any suite fails, so the target doubles as a CI check or a quick local regression test.
Signal over noise: The tester and logs are designed to show only the important results (errors, verdicts, tallies) and hide unnecessary clutter for efficient debugging.
- Console logs show per-case verdicts and aggregate tallies, making it obvious where to focus next.
- Valgrind trace dumps appear only when something goes wrong, keeping successful runs concise.
- During manual sessions, the on-screen move counter mirrors the terminal
printfoutput so navigation errors are easy to trace.