In this post we continue developing a dice game in Python.
- In Iteration 1 we coded a single round of the dice game for one player.
- In Iteration 2 we added an additional loop so that multiple rounds were completed until the target score is reached.
Iteration 3
For this iteration we add a second player to the game. A high-level design for the revised game is shown below.
set target set score1 to 0 set score2 to 0 while score1 < target and score2 < target player1 completes their turn update score1 player2 completes their turn update score2 end while output winner and scores
In the algorithm above, if player 1 reaches the target score, then player 2 will also get a turn before the loop terminates. However, the game should terminate as soon as one player reaches the target score. Another issue that we need to consider is ensuring that the amount of repeated code is minimised. A literal interpretation of the pseudocode above can lead to repeated code which we should avoid.
We improve the algorithm by adding a current player counter to keep track of who the current player is.
set target set score1 to 0 set score2 to 0 set current_player to 1 while score1 < target and score2 < target current_player completes their turn if current_player = 1 then update score1 set current_player to 2 else update score2 set current_player to 1 end if end while output winner and scores
After refining the algorithm to reduce the amount of repeated code we implement the algorithm in Python.
The first part of the code, as shown below, includes the necessary package imports together with variable initialisations. The variable current_player
is used to track which player has the current turn. Initially this has a value of 1 (for player one) and will alternate between 1 and 2 until the game is complete.
import random import time target = 200 score1 = 0 score2 = 0 current_player = 1
The next block of code contains the main control loop and code for running the current player's round. The condition for the control loop (highlighted in the code listing) checks whether both scores are below the target score. The next line of code provides an indication of who the current player is.
while score1 < target and score2 < target: print("Player", current_player, "turn") round_score = 0 valid = True while valid: roll1 = random.randint(1, 6) roll2 = random.randint(1, 6) total = roll1 + roll2 if total == 7: valid = False print(total) else: round_score = round_score + total print(total, end=", ") print("You scored", round_score, "this round")
The block of code starting at line 23 is responsible for printing the total score of the current player and then updating the value of the current player before the while loop runs again. The code includes a conditional statement that checks who the current player is. Note that the code in the two branches of the condition block are very similar. This provides further opportunities for improving (refactoring) the code to reduce repetition. This is explore in the next part of the tutorial where we generalise to any number of players.
if current_player == 1: score1 = score1 + round_score print("Total score for player 1 is", score1) current_player = 2 else: score2 = score2 + round_score print("Total score for player 2 is", score2) current_player = 1 time.sleep(1)
The final block of code outputs the winner of the game together with the final score. The winner is determined by comparing the scores of the two players within an if statement condition.
if score1 > score2: print("Player 1 wins", score1, "to", score2) else: print("Player 2 wins", score2, "to", score1)
Example output that is generated when the code is run is shown below. Note that for brevity the output has been elided with only the first three and last round shown.
Player 1 turn 9, 10, 11, 6, 7 You scored 36 this round Total score for player 1 is 36 Player 2 turn 2, 8, 10, 7 You scored 20 this round Total score for player 2 is 20 Player 1 turn 6, 5, 9, 6, 9, 11, 10, 6, 9, 7 You scored 71 this round ... Player 2 turn 11, 8, 11, 4, 6, 6, 5, 10, 5, 9, 7 You scored 75 this round Total score for player 2 is 234 Player 2 wins 234 to 154