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 declarationsgame.c: Implements all game-related functionstest.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.