In [1]:
#Hide code
from IPython.display import HTML

HTML('''<script>
function code_toggle() {
if (code_shown){
$('div.input').hide('500');$('#toggleButton').val('Show Code')
} else {
$('div.input').show('500');$('#toggleButton').val('Hide Code')
}
code_shown = !code_shown
}

$( document ).ready(function(){ code_shown=false;$('div.input').hide()
});
</script>
<form action="javascript:code_toggle()"><input type="submit" id="toggleButton" value="Show Code"></form>''')

Out[1]:

# The 21 Coin Game¶

Hello! Welcome to the 21 coin game.

The Rules: Imagine that there is a stack of 21 coins sitting on the table in front of you. You and a partner will take turns, alternatively removing coins from the pile. On each turn you can take either 1 or 2 coins from the pile. You can't skip a turn, and you can't remove more than 2 coins. The person who takes the last coin from the table wins the game, and gets to keep all of the money.

Getting Started: Grab a partner, two different coloured pens (to keep track of how many coins are left after each of your turns), and a piece of paper. We're going to start off by playing against each other, and then we will challenge a computer program using the strategies we have learned! Good luck.

In [1]:
#Importing the tools we need:
import ipywidgets as widgets
from IPython.display import clear_output
from ipywidgets import widgets, Layout, Button, Box
from IPython.display import clear_output
import random

#The needed global pieces
box_layout = Layout(justify_content = "center")
turn = "F"
coins = 21
first_or_second = 0

#Creating the first or second buttons
go_first_button = widgets.Button(
description='First',
disabled=False,
button_style='info', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)
go_second_button = widgets.Button(
description='Second',
disabled=False,
button_style='info', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)

#Laying out the buttons
button_list_3 = [go_first_button,go_second_button]
button_box_3 = Box(children = button_list_3, layout = box_layout)

#Defining the functions which are called when the first and second buttons are pressed.
def go_first(w):
global turn
turn = 'P'
clear_output()
game(turn)
def go_second(w):
global turn
turn = 'C'
clear_output()
game(turn)

#Creating the coin-taking buttons
one_coin_button = widgets.Button(
description='Take 1 coin',
disabled=False,
button_style='info', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)
two_coins_button = widgets.Button(
description='Take 2 coins',
disabled=False,
button_style='info', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)

#Laying out the buttons
button_list = [one_coin_button,two_coins_button]
button_box = Box(children = button_list, layout = box_layout)

#Defining the functions which are called when the take one and take two buttons are pressed.

#This code is run when the player clicks the take one button.
def take_one(w):
global coins
coins = coins-1

#Update the coin total here
print("You have taken 1 coin from the pile. The total number of remaining coins is: " + str(coins))
clear_output()

#Switch the turn to the computer
turn = "C"

#Runs the game function again (but only after a button has been clicked an a move has been made!)
game(turn)

#This code is run when the player clicks the take two button.
def take_two(w):
global coins
coins = coins-2

#Update the coin total here
print("You have taken 2 coins from the pile, leaving " + str(coins) +" coins.")

#Commented out for the same reason as before
clear_output()

#Switch the turn to the computer
turn = "C"

#Runs the game function again
game(turn)

#Creating the yes and no buttons
yes_button = widgets.Button(
description='Yes',
disabled=False,
button_style='success', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)
no_button = widgets.Button(
description='No',
disabled=False,
button_style='danger', # 'success' (green), 'info' (blue), 'warning' (orange), 'danger' (red) or '' (white)
tooltip='Click me',
icon=''
)

#Laying out the buttons
box_layout = Layout(justify_content = "center")
button_list_2 = [yes_button,no_button]
button_box_2 = Box(children = button_list_2, layout = box_layout)

#Defining the functions that are run when the yes and no buttons are presse

def say_yes(w):
global coins
global turn
global first_or_second
coins = 21
turn = 'F'
first_or_second = ' '
clear_output()
game(turn)
def say_no(w):
clear_output()
print("Thanks for playing! See you next time.")

#Defining the replay function
def replay():
print("Thank you for playing! Would you like to play again?")
display(button_box_2)

#Main game function, takes turn as input
def game(turn):
global coins
global first_or_second

if coins == 0:

if turn == 'C':
print("Congratulations! You win!")
elif turn == 'P':
print("The computer has won.")

replay()

#If turn is 1, only this section runs
elif turn == "F":

#Do all the stuff you need to do before the game starts here
print("Hello! Welcome to the 21 coin game!")

#Sets the turn for the next player (you'll want to make sure this is whatever player is chosen to go first)

print("Would you like to play first or second?")
display(button_box_3)

#Runs if it is the player's turn
elif turn == "P":

print("How many coins would you like to take?")

#The only thing that happens in this section is displaying the buttons (and printing stuff if you want to)
#Don't forget to only display one button if there is 1 coin left
if coins > 1:
display(button_box)
elif coins == 1:
display(one_coin_button)
else:
pass

#Runs if it is the computer's turn
elif turn == "C":

#Here you will want to have the computer decide what they will do, and update the coins
option1 = coins - 1
option2 = coins - 2

print("There are " + str(coins) + " coins in the pile.")

if option1%3 == 0:
coins = coins - 1
print("The computer has taken 1 coin from the pile, leaving " + str(coins) + " coins.")

elif option2%3 == 0:
coins = coins - 2
print("The computer has taken 2 coins from the pile, leaving " + str(coins) + " coins.")

else:
computer_taken = random.randint(1,2)

if computer_taken == 1:
coins = coins - 1
print("The computer has taken 1 coin from the pile, leaving " + str(coins) + " coins.")
else:
coins = coins - 2
print("The computer has taken 2 coins from the pile, leaving " + str(coins) + " coins.")

#Turn is switched to the player
turn = "P"

#Calls the game function again
game(turn)

#Button clicking redirect

#First and second buttons
go_first_button.on_click(go_first)
go_second_button.on_click(go_second)

#One coin and two coin buttons
one_coin_button.on_click(take_one)
two_coins_button.on_click(take_two)

#Yes and no buttons
yes_button.on_click(say_yes)
no_button.on_click(say_no)


# Let's Play!¶

In [2]:
game(turn)

Hello! Welcome to the 21 coin game!
Would you like to play first or second?


# Generalizing the Coin Game¶

In the original game, there were 21 coins at the start. Let's change 21 to ANY number of coins at the start. You choose.

In the original game, you could take up to 2 coins on any turn. Let's change 2 to ANY number of coins you can take. You choose.

Once again, the person who takes the last coin from the table wins the game.

In [3]:
box_layout = Layout(justify_content = "center")

turn = "F"

coins = 0
taken_coins = 0
player_turn = 0
game_over = 0

def replay():
global turn
global coins
global first_or_second
global taken_coins
global player_turn
global game_over
play_again = None

while play_again != 'Yes' and play_again != 'yes' and play_again != 'No' and play_again != 'no':
play_again = input("Thank you for playing! Would you like to play again?")

clear_output()

if play_again == 'Yes' or play_again == 'yes':
turn = "F"
coins = 0
taken_coins = 0
player_turn = 0

game(turn)

elif play_again == 'No' or play_again == 'no':
turn = 'Q'
print("Thank you for playing! See you next time.")
else:
print("An unknown error has occured. Please try again later.")

#Main game function, takes turn as input
def game(turn):
global coins
global first_or_second
global taken_coins
global player_turn
global game_over

#Only runs on the first turn
if turn == "F":

#Do all the stuff you need to do before the game starts here

while coins == 0:
coins = int(input('How many coins would you like to play with? '))

while taken_coins == 0:
taken_coins = int(input('What is the maximal number of coins you would like a player to be able to take on their turn? '))

while player_turn != 1 and player_turn != 2:
player_turn = int(input("Would you like to play first or second? Please enter 1 for first and 2 for second. "))

clear_output()

if player_turn == 1:
turn = 'P'
elif player_turn == 2:
turn = 'C'
else:
turn = 'F'

game(turn)

#win check
elif coins == 0 and game_over != 1:

if turn == 'C':
print("Congratulations! You win!")
elif turn == 'P':
print("The computer has won.")

replay()

#Runs if it is the player's turn
elif turn == "P":

taking_coins = coins + 100

while taking_coins > coins or taking_coins > taken_coins:
taking_coins = int(input("How many coins would you like to take?"))

clear_output()

coins = coins - taking_coins

turn = 'C'
game(turn)

#Runs if it is the computer's turn
elif turn == "C":

print("There are " + str(coins) + " coins in the pile.")

#Here you will want to have the computer decide what they will do, and update the coins
for x in range(1,taken_coins+1):
if (coins - x)%(taken_coins+1) == 0:
coins = coins - x
print("The computer has taken " + str(x) + ' coins from the pile, leaving ' + str(coins) + ' coins.')
turn = 'P'
game(turn)
else:
continue

computer_taken = random.randint(1,taken_coins)

coins = coins - computer_taken
print("The computer has taken " + str(computer_taken) + ' coins from the pile, leaving ' + str(coins) + ' coins.')

#Turn is switched to the player
turn = "P"

#Calls the game function again
game(turn)


# Let's Play!¶

In [ ]:
game(turn)