Implementing Tic-Tac-Toe Game Logic in C Using Arrays

Modular Program Structure

Tic-tac-toe implementation folllows modular design principles, separating code into distinct files for better organization:

  • game.h: Contains header inclusions, constant definitions, and function declarations
  • game.c: Implements all game-related functions
  • test.c: Contains main program logic and testing routines
// game.h - Header file structure
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define BOARD_ROWS 3
#define BOARD_COLS 3

void initializeBoard(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols);
void displayGrid(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols);
void playerTurn(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols);
void computerTurn(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols);
char checkGameState(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols);

Game Initialization and Board Setup

// game.c - Board initialization
void initializeBoard(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            grid[i][j] = ' ';
        }
    }
}

Dynamic Board Display

The display function adapts to different board sizes:

void displayGrid(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            printf(" %c ", grid[i][j]);
            if (j < cols - 1) printf("|");
        }
        printf("\n");
        
        if (i < rows - 1) {
            for (int j = 0; j < cols; j++) {
                printf("---");
                if (j < cols - 1) printf("|");
            }
            printf("\n");
        }
    }
}

Player Input Handling

void playerTurn(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    int x, y;
    printf("Player's turn (enter coordinates):\n");
    
    while (1) {
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= rows && y >= 1 && y <= cols) {
            if (grid[x-1][y-1] == ' ') {
                grid[x-1][y-1] = 'X';
                break;
            } else {
                printf("Position occupied. Try different coordinates:\n");
            }
        } else {
            printf("Invalid coordinates. Enter values between 1-%d:\n", rows);
        }
    }
}

Computer AI Implementasion

void computerTurn(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    printf("Computer's turn:\n");
    int x, y;
    
    do {
        x = rand() % rows;
        y = rand() % cols;
    } while (grid[x][y] != ' ');
    
    grid[x][y] = 'O';
}

Game State Evaluation

int isBoardFull(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            if (grid[i][j] == ' ') return 0;
        }
    }
    return 1;
}

char checkGameState(char grid[BOARD_ROWS][BOARD_COLS], int rows, int cols) {
    // Check rows for win
    for (int i = 0; i < rows; i++) {
        if (grid[i][0] == grid[i][1] && grid[i][1] == grid[i][2] && grid[i][0] != ' ') {
            return grid[i][0];
        }
    }
    
    // Check columns for win
    for (int j = 0; j < cols; j++) {
        if (grid[0][j] == grid[1][j] && grid[1][j] == grid[2][j] && grid[0][j] != ' ') {
            return grid[0][j];
        }
    }
    
    // Check diagonals
    if (grid[0][0] == grid[1][1] && grid[1][1] == grid[2][2] && grid[0][0] != ' ') {
        return grid[0][0];
    }
    if (grid[0][2] == grid[1][1] && grid[1][1] == grid[2][0] && grid[0][2] != ' ') {
        return grid[0][2];
    }
    
    // Check for draw
    if (isBoardFull(grid, rows, cols)) {
        return 'D';
    }
    
    // Game continues
    return 'C';
}

Main Game Loop

// test.c - Main program flow
void showMenu() {
    printf("\nTic-Tac-Toe Game\n");
    printf("1. Start Game\n");
    printf("0. Exit\n");
    printf("Select option: ");
}

void runGame() {
    char gameBoard[BOARD_ROWS][BOARD_COLS];
    char result;
    
    initializeBoard(gameBoard, BOARD_ROWS, BOARD_COLS);
    
    while (1) {
        displayGrid(gameBoard, BOARD_ROWS, BOARD_COLS);
        playerTurn(gameBoard, BOARD_ROWS, BOARD_COLS);
        result = checkGameState(gameBoard, BOARD_ROWS, BOARD_COLS);
        if (result != 'C') break;
        
        computerTurn(gameBoard, BOARD_ROWS, BOARD_COLS);
        result = checkGameState(gameBoard, BOARD_ROWS, BOARD_COLS);
        if (result != 'C') break;
    }
    
    displayGrid(gameBoard, BOARD_ROWS, BOARD_COLS);
    
    switch (result) {
        case 'X': printf("Player wins!\n"); break;
        case 'O': printf("Computer wins!\n"); break;
        case 'D': printf("Game ended in draw!\n"); break;
    }
}

int main() {
    srand((unsigned int)time(NULL));
    int choice;
    
    do {
        showMenu();
        scanf("%d", &choice);
        
        switch (choice) {
            case 1: runGame(); break;
            case 0: printf("Exiting game.\n"); break;
            default: printf("Invalid selection.\n");
        }
    } while (choice != 0);
    
    return 0;
}

Potential enhancements include implementing smarter computer AI that can analyze player moves and creating scalable win condition checks for larger board sizes.

Tags: c programming Arrays game development Tic-Tac-Toe Modular Design

Posted on Sun, 21 Jun 2026 16:57:30 +0000 by kenle