A small 2D tile-based game written in C with MiniLibX (X11). Navigate a maze, collect all collectibles, avoid enemies, and reach the exit. After collecting the last collectible, you must take an optimal path to the exit, deviating from the shortest path results in a loss.
- Rendering with MiniLibX (Linux/X11) using 50×50 px tiles
- Smooth viewport following the player on large maps
- Animated sprites for player, enemies, and exit
- Enemies patrol randomly and chase the player with A* pathfinding
- Map parsing and validation with detailed error messages
- Move counter overlay and pause mode
- Linux with X11 available (Xorg)
- X11 runtime libraries (dev packages only required if you rebuild MLX)
- A standard C toolchain (
cc,make)
This repository vendors MiniLibX and a custom libft, so you do not need network access to build.
makeArtifacts:
- Executable:
./so_long - Clean object files:
make clean - Clean objects + binary:
make fclean - Rebuild from scratch:
make re
./so_long maps/map5.berYou can try any of the sample maps under maps/ (e.g., map1.ber, map5.ber, pacman.ber).
- Arrow keys: move
- Space: pause/resume
- ESC: quit
Notes:
- The exit activates (is rendered) only after all collectibles are gathered.
- Enemies patrol between random points and will chase when close.
- Getting caught (adjacent to an enemy) leads to a loss after a short hit animation.
- Collect all collectibles (
C). - After you pick up the last collectible, the game computes the shortest path length to the exit using A*.
- From that moment, every move you make is counted toward your “route to exit”.
- Reach the exit (
E) with exactly the same number of moves as the optimal path to win. Any deviation results in a loss.
- Text-based grid using these characters:
1: wall (blocked)0: free spaceC: collectibleP: player start (exactly one)E: exit (exactly one)N: enemy (zero or more)
- Rules validated at startup:
- Map is rectangular
- Map is closed (outer borders are all
1) - Exactly one
Pand oneE, at least oneC - All collectibles and the exit are reachable from the player
Example (maps/map1.ber):
111111
10P0C1
100001
100001
100001
100001
100001
100001
100001
100001
10E0N1
111111srcs/: game source filesparsing/:.bermap loading and validation (shape, walls, elements, reachability)init_game/: initialization of MLX, window, sprites, and game staterender/: drawing routinesdraw/: static tiles, animated sprites, HUD (moves)viewport/: camera centering on the player and boundsload_img/: loading XPM textures (player, enemy, exit, walls, floor, coins)
handle_game/: main loop, input hooks, movement, patrol, chase, end conditionsa_star_search/: A* with a binary-heap priority queue for pathfindingutils/: error handling and cleanup
include/: headers (so_long.h,assets_paths.h)assets/: XPM textures (player, enemy, exit, walls, ground, collectibles)maps/: sample and invalid mapsmlx/: MiniLibX (Linux) sources and prebuilt static librarieslibft/: custom utility library used by the project
- Window size: 1600×1200, tile size: 50×50 (tweakable in
include/so_long.h) - Viewport follows the player while clamping to map bounds
- Animated sprites advance based on clock ticks (no frame cap dependency)
- Enemy behavior:
- Patrol between randomly generated valid points within a range
- Switch to chase mode when within a Manhattan distance threshold
- Movement is rate-limited by a configurable delay
- A* pathfinding:
- Manhattan distance heuristic on a 4-neighbor grid
- Custom min-heap priority queue
- Invalid usage (wrong number of args) prints an error to
stderrand exits with failure - Map validation failures print a precise “Error\n...” message before exiting
- Runtime failures (e.g., MLX/image allocation) print an error and exit cleanly
- Change assets or paths in
include/assets_paths.h - Adjust window and tile sizes, keycodes, and AI constants in
include/so_long.h - Add your own maps under
maps/, then run./so_long maps/your_map.ber
- Graphics framework: MiniLibX (included under
mlx/) - Utility library:
libft(included)