0% found this document useful (0 votes)
3 views

Lab 8 Plenary

The document discusses the implementation and strategies for the game Reversi, focusing on a divide-and-conquer approach to problem-solving by breaking down complex tasks into manageable pieces. It outlines the pseudocode for game actions, detailing the turn-taking process between a computer and a human player, and emphasizes the importance of move legality checks and smarter computer moves. Additionally, it highlights the iterative process of developing a simpler version of the game to facilitate testing and improvement.

Uploaded by

Kevin Gan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

Lab 8 Plenary

The document discusses the implementation and strategies for the game Reversi, focusing on a divide-and-conquer approach to problem-solving by breaking down complex tasks into manageable pieces. It outlines the pseudocode for game actions, detailing the turn-taking process between a computer and a human player, and emphasizes the importance of move legality checks and smarter computer moves. Additionally, it highlights the iterative process of developing a simpler version of the game to facilitate testing and improvement.

Uploaded by

Kevin Gan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 127

Reversi: Implementation and

Strategies

Baochun Li
Department of Electrical and Computer Engineering
University of Toronto
Revisiting engineering design

2
Revisiting engineering design
‣ Divide-and-conquer: involves dividing a complex problem into
smaller pieces

2
Revisiting engineering design
‣ Divide-and-conquer: involves dividing a complex problem into
smaller pieces

‣ Implement and test each of the pieces

2
Revisiting engineering design
‣ Divide-and-conquer: involves dividing a complex problem into
smaller pieces

‣ Implement and test each of the pieces

‣ Compose solutions for the smaller pieces into a solution for the
overall complex problem

2
Revisiting engineering design
‣ Divide-and-conquer: involves dividing a complex problem into
smaller pieces

‣ Implement and test each of the pieces

‣ Compose solutions for the smaller pieces into a solution for the
overall complex problem

‣ May have many “levels” of dividing, implementing and testing


(especially for a very complex problem)

2
Revisiting engineering design
‣ Divide-and-conquer: involves dividing a complex problem into
smaller pieces

‣ Implement and test each of the pieces

‣ Compose solutions for the smaller pieces into a solution for the
overall complex problem

‣ May have many “levels” of dividing, implementing and testing


(especially for a very complex problem)

‣ Many times, decomposing a complex problem into manageable


pieces is challenging in itself and often requires creativity!

2
Imagine you are playing Reversi with a friend
using a board, what are the actions of play?

3
Game action: Pseudocode

4
Game action: Pseudocode
turn = Black // initially

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))
turn = turn

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))
turn = turn
else // neither player has a turn

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))
turn = turn
else // neither player has a turn
game is over

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))
turn = turn
else // neither player has a turn
game is over
figure out the winner

4
Game action: Pseudocode
turn = Black // initially
computer = White // for example
while (game is not over) {
if (turn == computer)
computer should make a move
else
human should make a move
check if legal, and if not, game over
if (game is not over)
if (moveAvailable(findOpposite(turn))
turn = findOpposite(turn)
else if (moveAvailable(turn))
turn = turn
else // neither player has a turn
game is over
figure out the winner
}
4
Go Partway First

5
Go Partway First
‣ Our general idea has a lot of pieces to it — seems
awfully hard!

5
Go Partway First
‣ Our general idea has a lot of pieces to it — seems
awfully hard!

‣ Often, in software development, it is useful to


implement something much simpler that isn’t exactly
what we want, but yet brings us closer to the thing we
want

5
Go Partway First
‣ Our general idea has a lot of pieces to it — seems
awfully hard!

‣ Often, in software development, it is useful to


implement something much simpler that isn’t exactly
what we want, but yet brings us closer to the thing we
want

‣ Can you think of a simpler version that isn’t complete,


but would allow us to test things along the way?

5
Go Partway First
turn = Black // initially
computer = White // for example
while (true) {
if (turn == computer)
computer makes ANY legal move
else
human should make a move

turn = findOpposite(turn)
}
What’s missing?

6
What’s missing?

7
What’s missing?
‣ Move legality check for human player

7
What’s missing?
‣ Move legality check for human player

‣ Smarter moves for the computer

7
What’s missing?
‣ Move legality check for human player

‣ Smarter moves for the computer

‣ Some turn-taking processing

7
What’s missing?
‣ Move legality check for human player

‣ Smarter moves for the computer

‣ Some turn-taking processing

‣ Game over detection

7
Go Partway First

8
Go Partway First
‣ The beauty of this is we can start playing right away
and test the turn-taking behaviour!

8
Go Partway First
‣ The beauty of this is we can start playing right away
and test the turn-taking behaviour!

‣ How do we make the computer play any legal move?

8
Go Partway First
‣ The beauty of this is we can start playing right away
and test the turn-taking behaviour!

‣ How do we make the computer play any legal move?

‣ In your lab 7, you already printed out all available


moves for each colour. You can use that code to
make the computer play the first available move.

8
Back to the Full Implementation

9
Is a Move Available for a Colour?
‣ How would you decide if a player has an
available move?

‣ Let’s break it down into small pieces …

10
Is a Move Available for a Colour?

11
Is a Move Available for a Colour?
‣ A possible breakdown:

11
Is a Move Available for a Colour?
‣ A possible breakdown:

‣ First write a function isValidMove that accepts a


colour, row and column as input (as well as the board)
and determines if the (row, column) position is a legal
move for that colour

11
Is a Move Available for a Colour?
‣ A possible breakdown:

‣ First write a function isValidMove that accepts a


colour, row and column as input (as well as the board)
and determines if the (row, column) position is a legal
move for that colour

‣ How would this operate?

11
Is a Move Available for a Colour?
‣ A possible breakdown:

‣ First write a function isValidMove that accepts a


colour, row and column as input (as well as the board)
and determines if the (row, column) position is a legal
move for that colour

‣ How would this operate?

‣ Hint: Use your functionality from Lab 7

11
Is a Move Available for a Colour?

12
Is a Move Available for a Colour?
‣ You now have the function isValidMove

12
Is a Move Available for a Colour?
‣ You now have the function isValidMove

‣ Then write another function moveAvailable that


accepts a colour as input (as well as the board) and
determines if the colour has any valid move

12
Is a Move Available for a Colour?
‣ You now have the function isValidMove

‣ Then write another function moveAvailable that


accepts a colour as input (as well as the board) and
determines if the colour has any valid move

‣ How would this operate?

12
Is a Move Available for a Colour?
‣ You now have the function isValidMove

‣ Then write another function moveAvailable that


accepts a colour as input (as well as the board) and
determines if the colour has any valid move

‣ How would this operate?

‣ Hint: call isValidMove above

12
Smart Computer Moves: Part 1

Computer plays Black


13
Smart Computer Moves: Part 1

Computer plays Black


13
Smart Computer Moves: Part 1

1 3

Computer plays Black


13
Smart Computer Moves: Part 1

1 3 2

Computer plays Black


13
Smart Computer Moves: Part 1

1 3 2 x

Computer plays Black


13
Smart Computer Moves: Part 1

1 3 2 x

Computer plays Black


13
Smart Computer Moves: Part 1

1 3 2 x

x x

Computer plays Black


13
Computer Moves: Part I

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

‣ As the program walks the locations in order, what is happening?

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

‣ As the program walks the locations in order, what is happening?

‣ “Score” each location

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

‣ As the program walks the locations in order, what is happening?

‣ “Score” each location

‣ Keep track of the highest score

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

‣ As the program walks the locations in order, what is happening?

‣ “Score” each location

‣ Keep track of the highest score

‣ Keep track of the (row, col) associated with the highest score

14
Computer Moves: Part I
‣ First of all, notice that order in which the previous slides considered
the locations: how to achieve that order?

‣ Nested for loops: an outer loop over the rows, an inner loop over
the columns

‣ As the program walks the locations in order, what is happening?

‣ “Score” each location

‣ Keep track of the highest score

‣ Keep track of the (row, col) associated with the highest score

‣ In the event of a tied score, what happens?


14
Scoring a Location

15
Scoring a Location
‣ Say the computer is playing black, and (row, col) is a valid
location for the computer to play

15
Scoring a Location
‣ Say the computer is playing black, and (row, col) is a valid
location for the computer to play

‣ How does one determine the number of White tiles that would
be flipped if Black plays at that location?

15
Scoring a Location
‣ Say the computer is playing black, and (row, col) is a valid
location for the computer to play

‣ How does one determine the number of White tiles that would
be flipped if Black plays at that location?

‣ One idea: actually play a Black tile at that location and do the
flipping, as your Lab 7 program did

15
Scoring a Location
‣ Say the computer is playing black, and (row, col) is a valid
location for the computer to play

‣ How does one determine the number of White tiles that would
be flipped if Black plays at that location?

‣ One idea: actually play a Black tile at that location and do the
flipping, as your Lab 7 program did

‣ What’s the problem with this approach? — “Undo”

15
Scoring a Location
‣ Say the computer is playing black, and (row, col) is a valid
location for the computer to play

‣ How does one determine the number of White tiles that would
be flipped if Black plays at that location?

‣ One idea: actually play a Black tile at that location and do the
flipping, as your Lab 7 program did

‣ What’s the problem with this approach? — “Undo”

‣ How do you solve this problem?


15
Introduce a boolean parameter
int checkValidAndFlip(char board[][26],
int row, int col, char colour, int n,
bool flip)

// ‘flip’ tells me if I really want


to flip the tiles when computing the
score

// the function returns the score for


(row, col) position and the colour

16
An Alternative Solution

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)
‣ Perhaps in a function called copyBoard

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)
‣ Perhaps in a function called copyBoard
‣ Play Black in the candidate position in the board copy

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)
‣ Perhaps in a function called copyBoard
‣ Play Black in the candidate position in the board copy
‣ Flip tiles in the board copy using the Lab 7 solution

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)
‣ Perhaps in a function called copyBoard
‣ Play Black in the candidate position in the board copy
‣ Flip tiles in the board copy using the Lab 7 solution
‣ Count the number of Black tiles in the board copy, call it
blackCountAfterFlip

17
An Alternative Solution
‣ Before any move scoring, count the number of Black tiles on the
board, call this blackCountBeforeFlip
‣ For each candidate position where Black may play legally
‣ Make a copy of the entire board (use nested for loops)
‣ Perhaps in a function called copyBoard
‣ Play Black in the candidate position in the board copy
‣ Flip tiles in the board copy using the Lab 7 solution
‣ Count the number of Black tiles in the board copy, call it
blackCountAfterFlip
‣ Score for candidate location = blackCountAfterFlip -
blackCountBeforeFlip - 1
17
Scoring a Location

blackCountBeforeFlip = 5

Computer plays Black 18


Scoring a Location

?
copyBoard

blackCountBeforeFlip = 5

Computer plays Black 19


Scoring a Location

?
copyBoard

blackCountBeforeFlip = 5 blackCountAfterFlip = 9

Computer plays Black 20


Scoring a Location
score = 9 - 5 - 1 = 3

? 3
copyBoard

blackCountBeforeFlip = 5 blackCountAfterFlip = 9

Computer plays Black 21


Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences
‣ What are other factors to consider in a location’s score?

22
Part II: Strategies

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences
‣ What are other factors to consider in a location’s score?

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences
‣ What are other factors to consider in a location’s score?
‣ Corners of the board are good

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences
‣ What are other factors to consider in a location’s score?
‣ Corners of the board are good
‣ Fewer available counter-moves for the opponent

23
Part II: Strategies
‣ This is really just about different (more clever) ways of scoring
locations
‣ The Part I approach is called “greedy”
‣ Goes for the maximum # of flips, regardless of
consequences
‣ What are other factors to consider in a location’s score?
‣ Corners of the board are good
‣ Fewer available counter-moves for the opponent
‣ Opponent’s potential response to computer’s move

23
Composite scoring
‣ You can consider a “composite” scoring function:

score = a * #flips + b * #corners + c


* #opponentMovesEliminated

(a, b and c are constants you set


empirically)

24
Finding # of Available Opponent Moves

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped
‣ Say (r1, c1) leaves White with 4 locations to play, and (r2, c2)
leaves White with 1 location to play

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped
‣ Say (r1, c1) leaves White with 4 locations to play, and (r2, c2)
leaves White with 1 location to play
‣ (r2, c2) may be a better move

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped
‣ Say (r1, c1) leaves White with 4 locations to play, and (r2, c2)
leaves White with 1 location to play
‣ (r2, c2) may be a better move
‣ How would you find, for a candidate move position, the
number of locations in which the opponent could play after the
flipping?

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped
‣ Say (r1, c1) leaves White with 4 locations to play, and (r2, c2)
leaves White with 1 location to play
‣ (r2, c2) may be a better move
‣ How would you find, for a candidate move position, the
number of locations in which the opponent could play after the
flipping?
‣ Use the copy of the board

25
Finding # of Available Opponent Moves
‣ Imagine a computer is playing Black, and two locations (r1, c1)
and (r2, c2) result in 3 White tiles being flipped
‣ Say (r1, c1) leaves White with 4 locations to play, and (r2, c2)
leaves White with 1 location to play
‣ (r2, c2) may be a better move
‣ How would you find, for a candidate move position, the
number of locations in which the opponent could play after the
flipping?
‣ Use the copy of the board
‣ Use a nested loop and the isValidMove function we
talked about before
25
Scoring a Location
In how many locations can White play? 3

? 3
copyBoard

blackCountBeforeFlip = 5 blackCountAfterFlip = 9

Computer plays Black 26


With a copy of the board as a “scratch pad,”
we can call isValidMove to find out possible
opponent moves!

27
More Sophisticated: Game Tree

28
More Sophisticated: Game Tree
‣ Board-game playing programs (Chess, Go, etc.) use
a “game tree”

28
More Sophisticated: Game Tree
‣ Board-game playing programs (Chess, Go, etc.) use
a “game tree”

‣ When humans play these games, good players can


“look several moves into the future” to see eventual
consequences of a move

28
More Sophisticated: Game Tree
‣ Board-game playing programs (Chess, Go, etc.) use
a “game tree”

‣ When humans play these games, good players can


“look several moves into the future” to see eventual
consequences of a move

‣ A “game tree” is a way of looking into the future


within a computer program

28
It’s now Black’s move

29
It’s now Black’s move

... …
30
Game Tree

31
Game Tree
‣ Still needs a way to “score” candidate moves

31
Game Tree
‣ Still needs a way to “score” candidate moves

‣ Our example game tree has a depth of 2, and to


be smarter we need to go deeper

31
Game Tree
‣ Still needs a way to “score” candidate moves

‣ Our example game tree has a depth of 2, and to


be smarter we need to go deeper

‣ For each of Black’s candidate moves, expect the


opponent to play its best possible response

31
Game Tree: Challenges

32
Game Tree: Challenges
‣ Manage copies of the board representing future
configurations

32
Game Tree: Challenges
‣ Manage copies of the board representing future
configurations

‣ Handling the case when one player gets a chance


to make multiple moves in succession (the
opponent has no valid moves)

32
Game Tree: Challenges
‣ Manage copies of the board representing future
configurations

‣ Handling the case when one player gets a chance


to make multiple moves in succession (the
opponent has no valid moves)

‣ Google “game tree” and “minimax” to learn more


about it

32
Testing Your Part II Code
‣ Read the lab 7 handout: “Testing Your Work”
‣ Download a static library containing our solutions for
Fourth time
your code in this
to play course:
against: liblab8part2.a
APS
‣ Add 105 competition
#include leaderboard
<lab8part2lib.h>
http://aps105.ece.utoronto.ca:8090
‣ Call either of our solutions instead of prompting for
input from a human player:
findSmarterMove(board, n, colour, &row, &col);
findSmartestMove(board, n, colour, &row,
&col);
22
33
The APS 105 Reversi Leaderboard

34
The APS 105 Reversi Leaderboard
‣ Entered automatically when you submit your Lab 8 Part 2 to examify.ca, if
your submission passes the test cases

34
The APS 105 Reversi Leaderboard
‣ Entered automatically when you submit your Lab 8 Part 2 to examify.ca, if
your submission passes the test cases

‣ Pairwise competitions between leaderboard participants

34
The APS 105 Reversi Leaderboard
‣ Entered automatically when you submit your Lab 8 Part 2 to examify.ca, if
your submission passes the test cases

‣ Pairwise competitions between leaderboard participants

‣ Two games are played between each pair of finalists, and the results are
scored and ranked

34
The APS 105 Reversi Leaderboard
‣ Entered automatically when you submit your Lab 8 Part 2 to examify.ca, if
your submission passes the test cases

‣ Pairwise competitions between leaderboard participants

‣ Two games are played between each pair of finalists, and the results are
scored and ranked

‣ Continuously run every several days, submit as many times as you wish

34
Enjoy the lab and have fun!

35

You might also like