I know several there have been several posts about Tic Tac Toe games previously, nonetheless I was really hoping that you may take a look at my attempt. I have tried to keep it as modularized as possible to minimize side effects. I started teaching myself C only about a month ago, so any and all advice would be greatly appreciated, especially in terms of general design and use of pointers.
Game
int main()
{
int** board;
int rounds_played, selection, col, row, current_player;
current_player = O_PLAY;
rounds_played = 0;
board = initialize_board();
print_instructions(board);
while (rounds_played != MAX_ROUNDS)
{
/* Clear out current value in selection - prevents infinite loop if alphabetic char is entered */
/* Side-effect requires you to hit enter prior to starting the game */
while((selection = getchar()) != '\n' && selection != EOF);
/* Get player selection */
printf("Player %c, please make a move: ", current_player);
scanf("%d", &selection);
update_col_row(selection, &col, &row);
/* Validate user-input and update board */
if (is_valid_move(selection, col, row, board) == 1) {
update_board(current_player, board, col, row);
print_state(board);
if (is_player_winner(board) > 0) {
printf("Player %c wins the game!\n", current_player);
return 0;
}
update_player(¤t_player);
rounds_played++;
} else {
printf("That move is not valid, please try again...\n");
continue;
}
}
free(board);
printf("Game ended in a draw.\n");
return 0;
}
Initialize Board
int** initialize_board()
{
int** board;
int i, j, tile_number;
tile_number = 1;
board = (int**) malloc(sizeof(int*) * BOARD_SIZE);
for (i = 0; i < BOARD_SIZE; i++)
{
board[i] = malloc(sizeof(int) * BOARD_SIZE);
for (j = 0; j < BOARD_SIZE; j++)
{
board[i][j] = tile_number;
tile_number++;
}
}
return board;
}
Place marker / update board
/* Place marker in selected tile */
void update_board(int marker, int** board, int col, int row)
{
board[row][col] = marker;
}
Update player
/* Toggle between players */
void update_player(int* current_player)
{
*(current_player) = *(current_player) == X_PLAY ? O_PLAY : X_PLAY;
}
Validate Move
/* Validate user-input */
int is_valid_move(int selection, int col, int row, int** board)
{
if (selection < 1 || selection > 9) {
return 0;
} else if (board[row][col] == X_PLAY || board[row][col] == O_PLAY) {
return 0;
}
return 1;
}
Calculate Column / Row
/* Calculate horizontal and vertical axis based on user-input */
void calculate_col_row(int selection, int* col, int* row)
{
selection -= 1;
*(col) = selection % 3;
*(row) = selection / 3;
}
Check Diagonal
/* Check major and minor diagonals for a winner */
int check_diagonal(int** board)
{
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
return 1;
} else if (board[0][2] == board[1][1] && board[2][0] == board[1][1]) {
return 1;
}
return 0;
}
Check Rows
/* Iterate through rows and check for a winner */
int check_rows(int** board)
{
int i;
for (i = 0; i < BOARD_SIZE; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]) {
return 1;
}
}
return 0;
}
Check Columns
/* Iterate through columns and check for winner */
int check_columns(int** board)
{
int i;
for (i = 0; i < BOARD_SIZE; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i]) {
return 1;
}
}
return 0;
}
Check for winner
/* Check board for winner */
int is_player_winner(int** board)
{
if (check_diagonal(board) || check_rows(board) || check_columns(board)) {
return 1;
}
return 0;
}
Print current state
/* Print current state of the board */
void print_state(int **board)
{
int i, j;
printf("-------------\n");
for (i = 0; i < BOARD_SIZE; i++)
{
for (j = 0; j < BOARD_SIZE; j++)
{
/* Hacky way to handle numbers and characters */
if (board[i][j] > 9) printf("| %c ", board[i][j]);
else printf("| %d ", board[i][j]);
}
printf("|\n-------------\n");
}
}
Print instructions
/* Print game-play instructions */
void print_instructions(int **board)
{
printf("\t\t\t\tWelcome to my Tic Tac Toe game\n\n");
printf("\t\t\tWhen prompted to make a move, simply enter the number\n\t\t\t corresponding to a tile of your choosing\n");
printf("\t\t\t\tThe board will initalize as below: \n");
printf("\t\t\t\t Hit ENTER to start playing.\n");
print_state(board);
}