CSCI1120
Introduction to Computing Using C++
Tutorial 7: Assignment 4
P.1
Introduction
P.2
Assignment 4: Othello
Othello, or Reversi ( 黑白棋 )
Disc
Board
Initial
Setup P.3
Mechanism
Turn over / Flip / Reverse
⚫’s turn ⚪’s turn
P.4
Mechanism
Turn over / Flip / Reverse
⚫’s turn ⚪’s turn
P.5
Mechanism
Turn over / Flip / Reverse
P.6
Valid
Invalid
Rule
If you can’t flip any opponent’s disc, you can’t place this position
→ A valid move means a move that can flip at least one of opponent’s discs
⚫‘s turn
If you can’t make any move, you need to pass one time
→ If no one can make any move (which mean two consecutive passes), the game ends
Winner will be the one with more discs on the board (e.g. ⚫: 20, ⚪:18 → ⚫ wins)
If both players have the same number of discs, the game draws
You can try it on https://cardgames.io/reversi/
P.7
Additional Feature
Pit
Pit is like the wall, you can’t place anything to the pit cells
P.8
Othello in C++
P.9
Representation
P.10
Representation
empty
pit
White Black
P.11
User flow
Enter number of pits: 3
Enter position for pit 1: A1
Enter position for pit 2: A2
Enter position for pit 3: B1
Round 1:
AB C D E F
1##....
2#.....
3..XO..
4..OX..
5......
6......
Player X's turn: E3
P.12
User flow
Enter number of pits: 3 First, user need to enter the number of pit(s)
Enter position for pit 1: A1 (It can be 0)
Enter position for pit 2: A2
e.g. If there are 3 pits, then user enter the
Enter position for pit 3: B1
Round 1: coordinates of the 3 pits
AB C D E F
1##....
2#..... Coordinates are composed of
3..XO..
one char + one integer
4..OX..
5...... (e.g. A1, B2… not 1A, 5C… )
6...... char → horizontal position
Player X's turn: E3 integer → vertical position
P.13
User flow
Round 1:
AB C D E F
1##....
2#.....
3..XO..
4..OX.. First player must be X
5......
6...... Two players take turns and play the game,
Player X's turn: E3
Round 2:
until there are no move for both two players
AB C D E F
1##....
2#.....
3..XXX.
4..OX..
5......
6......
Player O's turn: C2
P.14
User flow
Enter Number of Pit(s)
Enter Pit’s Position
Player X’s turn
Player O’s turn
Game over
P.15
cin: Number of Pits
Developer Perspective
Check the user input
cin: Pit’s Positions Check any valid move
Check the user input Check the game state
So many things to do!!
Initialize the Game Print the board
Don’t panic
Player X/O’s turn
Let’s go through some important steps together
Check the user input
Flip the board
Game over
P.16
Important Concept
2-D Array ASCII Character
For Loop (Nested)
Break / Continue Function
If you are not familiar to these topics, please read the lecture notes again
P.17
Array[0]
Board Size Array[1]
Array[2]
The board is simply a 2-D array
When grading your assignment, we will change the board size
Assuming:
1. Board is always a square, so the board is always (N * N)
2. The range of N will be 4 ≤ N ≤ 26 (which is A to Z for the column)
2. N will always be even number, so the board may be (4 * 4), (8 * 8), (24 *
24), but not (11 * 11)
But how to manage the board size easily?
P.18
Board Size
A special rule for this assignment:
Still, you are not allowed to use global variable. BUT, you are allow to use global
constants
#include <.....> Why const?
Some compilers don’t accept the ordinary
const int N = 8; // board size variable as the array size (See lecture 7 P.8)
int main(){ It’s safe. The value of const can’t be altered
throughout the program
char board[N][N]; By changing the const variable, the board size
... and the times of iteration are automatically
changed
} (Don’t need to change all the n in the program)
Please Follow this Format
P.19
Pits
Number of pits
You can assume that the input is always non-negative integer [0, ∞)
However, the number of pits should NOT be greater than (board size^2) / 2
→ If the number exceeds the bound, print “Too many pits!”, then ask for the number again
Pit position
Any position that is outside the board or overlapping with the initial four discs are invalid
→ If the input is invalid, print “Invalid position!", then ask for the position again
P.20
Position
User need to input the position for the pits and the discs
You can assume the format will always be [1 character + 1 integer]
( e.g. AAA1, A01, A3.14, 435, 4A, ~@#... will not appear)
However, the position input is not case-sensitive, both lowercase and uppercase are
accepted
( e.g. A1, a1 are both valid and the same position )
P.21
Position
Problem: How can we convert the position to two coordinates?
e.g. A10 or a10 → [9][0]
First, separate the input into row and column
char column_char;
int row_num;
cin >> column_char >> row_num;
e.g. For string “A10”, the first character ‘A’ will be stored into variable column_char
Then, the rest of the string will be stored into integer variable row_num
∴ column_char = ‘A’ and row_num = 10
P.22
Position
Problem: How can we convert the position to two coordinates?
e.g. A10 or a10 → [9][0]
Second, convert the character to column number
Hints:
1. You must understand the ASCII encoding and know how to
read the ASCII table (See lecture 4)
2. You can do both lower and upper cases, or convert the
lowercase to uppercase
P.23
Valid move
There are two situations that we need to check whether the move is valid or not
1. Before each of the player’s turn, we need to check if the player has any valid move to
make
2. After the player inputs the position, we need to check if the position is valid or not
P.24
Valid move
There are two situations that we need to check whether the move is valid or not
1. Before each of the player’s turn, we need to check if the player has any valid move to
make
2. After the player inputs the position, we need to check if the position is valid or not
Three types of invalid position:
1. Position out of bound
2. Non-empty position
3. A position that can’t flip any opponent’s disc
⚫’s turn P.25
Valid move
There are two situations that we need to check whether the move is valid or not
1. Before each of the player’s turn, we need to check if the player has any valid move to
make
2. After the player inputs the position, There
we need to check if the position is valid or not
are eight directions that we should check
If at least one direction is valid, then the move is valid
( break, continue or early return are important here )
Also, there are several cases in one direction
- Next one is empty
- Next one is a pit
- Next one is outside the board
- Next one is our disc
- Next one is opponent’s disc
⚫’s turn P.26
[0] [1] [2]
Valid move
Array[0]
Array[1]
Array[2]
Question: How to loop for eight directions?
For example, the board is represented by the array above
The eight directions are:
[-1][-1] [-1][0] [-1][+1]
[ 0][-1] [ 0][0] [ 0][+1]
[+1][-1] [+1][0] [+1][+1]
You can define your global constant array to store them
(Can be 2 arrays or 8 arrays or others)
Then use the for loop or 8 x if-else depends on your choice
⚫’s turn P.27
Valid move
There are two situations that we need to check whether the move is valid or not
1. Before each of the player’s turn, we need to check if the player has any valid move to
make
2. After the player inputs the position, we need to check if the position is valid or not
Note that there are two cases for checking valid move
Case 0 : Checking for surrounding
Case 1: Looping for a particular direction
Case 0 and Case 1 are with the same surroundings, but
they may return different result
⚫’s turn P.28
Valid move
There are two situations that we need to check whether the move is valid or not
1. Before each of the player’s turn, we need to check if the player has any valid move to
make
2. After the player inputs the position, we need to check if the position is valid or not
Again, if at least one position is valid, player can still play this turn
We must loop the board to find any valid move
→ The logic from the last two pages can be reused
⚫’s turn P.29
Flip
Be careful, there maybe several directions
need to be flipped
⚪’s turn
P.30
End Game
If player X and player O both don’t have any valid move or the board is full, the game is
over
→ You can set a counter to track any two consecutive passes
Finally, remember to print :
- “Game over:”
- The board
- “Player O wins!” or “Player X wins!” or “Draw game!”
P.31
Restrictions
1. You cannot declare any global variables (i.e. variables declared outside any
functions). But global constants or arrays of constants are allowed
2. Please use a character array to represent the board. Avoid using other container
classes like vector, map, etc. available in the standard library.
3. Avoid defining classes in this assignment. We will have other assignments on classes
and objects to come (You’ll see). But using “struct”(C/C++ structures) is still allowed
if you find it fit for this assignment.
P.32
Reminders
1. Your program source file name should be othello.cpp
2. Insert your name, student ID, and e-mail as comments at the beginning of your
source file
3. Your program output should be exactly the same as the sample program (same text,
symbols, letter case, spacings, etc.).
4. Your program should be free of compilation errors and warnings
5. Your program should include suitable comments as documentation.
6. Do NOT plagiarize. (Come on, the assignment is not that hard)
P.33
space
Advice
Don’t lose marks on formatting!!
Be careful with the double digit
(A space for the single digit)
Useful function
setw() // See assignment two and http://www.cplusplus.com/reference/iomanip/setw/
Useful tools for format checking
diff command on linux: https://www.geeksforgeeks.org/diff-command-linux-examples/
or Online diffchecker: https://www.diffchecker.com
P.34
Advice
Modularize your code makes your life easier
Your program should be reasonably decomposed into functions, for example:
- print the board
- initialize the board + add pits
- flip the discs
- check for a valid move
- check for a direction
……
Since the board array is a local variable, your functions should pass the board array as a
parameter (for more details please go to lecture 8, P.18)
P.35
Advice
Be careful with array indexing
e.g. int a[5] = { 1, 2, 3, 4, 5 };
[0] [1] [2] [3] [4]
Index starts from 0, not 1
Do not access a[5] a[5] 1 2 3 4 5
Also be careful with for loop when accessing array
for (int i = 0; i <= 5; i++)
is not the same as
for (int i = 0; i < 5; i++)
P.36
Advice
Try to implement the small board first, then change to larger board size
It only has two players, so you can use 0 and 1 to represent them
→ Whenever you need to change the player, just do
player = 1 - player;
If it is player 0, next turn will be player 1 ( 1 - 0 = 1 )
If it is player 1, next turn will be player 0 ( 1 - 1 = 0 )
Also, if you are using char ‘X’ and ‘O’ to represent players, you can use one line to change
the player (I’ll leave it for you to think)
Knowing more ways to program makes you stronger
P.37
Any Questions?
P.38
Thank you for listening
P.39