so_long is a small 2D game project that introduces basic game development concepts using the MiniLibX graphics library. The player controls a cow that must collect all flowers before reaching the barn. The project focuses on window management, event handling, texture rendering, and basic game logic implementation.
Through this project, I gained experience with graphics programming, event-driven programming, memory management, and map parsing/validation.
- Create a functional 2D game with graphical interface
- Implement event handling (keyboard input, window closing)
- Parse and validate game maps from
.berfiles - Render textures and sprites using MiniLibX
- Implement collision detection and game logic
- Ensure proper memory management with no leaks
You're a cow on a farm trying to collect all the flowers before entering to the barn! Navigate through the map, avoid the mountains (walls), collect every flower, and find your way to the barn's exit.
- Collect all flowers (
C) on the map - Reach the barn exit (
E) after collecting all flowers - Complete the level in as few moves as possible
- W or โ - Move up
- A or โ - Move left
- S or โ - Move down
- D or โ - Move right
- ESC - Exit game
Maps are stored in .ber files with the following specifications:
1- Wall (Mountains) - Impassable terrain0- Empty space (Background) - Walkable terrainC- Collectible (Flower) - Must collect allE- Exit (Barn) - Goal locationP- Player starting position (Cow) - Only one allowed
- Rectangular: Map must be rectangular (all rows same length)
- Surrounded by walls: Map must be completely enclosed by
1 - Valid path: Must have a valid path from player to all collectibles and exit
- One player: Exactly one player starting position (
P) - One exit: Exactly one exit (
E) - At least one collectible: At least one flower (
C) to collect - Valid characters: Only
0,1,C,E,Pallowed
1111111111111
10010000000C1
1000011111001
1P0011E000001
1111111111111
This map has:
- Walls forming the border and obstacles
- One player position (
P) - One exit (
E) - One collectible (
C) - Empty spaces to navigate (
0)
The game uses custom XPM textures located in the Textures/ directory:
- Background.xpm - Grass tile background
- Cow.xpm - Player sprite
- Mountains.xpm - Wall/obstacle sprite
- Flower.xpm - Collectible sprite
- Barn.xpm - Exit sprite
Each tile is 128x128 pixels (TILE_SIZE constant).
- MiniLibX - Graphics library (included in
minilibx-linux/) - X11 libraries - Required for MiniLibX on Linux
- gcc - C compiler
- make - Build automation tool
To compile the program, simply run:
makeThis creates the so_long executable.
make- Compile the programmake clean- Remove object filesmake fclean- Remove object files and the executablemake re- Recompile everything from scratch
./so_long [map_file.ber]# Run with a specific map
./so_long Maps/map1.ber
# Try different maps
./so_long Maps/map2.ber
./so_long Maps/map3.ber- The game window opens automatically
- Move counter displays at the top-left corner
- Each movement increments the counter (displayed in terminal and window)
- Window size adjusts based on map dimensions
The program outputs descriptive error messages for:
- Invalid arguments: Wrong number of command-line arguments
- Invalid file extension: Map file must end with
.ber - Invalid map structure: Map not rectangular or not enclosed by walls
- Invalid characters: Unknown characters in the map
- Missing elements: No player, exit, or collectibles
- Duplicate elements: Multiple players or exits
- No valid path: Impossible to reach all collectibles and exit
- Texture loading failures: Missing or corrupted texture files
The project is organized with a modular approach:
- so_long.c - Main program, initialization, and event loop
- so_long.h - Header file with structure definitions and function prototypes
- so_long_check.c - Map validation (path finding, element counting)
- so_long_check_utils.c - Helper functions for map validation
- so_long_utils.c - Game logic, movement, collision detection
- so_long_utils_utils.c - Additional utility functions
- so_long_utils_x3.c - Extended utility functions
- so_long_libft.c - Custom C library functions
- so_long_libft_utils.c - Additional libft utilities
- get_next_line/ - File reading utility for map parsing
- ft_printf/ - Custom printf implementation for output
typedef struct s_data
{
void *mlx; // MiniLibX connection
void *window; // Game window
// Textures
void *background; // Background tile
void *mountain; // Wall sprite
void *flower; // Collectible sprite
void *barn; // Exit sprite
void *player; // Player sprite
// Dimensions
int number_of_tiles_x; // Map width in tiles
int number_of_tiles_y; // Map height in tiles
// Player state
int player_x; // Player X position
int player_y; // Player Y position
// Game state
char **objects_position; // 2D map array
int number_of_movements; // Move counter
int flowers_exist; // Remaining collectibles
char *file_name; // Map file name
} t_data;- Language: C
- Compiler: gcc
- Flags:
-Wall -Wextra -Werror - Graphics Library: MiniLibX (X11)
- Norm: 42 Norminette
- Data Structure: 2D array for map representation
- Dependencies: MiniLibX, X11, Xext, ft_printf, get_next_line
The fill_v() function implements a recursive flood fill to validate path accessibility:
- Marks visited positions as
'V' - Recursively explores all reachable positions
- Ensures player can reach all collectibles and the exit
- Tracks player position in tile coordinates
- Checks collisions before allowing movement
- Updates collectible count when flowers are picked up
- Only allows exit when all flowers are collected
- Displays move count in real-time
The project includes various test maps in the Maps/ directory:
# Valid maps
./so_long Maps/map1.ber # Basic valid map
./so_long Maps/map2.ber # Different layout
./so_long Maps/map3.ber # More complex
# Test edge cases
./so_long Maps/map10.ber # Large map
./so_long Maps/map11.ber # Narrow corridorsCreate your own .ber map files following these rules:
- Use only
0,1,C,E,Pcharacters - Surround the map with
1(walls) - Include exactly one
P(player) - Include exactly one
E(exit) - Include at least one
C(collectible) - Ensure all rows have the same length
- Make sure there's a valid path to all elements
Example:
11111
1P0C1
1E001
11111
- All functions follow the 42 Norminette coding standards
- Memory is properly managed with no leaks
- The program handles window closing gracefully (X button and ESC key)
- Textures are loaded dynamically and validated
- Move counter is displayed both in the window and terminal
- The game prevents invalid moves (walking through walls)
- Exit only works after collecting all flowers
- Window size is fixed based on map dimensions (no scaling)
- No animations for player movement
- Single texture per entity type
- No sound effects or music
opopov