A terminal-based Connect Four implementation in C, featuring a minimax AI opponent with alpha-beta pruning.
Built as a 42-style project: a strict mandatory / bonus split, a from-scratch libft, and zero external game logic dependencies.
connect4 is a two-player Connect Four game played against a computer opponent, built entirely in C on top of a custom libft.
The project ships in two modes:
- Mandatory — a plain text-mode game loop (
game_loop.c), rendering the board withprintf/ft_printfand reading moves viaget_next_line. - Bonus — an
ncurses-driven variant with colored cell rendering, an animated piece drop, and a message box for win/draw states.
Both modes share the same board representation, win-checking, and AI move logic.
- Configurable board — rows and columns are passed as CLI arguments (minimum 6×7, capped to keep minimax tractable).
- Two rendering modes — a plain-text mandatory loop and a colored
ncursesbonus loop, selected via abonusargument flag. - Minimax AI — the computer opponent searches with alpha-beta pruning, immediate win/loss detection, and a center-column + windowed-pattern scoring heuristic.
- Robust argument parsing — dedicated digit and overflow checks reject malformed or out-of-range grid sizes before any memory is allocated.
- Signal-safe startup —
SIGINT/SIGQUITare ignored once the game takes over the terminal.
The board is a char **map inside t_data, where each cell is '0' (empty), '1' (AI) or '2' (player). All game logic — rendering, input, win-checking, and AI — operates on this single shared grid, so the mandatory and bonus loops can reuse the exact same check_game_state, ai_make_move, and parsing helpers.
t_data(structs.h) bundles board dimensions, the map, terminal cell geometry, and aFlagstruct tracking whose turn it is.- Game loop drives turn order (
AI_MOVE/PLAYER_MOVE), calls into rendering + input, then checks state after every move. - AI runs a fixed-depth minimax search with alpha-beta pruning and column-order search (center-out) to prune faster.
- Win-checking walks all 4 line directions (horizontal, vertical, diagonal, anti-diagonal) from every placed piece.
| File | Responsibility |
|---|---|
main.c |
Entry point, argument dispatch (bonus flag), top-level error handling |
parse.c |
Digit/overflow validation and grid size bounds checking |
init_game.c |
Board allocation and initialization (t_data.map) |
start_game.c |
Picks the first player, drives the ncurses bonus game loop |
signals.c |
Ignores SIGINT/SIGQUIT once the game starts |
check_game_state.c |
Win/draw detection, player drop validation |
ai.c |
Minimax + alpha-beta search, board scoring heuristics, best-move selection |
cleanup.c |
Frees the board (free_split) |
utils.c |
Error printing, busy-wait sleep helper |
verbose.c |
Debug board dump (VERBOSE build flag) |
grid/game_loop.c |
Mandatory (text-mode) turn loop |
grid/print_grid.c |
Text-mode board rendering with column numbers and colored cells |
grid/input_player.c |
Reads and validates a column number from stdin |
make # builds the mandatory version
make bonus # builds the ncurses (colored) version
make run # rebuilds and runs with an 8x7 board
./connect4 <rows> <columns> [bonus]rowsmust be ≥ 6,columnsmust be ≥ 7 (and both must stay under the hard caps inparse.c).- Passing
bonusas a third argument launches thencursesrendering loop instead of the plain text prompt. make verbosebuilds with-DVERBOSE=1and-gfor a debug board dump after initialization.
The AI move selection (ai_make_move) evaluates every playable column with a depth-limited minimax search:
- Immediate win/loss detection short-circuits the search as soon as a branch produces four in a row.
- Alpha-beta pruning cuts off branches that can't improve on the current best.
- Center-out column ordering (
get_column_order) explores the strategically stronger center columns first, improving pruning efficiency. - Heuristic scoring (
score_position) rewards center-column control and scores every 4-cell window across all four directions — favoring near-complete AI lines and penalizing player lines one move from a win.
Search depth is currently fixed; a dynamic-depth heuristic based on board size and fill ratio exists in the source but is not yet wired in.
The project deliberately does not yet include:
- Dynamic search depth (grid-size/fill-ratio aware) — implemented but disabled
- A full
ncursesbonus loop parity with the mandatory text loop (rendering internals are still being reworked) - Replay/undo, move history, or a configurable AI difficulty
- Networked or hot-seat multiplayer (the second "player" is always the AI)
- A C compiler (
cc/gcc, C99 or later) - GNU Make
ncursesdevelopment headers/library (-lncurses) for the bonus build- The bundled
libft(built automatically as part ofmake)