Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

COMPUTER SCIENCE STUDENTS’

SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

MENTORSHIP PROGRAM
Code Writing Exercise for CSci 13 – Fundamentals of Programming
First Semester, AY 2022-2023

Tic-tac-toe is a simple game played on a 3x3 grid with paper and pencil by two
players. Each player takes turns placing either an X or an O on the grid. The goal is to
get three of your marks in a row, either horizontally, vertically, or diagonally. The player
who accomplishes this first wins the game. It is a solved game, meaning that with
optimal play from both players, the result will always be a draw.

'O' '-' 'X'


'-' 'O' 'O'
'X' 'X' 'X'

Figure 1. An example state of the board where player X wins the game in 7 steps.

In the following example, the first player (X) wins the game in seven steps:

'-' '-' 'X' 'O' '-' 'X' 'O' '-' 'X'

'-' '-' '-' '-' '-' '-' '-' '-' '-'

'-' '-' '-' '-' '-' '-' 'X' '-' '-'

'O' '-' 'X' 'O' '-' 'X' 'O' '-' 'X'

'-' 'O' '-' '-' 'O' '-' '-' 'O' 'O'

'X' '-' '-' 'X' '-' 'X' 'X' '-' 'X'

Page 1 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

'O' '-' 'X'

'-' 'O' 'O'

'X' 'X' 'X'

Figure 2. The step-by-step (left-to-right) of the earlier figure resulting to player X's win.

There is no universally agreed rule as to who plays first, but in this program the
convention that X plays first is used.

Objective: In this exercise, you will apply the programming fundamentals in creating
a simple tic-tac-toe program. The procedures in the succeeding pages will serve as
your guide, but you may opt to create your own version of this exercise.

Difficulty: Advanced

Topics Applied:
• Program Control Constructs (If-Else, Pre-test Iterations, Post-test Iterations,
Nested Loops)
• Arrays (One-Dimensional, and Two-Dimensional Arrays)
• Functions

Page 2 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Implementation Guide:

Setting Up the Program


In this section, you will be setting up the program structure by initializing variables
and declaring functions necessary for the program to work.

1. Create a new C file named tictactoe.c.


2. In tictactoe.c, let us include the standard input/output library stdio.h.
This can be done by inserting #include <stdio.h> at the top of the file.
3. Below the include statement, declare a function main() with int datatype.
4. Declare the following variables inside the main() function.
Table 1. Variables for function main().

Property Data type Description


row int Holds the
data/information about
the current row of the
board to be played.
col int Holds the
data/information about
the current column of
the board to be played.
board char[3][3] Holds the
data/information about
the current state of the
game.

Page 3 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Initialize the two-dimensional array board with character values '-'. It should
look like this:
[0] [1] [2]

[0] '-' '-' '-'

[1] '-' '-' '-'

[2] '-' '-' '-'

Figure 3. A two-dimensional array containing a dash '-' character in all its elements.

5. Next, declare these functions as methods to communicate with our created


variables:
Table 2. Functions other than main() for tictactoe.c

Function Name Parameters Return type Description


displayBoard char void Displays the current
board[3][3] state of the board.
displayPlayerTurn int void Displays whose
playerTurn player turn to play.
validateInput char int Determines whether
board[3][3] the user input is valid
int row or not.

int col

updateBoard char void Marks an element of


board[3][3] the board based on
int the row and column
playerTurn values provided by
int row the user and whose
player turn it is.
int col

checkWinner char int Determines whether


board[3][3] the game has a
winner.
displayWinner int void Displays the winner
playerTurn of the game.

Page 4 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

After declaring all properties listed in Table 1, and Table 2, the tictactoe.c
will look like this:
#include <stdio.h>

void displayBoard(char board[3][3]);


void displayPlayerTurn(int playerTurn);
int validateInput(char board[3][3], int row, int col);
void updateBoard(char board[3][3], int playerTurn, int row, int col);
int checkWinner(char board[3][3]);
void displayWinner(int playerTurn);

int main()
{
int row, col;
char board[3][3] = {
{'-', '-', '-'},
{'-', '-', '-'},
{'-', '-', '-'}
};
}

void displayBoard(char board[3][3])


{

void displayPlayerTurn(int playerTurn)


{

int validateInput(char board[3][3], int row, int col)


{

void updateBoard(char board[3][3], int playerTurn, int row, int col)


{

int checkWinner(char board[3][3])


{

void displayWinner(int playerTurn)


{

Page 5 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Switching Between Two Players

In this section, you will be creating a simple loop construct that switch between two
players of the game.

1. Create a for loop construct that satisfies the following arguments:


a. Initializes an integer variable named playerTurn that has a value of 0.
b. Checks whether the playerTurn is less than 9.
c. Increments the playerTurn by 1.
2. In the function displayPlayerTurn(), create a simple if-else construct that
satisfies the following:
a. If the playerTurn’s value is an even integer, print that it is player X’s
turn.
b. Else, print that it is player O’s turn.
3. Temporarily call the getch() function at the end of the displayPlayerTurn()
function, outside the if-else structure. This allows pausing of the function until
the user presses any key.
4. Finally, in the function main(), call the displayPlayerTurn() function
passing the playerTurn’s value as its argument inside the for loop structure.
When compiled and run, the resulting program result should look like this.

$ ./tictactoe
Player X's turn
Player O's turn
Player X's turn
Player O's turn
Player X's turn
Player O's turn

Page 6 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Supporting User Inputs

In this section, you will be adding support to user input and determine whether they
are valid or not.

5. In the function main() after calling the displayPlayerTurn() function inside


the for loop structure, print a simple UI that indicates that the user shall enter
integer values from 0 to 2. After that, allow user input that will be assigned into
the row variable.
6. Repeat step 5 for the col variable.
7. In the function validateInput(), create a simple if construct that checks the
following conditions:
a. If row value is less than 0; or
b. If row value is greater than 2; or
c. If col value is less than 0; or
d. If col value is greater than 2.

When either of the inputs are outside range, the value of the validateInput()
function will return 0 or equivalent to false. Otherwise, it will return 1 or
equivalent to true.

8. After the code block created in step 6, create an if-else construct that satisfies
the following:
a. If the resulting value when calling the validateInput() function is 0,
do the following:
i. Print that the user input is invalid.
ii. Next, prompt the user to press any key to continue by calling the
getch() function.
iii. Decrement the playerTurn variable by 1 to reverse the value
increment that is made for every loop from step 1.

Page 7 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

b. In the else construct, leave it blank for later.


9. Finally, remove the getch() call inserted in step 3.
When compiled and run, the resulting program should look like this.
[Inputs are marked in yellow]
$ ./tictactoe
Player X's turn
Enter row [0-2]: 2
Enter column [0-2]: 0

Player O's turn


Enter row [0-2]: 1
Enter column [0-2]: 2
Player X's turn
Enter row [0-2]: 3
Enter column [0-2]: 2
Invalid input. Try again.

Player X's turn


Enter row [0-2]:

10. In the function main(), call the function system() with the a lone parameter
"cls" at the top of the for loop structure. This clears the terminal window every
time the program loops.
When compiled and run, the resulting program would look like this:
$ ./tictactoe
~[terminal is cleared after running program]~

Player X's turn


Enter row [0-2]: 2
Enter column [0-2]: 0
~[terminal is cleared after entering input]~

Player O's turn


Enter row [0-2]: 1
Enter column [0-2]: 2

~[terminal is cleared after entering input]~

Player X's turn


Enter row [0-2]: 3
Enter column [0-2]: 2
Invalid input. Try again.

Page 8 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Updating the Game Board

In this section, you will be integrating the user input into the game board, by checking
whether the space has been marked or not.

11. In the function displayBoard(), create a nested for loop construct that iterates
through the board variable to display the current state of the game. Be sure to
add a space between every column and create a new line for every row.
12. In the function main(), before the function displayPlayerTurn() in the for
loop construct you called in step 4, call the displayBoard() function bearing
the board variable as a sole parameter to print the current board state in every
loop.
13. In the function updateBoard(), create a simple if-else construct that satisfies
the following conditions:
a. If the playerTurn’s value is an even integer, assign the value of 'X' to
the board’s index based on row and col values.
b. Else, assign the value of 'O' to the same index as 13a.
14. In the blank else construct in step 8b, call the function updateBoard() bearing
the parameters board, playerTurn, row, and col variables, respectively.
When compiled and run, the resulting program should look like this.
$ ./tictactoe
~[terminal is cleared after running program]~

- - -
- - -
- - -
Player X's turn
Enter row [0-2]: 2
Enter column [0-2]: 2
~[terminal is cleared after entering input]~

Page 9 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

- - -
- - -
- - X
Player O's turn
Enter row [0-2]: 0
Enter column [0-2]: 1
~[terminal is cleared after entering input]~

- O -
- - -
- - X
Player X's turn
Enter row [0-2]:

Page 10 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Checking for Winner

In this section, you will be implementing an algorithm that determines whether there’s
already a game winner.

There are 8 ways to check for a winner, categorized into 3 (vertical, horizontal,
diagonal)

Vertically (Column)

[0] [1] [2] [0] [1] [2] [0] [1] [2]

[0] 'X' '-' '-' [0] '-' 'X' '-' [0] '-' '-' 'X'

[1] 'X' '-' '-' [1] '-' 'X' '-' [1] '-' '-' 'X'

[2] 'X' '-' '-' [2] '-' 'X' '-' [2] '-' '-' 'X'

Horizontally (Row)

[0] [1] [2] [0] [1] [2] [0] [1] [2]

[0] 'X' 'X' 'X' [0] '-' '-' '-' [0] '-' '-' '-'

[1] '-' '-' '-' [1] 'X' 'X' 'X' [1] '-' '-' '-'

[2] '-' '-' '-' [2] '-' '-' '-' [2] 'X' 'X' 'X'

Diagonal (Upward) Diagonal (Downward)

[0] [1] [2] [0] [1] [2]


[0] '-' '-' 'X' [0] 'X' '-' '-'
[1] '-' 'X' '-' [1] '-' 'X' '-'
[2] 'X' '-' '-' [2] '-' '-' 'X'

Figure 4. All possible winning positions.

Page 11 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

15. In the function checkWinner(), Create a for loop that iterates 3 times
(rows/columns). It is possible to have a single for loop to iterate each column
and row.
16. Inside the for loop, create an if-else construct that satisfies the following:
a. If the first and second column of the current row are equal; and
b. If the second and third column of the current row are equal; and
c. If the first column of the current row is not equal to character '-'.

When all conditions are satisfied, return the function’s value of 1.

17. Repeat step 16 but for comparing the rows of the current column. The logic is
omitted as your exercise.
18. Outside the for loop, repeat step 16 twice but for both upward and downward
diagonals. The logic is omitted as your exercise.
19. If neither of the above steps are satisfied, the function will return a value of 0.
20. In the function displayWinner(), create an if-else construct that satisfies the
following:
a. If the playerTurn’s value is an even integer, print that player 'X' has
won the game.
b. Else, print that player 'O' has won the game.
21. In function main(), create an if construct that calls the checkWinner() function
as the condition.
22. Inside the if construct you created in step 21, call the displayWinner()
function bearing the playerTurn variable as the sole parameter to display the
winner of the game.
23. Then, call the break statement next to the displayWinner() call..

Page 12 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

[Skipped to winner result; winner is only colored yellow for easy visualization]

Won Horizontally (Row)


O - X
- O X
- - X
X wins!

Won Vertically (Column)


X X X
- O -
- - O
X wins!

Won Diagonally
X O O
- X -
- - X
X wins!

Page 13 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022
COMPUTER SCIENCE STUDENTS’
SOCIETY
Visayas State University
Visca, Baybay City, Leyte, PHILIPPINES
cscube@vsu.edu.ph

Checking for Draw

24. Finally, outside the for loop you created earlier in step 1, simply print that the
game was a draw.
Since it’s the end of the program, there’s no need for a break statement.
When compiled and run, the resulting program should be as follows:
X O X
O O X
X X O
Draw!

Page 14 of 14 fb.me/VSUCSCube
Version 2 | 23 Dec 2022

You might also like