Week 1 DVASS Tangibles - Drew Reed
The current progress on my lesson and the Python version of the simulation (using Objects!)
class Card:
def __init__(self, suit, val):
self.suit = suit
self.val = val
if val == 11:
self.kind = "Ace"
elif val == 12:
self.kind = "Jack"
elif val == 13:
self.kind = "Queen"
elif val == 14:
self.kind = "King"
else:
self.kind = str(self.val)
def show(self):
return f"{self.kind} of {self.suit}"
def ace_adj(self):
if self.kind == "Ace":
self.val = 1
card = Card("Spades", 11)
card.show()
import random
class Deck:
def __init__(self):
self.cards = []
self.build()
def build(self):
for suit in ["Spades", "Clubs", "Diamonds", "Hearts"]:
for val in range(2, 15):
self.cards.append(Card(suit, val))
def show(self):
card_disp = [card.show() for card in self.cards]
return card_disp
def shuffle(self):
random.shuffle(self.cards)
def draw_card(self):
return self.cards.pop()
deck = Deck()
deck.shuffle()
from IPython.display import clear_output as clr
player_chips = 100
def game_start():
clr(wait=True)
global player_hand #initializing hands and deck
global dealer_hand
global deck
global p_bet
deck = Deck()
deck.shuffle()
player_hand = []
dealer_hand = []
p_bet = bet(player_chips) #getting the player bet
print("Initial draws:") #giving the initial draws
d1 = hit(dealer_hand)
print(f"The dealer draws: {d1}")
p1 = hit(player_hand)
print(f"You receive: {p1}")
d2 = hit(dealer_hand)
print("The dealer draws a face-down card...")
p2 = hit(player_hand)
print(f"You receive: {p2}")
if sum(player_hand) == 21: #instant player win on blackjack potentially
if sum(dealer_hand) != 21:
print("WOW! A blackjack! You win!")
win(p_bet)
play_again()
return
else:
print("Both you and the dealer have blackjack, so it's a bust! Keep your bet.")
play_again()
return
print("--------------------------------")
print(f"Dealer's hand: {d1}, ???")
player_turn() #once player turn finishes, the dealer turn occurs
play_again()
def bet(chips):
print(f"Current chips: {chips}")
b = input(f"How much would you like to bet? (Input an integer {str(player_chips)} or less.)")
try:
if int(b) <= chips:
return int(b)
else:
print("Invalid bet.")
bet(chips)
except:
print("Invalid bet.")
bet(chips)
def sum(hand):
sm = 0
for card in hand:
if card.val > 11:
sm += 10
else:
sm += card.val
if sm > 21:
for card in hand:
if card.val == 11:
card.ace_adj()
return sum(hand)
return sm
def hit(hand):
res = deck.draw_card()
if (res.val == 11) and (sum(hand) + 11 > 21): #adjusting ace if it would break
res.ace_adj()
hand.append(res)
return res.show()
def hand_display(hand):
disp_hand = []
for card in hand:
disp_hand.append(card.show())
return ", ".join(disp_hand)
def player_turn():
print(f"Your hand: {hand_display(player_hand)}")
if sum(player_hand) > 21:
print("You break! You lose.")
lose(p_bet)
return
rsp = input("Would you like to hit (h) or stay (s)? (input either option)")
if rsp == "h":
received = hit(player_hand)
print(f"You drew a {received}!")
player_turn()
elif rsp == "s":
print("You stand.")
dealer_turn()
else:
print('Invalid input. Input "h" to hit or "s" to stand.')
player_turn()
def dealer_turn():
print(f"Dealer's hand: {hand_display(dealer_hand)}")
if sum(dealer_hand) > 16:
print("The dealer stays.")
pass
else:
print(f"The dealer draws: {hit(dealer_hand)}")
if sum(dealer_hand) > 21:
print("The dealer breaks! You win.")
win(p_bet)
return
dealer_turn()
return
if sum(player_hand) > sum(dealer_hand):
print(f"Congratulations! You won with a hand worth {sum(player_hand)}!")
win(p_bet)
elif sum(dealer_hand) > sum(player_hand):
print(f"Too bad! You lost to the dealer's hand, worth {sum(dealer_hand)}.")
lose(p_bet)
else:
print("It's a push! You keep your bet.")
return
def win(bet):
global player_chips
player_chips += bet
return
def lose(bet):
global player_chips
player_chips -= bet
return
def play_again():
if player_chips != 0:
pa = input('Would you like to play again? (Input "y" for yes and "n" for no.)')
if pa.lower() == "y":
game_start()
else:
print(f"You finished with {str(player_chips)} chips!")
return
else:
print("You lost all of your chips! Better luck next time.")
return
game_start()
Tentative Lesson Plan
My lesson will mainly focus on these topics:
- Lists (Review)
- Iteration (Review)
- Random Values
- Simulations
The lesson will be structured as follows.
Introduction: Simulations
Simulations are models of real-world phenomena or systems that use mathematical algorithms and computer programs simulate the real behavior and aspects of the subject being modeled.
Simulations are most often used to model complex or time-consuming things that would be difficult to test in real life, such as modeling the spread of diseases in certain ecosystems or testing the functionality of a potential product before it is made.
In this lesson, we will be looking at lists, iteration, and random values through the lens of simulations.
Review: Lists and Iteration
In this section, I go over lists to set up for iteration.
Code plans:
# Unique concept: adding things to the list
# Going over lists using the deck list
# Unique concept: shuffling the list
# Unique concept: getting rid of things with pop
def game_start():
#after the game setup and outcome...
play_again()
def play_again():
if player_chips != 0:
pa = input('Would you like to play again? (Input "y" for yes and "n" for no.)')
if pa.lower() == "y":
game_start() #HERE
else:
print(f"You finished with {str(player_chips)} chips!")
return
else:
print("You lost all of your chips! Better luck next time.")
return
For Loops
For loops are used quite often throughout the simulation and are helpful to easily be able to repeat a set of conditions to everything inside of a list/collection of data or to repeat a process a certain number of times.
An example of both of these things are very conveniently seen in the Deck
class function build()
. It also shows loops being nested.
def build(self):
for suit in ["Spades", "Clubs", "Diamonds", "Hearts"]:
for val in range(2, 15):
self.cards.append(Card(suit, val))
Going piece by piece:
for suit in ["Spades", "Clubs", "Diamonds", "Hearts"]:
Whatever is mentioned below this will be repeated four times, once for each of the listed card suits.
for val in range(2, 15)
Here, the for
loop is essentially doing the same thing as before, this time with a list of numbers starting with 2 and ending with 14. As a result, the function runs 13 times, each time with a new integer value that is assigned to the value of a card of a certain suit.
While Loops
While loops aren't used in the program, but they offer a different way to repeat a set of instructions in a program. The procedure below the while [condition]
line will occur until the condition is made not true.
**Student Interation**: How could this `build` function be altered to function with a while loop within it?
def build(self):
for suit in ["Spades", "Clubs", "Diamonds", "Hearts"]:
for val in range(2, 15): #HINT: try replacing this function
self.cards.append(Card(suit, val))
#HINT: you may want to make a variable i to be the numbers in the range
# you could increment it each loop
While loops also alter an alternative way to loop a set of instructions forever, until a precise thing occurs to break the loop. See the code below.
i = 0
while True:
i += 1
ch = random.randint(1, 11)
if ch == 10:
print(f"It took {str(i)} random generations to get 10.")
break
Speaking of random generations...
Random Values
Because unpredictable randomness occurs in the real world, it's important to have a way to represent it. Simulations are able to use randomization, which could be in the form of random number generation or other methods like shuffle
.
Card decks are a great example of how random values can be used to represent real-world scenarios. In the card simulation, the random
module's shuffle
function is used to quite literally shuffle the deck, seen below.
def shuffle(self):
random.shuffle(self.cards)
Often, random selection methods use functions like randint
or randrange
as ways to select certain indexes in lists, or might use the random numbers in some other way.
Without shuffling the card order of the deck, can you think of a way that the aforementioned random
module functions could be used to get a random card from the deck?
import random
s_deck = Deck().show() #the deck shuffle is a separate function, so this is unsorted
rando = random.randint(0, len(s_deck)) #generating a random number to use as index
randsel = s_deck[rando] #selecting a random card with the index
s_deck.pop(rando) #getting rid of the selected card from the deck
print(randsel)