Instructions
Objective
Great job on taking on the challenge to create a game of Tic Tac Toe in C language! It's a fantastic opportunity to showcase your programming skills and problem-solving abilities. I'm confident that you can complete a C assignment like this with your dedication and passion for coding. Remember, Tic Tac Toe is a classic game with simple rules, but implementing it in C requires attention to detail and logical thinking. Break down the task into smaller steps, and don't hesitate to refer to C language resources for guidance.
Requirements and Specifications
Skeleton code
#include
#include //time()
#include //srand() and rand()
typedef struct
{
int occupied; // 0 means unoccupied, 1 means occupied
char symbol; //’X’ or ’O’ or ’ ’
} Cell;
typedef struct
{
Cell cells[3][3]; // 9 spaces in our board
int winner; // 1 if the currentPlayer has won, 0 otherwise
int counter; // for how many turns have been played in total
int size; // should match the dimensions of the ‘cells‘ array
int currentPlayer; // 0 for ’O’s and 1 for ’X’s
} Board;
// In function prototypes, just the type of each argument is sufficient.
Cell initializeCell(char, int);
void getPosition(Board, int[2]);
Board updateBoard(int, int, Board);
int isWinningMove(int, int, Board);
void printBoard(Board);
int main(void)
{
srand(time(NULL));
Board mainBoard;
// TODO: Initialize the members (except for ‘cells‘) of the mainBoard
// to appropriate values. You must choose a random player to start.
// TODO: Initialize each cell in the mainBoard to an unoccupied cell
// with a single space for the symbol. Note that you’ll need a nested
// for loop to do this, since the ‘cells‘ array inside mainBoard is 2D.
// Use your initializeCell() function in the body of the nested for
// loop to do this.
while ((mainBoard.winner == 0) && (mainBoard.counter < 9))
{
// TODO:
// 1) Alternate the mainBoard.currentPlayer
// 2) Create an array that holds 2 ints called ‘position‘
// 3) call the getPosition() function, passing in the ‘mainBoard‘
// and the ‘position‘ array. getPosition() "returns" two
// values by using this array to hold the output values.
// 4) call updateBoard(), passing in the row and column which
// were stored in the ‘position‘ array by getPosition() and
// the ‘mainBoard‘. Assign its return value to mainBoard, effectively
// updating main()’s local mainBoard variable.
// 5) set ‘mainBoard.winner‘ to the return value of isWinningMove().
// Pass in the row and column of the cell that was just played
// and the ‘mainBoard‘.
// 6) call printBoard()
}
if (mainBoard.winner==0)
printf("Tie Game\n");
else
printf("Player %d won\n", mainBoard.currentPlayer);
return 0; }
void printBoard(Board board)
{
// Don’t touch this function. It already prints things nicely for you.
// Note that here, I’m using the first index of the cells array
// as the row, and the second as the column.
for (int row = 0; row < board.size; row++)
{
printf("| ");
for (int column = 0; column < board.size; column++)
{
printf("%c | ", board.cells[row][column].symbol);
}
printf("\n");
}
printf("\n");
}
Cell initializeCell(char sym, int isOccupied)
{
// TODO:
// 1) Create a local variable of type Cell and initialize its
// members according to the arguments passed into this function.
// 2) Return the local variable.
//
// This function is here mainly to show you that you can return structs
// from a function.
}
void getPosition(Board board, int pos[2])
{
int r, c; // Remember, these are local variables to the function
do
{
printf("Enter the row and column: ");
scanf("%d%d", &r, &c);
} while (/*insert condition here*/);
// TODO: Fill in the condition of the while loop above. It should continue
// to ask the user for a row and column as long as the row and column
// the user has asked for is out of bounds OR if the cell is already
// occupied in the board.
// TODO: Assign the desired row ‘r‘ to pos[0] and the desired column ‘c‘
// to pos[1]. Here we’re using the ‘pos‘ array to "return" two values
// back to main(), more specifically the row and column of the cell the user
// wants to play their symbol in.
}
Board updateBoard(int r, int c, Board board)
{
// TODO:
// 1) Set the cell associated with the row ‘r‘ and column ‘c‘ to
// occupied.
// 2) Incremenet the board counter, since a move has just been made.
// 3) Set the symbol of the cell associated with ‘r‘ and ‘c‘ to
// the symbol of the currentPlayer (let player 0 be ’O’s and
// player ‘ be ’X’s.
// 4) Return the board.
int isWinningMove(int r, int c, Board board)
{
int possibleWin = 0;
// TODO: Create a char variable called ‘playerSymbol‘ and set
// it to either ’X’ or ’O’ depending on the current player.
// The code below checks to see if there is a 3-in-a-row in the
// row that was just played in (‘r‘ is the row that was just played in).
// Do not change this. It is provided to help you with the other
// checks below. For full credit, you must use a for loop (like below)
// for each check.
for (int column = 0; column < board.size; column++)
{
if (board.cells[r][column].symbol == playerSymbol)
possibleWin = 1;
else
{
possibleWin = 0;
break; }
}
if (possibleWin == 1)
{
// possibleWin can only be a 1 if all 3 symbols in the row matched
// so we have a winner!
return possibleWin;
}
// TODO: Using the above example on how to check for a 3-in-a-row in
// the row that was just played in, check for a 3-in-a-row in the
// column that was just played in. Again, you should do this using
// a single for loop, and after it, returning ‘possibleWin‘ if
// ‘possibleWin‘ is a 1.
// Now we have to check for diagonal 3-in-a-rows, but only if the
// most recent move was in a diagonal. Let’s check the main diagonal
// first (top left to bottom right). We can tell if the most recent move
// is part of the main diagonal if the row and column of the most recent
// move are identical.
if (c == r)
{
// TODO: Check for a 3-in-a-row in the main diagonal of the board.
// Use the example for checking for a 3-in-a-row in the row that
// was just played in.
}
// Now we check for the off-diagonal (bottom left to top right).
if (c == board.size - 1 - r)
{
// TODO: Check for a 3-in-a-row in the off diagonal of the board.
}
// If we haven’t returned a 1 at this point after all the checks, then the
// current player did not just win, so we return a 0 (indicating no one has
// won yet).
return 0;
}
}
Screenshots of output
Source Code
#include
#include //time()
#include //srand() and rand()
typedef struct
{
int occupied; // 0 means unoccupied, 1 means occupied
char symbol; //’X’ or ’O’ or ’ ’
} Cell;
typedef struct
{
Cell cells[3][3]; // 9 spaces in our board
int winner; // 1 if the currentPlayer has won, 0 otherwise
int counter; // for how many turns have been played in total
int size; // should match the dimensions of the ‘cells‘ array
int currentPlayer; // 0 for ’O’s and 1 for ’X’s
} Board;
// In function prototypes, just the type of each argument is sufficient.
Cell initializeCell(char, int);
void getPosition(Board, int[2]);
Board updateBoard(int, int, Board);
int isWinningMove(int, int, Board);
void printBoard(Board);
int main(void)
{
srand(time(NULL));
Board mainBoard;
// TODO: Initialize the members (except for ‘cells‘) of the mainBoard
// to appropriate values. You must choose a random player to start.
mainBoard.winner = 0;
mainBoard.counter = 0;
mainBoard.size = 3;
mainBoard.currentPlayer = rand() % 2;
// TODO: Initialize each cell in the mainBoard to an unoccupied cell
// with a single space for the symbol. Note that you’ll need a nested
// for loop to do this, since the ‘cells‘ array inside mainBoard is 2D.
// Use your initializeCell() function in the body of the nested for
// loop to do this.
for (int row = 0; row < mainBoard.size; row++)
for (int col = 0; col < mainBoard.size; col++)
mainBoard.cells[row][col] = initializeCell(' ', 0);
while ((mainBoard.winner == 0) && (mainBoard.counter < 9))
{
// TODO:
// 1) Alternate the mainBoard.currentPlayer
if (mainBoard.currentPlayer == 0)
mainBoard.currentPlayer = 1;
else
mainBoard.currentPlayer = 0;
// 2) Create an array that holds 2 ints called ‘position‘
int position[2];
// 3) call the getPosition() function, passing in the ‘mainBoard‘
// and the ‘position‘ array. getPosition() "returns" two
// values by using this array to hold the output values.
getPosition(mainBoard, position);
// 4) call updateBoard(), passing in the row and column which
// were stored in the ‘position‘ array by getPosition() and
// the ‘mainBoard‘. Assign its return value to mainBoard, effectively
// updating main()’s local mainBoard variable.
mainBoard = updateBoard(position[0], position[1], mainBoard);
// 5) set ‘mainBoard.winner‘ to the return value of isWinningMove().
// Pass in the row and column of the cell that was just played
// and the ‘mainBoard‘.
mainBoard.winner = isWinningMove(position[0], position[1], mainBoard);
// 6) call printBoard()
printBoard(mainBoard);
}
if (mainBoard.winner==0)
printf("Tie Game\n");
else
printf("Player %d won\n", mainBoard.currentPlayer);
return 0;
}
void printBoard(Board board)
{
// Don’t touch this function. It already prints things nicely for you.
// Note that here, I’m using the first index of the cells array
// as the row, and the second as the column.
for (int row = 0; row < board.size; row++)
{
printf("| ");
for (int column = 0; column < board.size; column++)
{
printf("%c | ", board.cells[row][column].symbol);
}
printf("\n");
}
printf("\n");
}
Cell initializeCell(char sym, int isOccupied)
{
// TODO:
// 1) Create a local variable of type Cell and initialize its
// members according to the arguments passed into this function.
// 2) Return the local variable.
//
// This function is here mainly to show you that you can return structs
// from a function.
Cell cell;
cell.occupied = isOccupied;
cell.symbol = sym;
return cell;
}
void getPosition(Board board, int pos[2])
{
int r, c; // Remember, these are local variables to the function
do
{
printf("Enter the row and column: ");
scanf("%d%d", &r, &c);
} while (r < 0 || r >= board.size || c < 0 || c >= board.size || board.cells[r][c].occupied);
// TODO: Fill in the condition of the while loop above. It should continue
// to ask the user for a row and column as long as the row and column
// the user has asked for is out of bounds OR if the cell is already
// occupied in the board.
// TODO: Assign the desired row ‘r‘ to pos[0] and the desired column ‘c‘
// to pos[1]. Here we’re using the ‘pos‘ array to "return" two values
// back to main(), more specifically the row and column of the cell the user
// wants to play their symbol in.
pos[0] = r;
pos[1] = c;
}
Board updateBoard(int r, int c, Board board)
{
// TODO:
// 1) Set the cell associated with the row ‘r‘ and column ‘c‘ to
// occupied.
board.cells[r][c].occupied = 1;
// 2) Increment the board counter, since a move has just been made.
board.counter++;
// 3) Set the symbol of the cell associated with ‘r‘ and ‘c‘ to
// the symbol of the currentPlayer (let player 0 be ’O’s and
// player ‘ be ’X’s.
if (board.currentPlayer == 0)
board.cells[r][c].symbol = 'O';
else
board.cells[r][c].symbol = 'X';
// 4) Return the board.
return board;
}
int isWinningMove(int r, int c, Board board)
{
int possibleWin = 0;
// TODO: Create a char variable called ‘playerSymbol‘ and set
// it to either ’X’ or ’O’ depending on the current player.
char playerSymbol;
if (board.currentPlayer == 0)
playerSymbol = 'O';
else
playerSymbol = 'X';
// The code below checks to see if there is a 3-in-a-row in the
// row that was just played in (‘r‘ is the row that was just played in).
// Do not change this. It is provided to help you with the other
// checks below. For full credit, you must use a for loop (like below)
// for each check.
for (int column = 0; column < board.size; column++)
{
if (board.cells[r][column].symbol == playerSymbol)
possibleWin = 1;
else
{
possibleWin = 0;
break;
}
}
if (possibleWin == 1)
{
// possibleWin can only be a 1 if all 3 symbols in the row matched
// so we have a winner!
return possibleWin;
}
// TODO: Using the above example on how to check for a 3-in-a-row in
// the row that was just played in, check for a 3-in-a-row in the
// column that was just played in. Again, you should do this using
// a single for loop, and after it, returning ‘possibleWin‘ if
// ‘possibleWin‘ is a 1.
for (int row = 0; row < board.size; row++)
{
if (board.cells[row][c].symbol == playerSymbol)
possibleWin = 1;
else
{
possibleWin = 0;
break;
}
}
if (possibleWin == 1)
{
return possibleWin;
}
// Now we have to check for diagonal 3-in-a-rows, but only if the
// most recent move was in a diagonal. Let’s check the main diagonal
// first (top left to bottom right). We can tell if the most recent move
// is part of the main diagonal if the row and column of the most recent
// move are identical.
if (c == r)
{
// TODO: Check for a 3-in-a-row in the main diagonal of the board.
// Use the example for checking for a 3-in-a-row in the row that
// was just played in.
for (int row = 0; row < board.size; row++)
{
if (board.cells[row][row].symbol == playerSymbol)
possibleWin = 1;
else
{
possibleWin = 0;
break;
}
}
if (possibleWin == 1)
{
return possibleWin;
}
}
// Now we check for the off-diagonal (bottom left to top right).
if (c == board.size - 1 - r)
{
// TODO: Check for a 3-in-a-row in the off diagonal of the board.
for (int row = 0; row < board.size; row++)
{
if (board.cells[row][board.size - 1 - row].symbol == playerSymbol)
possibleWin = 1;
else
{
possibleWin = 0;
break;
}
}
if (possibleWin == 1)
{
return possibleWin;
}
}
// If we haven’t returned a 1 at this point after all the checks, then the
// current player did not just win, so we return a 0 (indicating no one has
// won yet).
return 0;
}
Related Samples
On ProgrammingHomeworkHelp.com, we offer a specialized section for C programming assignments, providing valuable related samples to support students. Our collection includes expertly crafted examples that cover a range of C programming topics, from basic syntax to advanced data structures. These samples are designed to help students understand complex concepts and improve their coding skills. Whether you’re tackling pointers, arrays, or algorithms, our C assignment samples are a great resource to guide you through your coursework and enhance your programming proficiency. Explore our samples today and excel in your studies!
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C
C