Blackjack
Blackjack against the dealer with one deck and a stack of chips: hit, stand or double, aces counted 1 or 11 with soft totals shown, the dealer drawing to 16 and standing on every 17, a blackjack paying 3 to 2. The deck is shuffled by a Fisher-Yates shuffle on EML's own random numbers, so a seed deals the same cards every time.
Every screen below was recorded under CPython. When this page was built, the EML interpreter replayed each session from the same input and printed the same bytes.
About
Blackjack against the dealer, with one deck and a stack of chips. Get closer to 21 than the dealer without going over. Number cards count their number, jacks, queens and kings count 10, and an ace counts 1 or 11, whichever helps. You can hit, stand, or double your bet for one more card.
main.eml- the menu, the bets, playing a hand in the order of a real table, and the chipscards.eml- the deck and its shuffle, card names, the value of a hand, and how a hand is settledrng.eml- random numbers written in EML, the generator of P008
How each part works:
- The deck is shuffled by Fisher-Yates from the last position down. The card for each position is picked from that position and every one before it, so every order is equally likely, and a card may stay where it was. The corpus case
the-shuffle-left-one-in-place-as-expectedworks out that a uniform shuffle leaves one card in place on average; a shuffle that never did would be less random, not more. A new deck is shuffled before a hand when fewer than 15 cards are left. The random numbers come from EML code, so a seed deals the same cards every time. - A hand's value counts every ace as 1, then one ace as 11 when that does not go over 21; the hand is then soft. Only one ace can ever count 11, since two would make 22.
- The cards are dealt you, dealer, you, dealer, with the dealer's second card face down. A blackjack - an ace and a ten-card as the first two - ends the hand at once: yours alone pays 3 to 2, rounded down; the dealer's alone takes your bet; both is a push.
- You may double on your first two cards when your chips cover twice the bet: the bet doubles and you get exactly one more card. A hand that reaches 21 stops asking.
- If you bust, you lose and the dealer does not play. Otherwise the dealer turns over the hidden card and draws to 16, standing on every 17, including a soft 17. There is no splitting and no insurance.
What is checked: menu choices 1 to 3; a bet from 1 to your chips; h, s and d in a hand, where d is only accepted while doubling is allowed; a new game with 10 to 1000 chips and a seed from 0 to 999999999; no hand without chips. An empty answer cancels.
Sessions: sessions/basic.in plays nine hands of the default game (100 chips, seed 2026): - a soft 13 hit to a soft 19, and a push when the dealer draws to 19; - two doubles that lose; - a blackjack on a bet of 5, which wins 7 (7.5 rounded down); - a 9 hit twice to 20, winning against 18; - a double that busts; - a double that wins when the dealer busts after drawing twice; - a new deck before the eighth hand, with 14 cards left, and a bust; - the last 7 chips lost to the dealer's blackjack, and the game is out of chips.
sessions/bad-input.in gives: - menu choices 0 and x; - bets 0, 101 and abc, then an empty one; - x in a hand, and d after a hit; - d with all 100 chips bet, so doubling is not offered. That hand goes from a soft 17 to a hard 15 and busts, and the game is out of chips; - a hand with no chips; - a new game with chips 9, 1001 and x, cancelled at each question, and then 10 chips with seed 7, where a blackjack on a bet of 10 wins 15.
Built on the verified corpus case the-shuffle-left-one-in-place-as-expected (how often a uniform shuffle leaves an item where it was).
Recorded sessions
What the screen shows while someone uses the program. Each typed line appears after its prompt, the way a terminal shows it.
bad-input
interpreter: byte-equal== Blackjack ==
Get closer to 21 than the dealer without going over. The dealer draws to 16 and stands on 17.
A new game: 100 chips, seed 2026.
1) play a hand 2) new game 3) quit
choice> 0
Pick a number from 1 to 3.
1) play a hand 2) new game 3) quit
choice> x
Pick a number from 1 to 3.
1) play a hand 2) new game 3) quit
choice> 1
The deck is shuffled.
bet (1 to 100)> 0
Type a bet from 1 to 100.
bet (1 to 100)> 101
Type a bet from 1 to 100.
bet (1 to 100)> abc
Type a bet from 1 to 100.
bet (1 to 100)>
Cancelled.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 100)> 10
Dealer: 6D ??
You: 2C AH - soft 13
h) hit s) stand d) double> x
Type h to take a card, s to stay, or d to double your bet for one card.
h) hit s) stand d) double> h
You draw 6H: 2C AH 6H - soft 19
h) hit s) stand> d
Type h to take a card or s to stay.
h) hit s) stand> s
The dealer turns over KS: 6D KS - 16
The dealer draws 3H: 6D KS 3H - 19
A push at 19 - your bet comes back.
Chips 100 after 1 hand: 0 won, 0 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 100)> 100
Dealer: 9H ??
You: AC 2D - soft 13
h) hit s) stand> d
Type h to take a card or s to stay.
h) hit s) stand> h
You draw 4H: AC 2D 4H - soft 17
h) hit s) stand> h
You draw 8D: AC 2D 4H 8D - 15
h) hit s) stand> h
You draw 10H: AC 2D 4H 8D 10H - 25, bust
Bust - you lose 100.
Chips 0 after 2 hands: 0 won, 1 lost, 1 pushed.
You are out of chips - start a new game to play on.
1) play a hand 2) new game 3) quit
choice> 1
You have no chips left - start a new game.
1) play a hand 2) new game 3) quit
choice> 2
chips (10 to 1000)> 9
Type a number from 10 to 1000.
chips (10 to 1000)> 1001
Type a number from 10 to 1000.
chips (10 to 1000)> x
Type a number from 10 to 1000.
chips (10 to 1000)>
Cancelled.
1) play a hand 2) new game 3) quit
choice> 2
chips (10 to 1000)> 10
seed (0 to 999999999)>
Cancelled.
1) play a hand 2) new game 3) quit
choice> 2
chips (10 to 1000)> 10
seed (0 to 999999999)> 7
A new game: 10 chips, seed 7.
1) play a hand 2) new game 3) quit
choice> 1
The deck is shuffled.
bet (1 to 10)> 10
Dealer: 4C 6S
10
You: AH QS - blackjack
Blackjack! You win 15.
Chips 25 after 1 hand: 1 won, 0 lost, 0 pushed.
1) play a hand 2) new game 3) quit
choice> 3
Bye.
What was typed (34 lines)
0
x
1
0
101
abc
1
10
x
h
d
s
1
100
d
h
h
h
1
2
9
1001
x
2
10
2
10
7
1
10
3
basic
interpreter: byte-equal== Blackjack ==
Get closer to 21 than the dealer without going over. The dealer draws to 16 and stands on 17.
A new game: 100 chips, seed 2026.
1) play a hand 2) new game 3) quit
choice> 1
The deck is shuffled.
bet (1 to 100)> 25
Dealer: 6D ??
You: 2C AH - soft 13
h) hit s) stand d) double> h
You draw 6H: 2C AH 6H - soft 19
h) hit s) stand> s
The dealer turns over KS: 6D KS - 16
The dealer draws 3H: 6D KS 3H - 19
A push at 19 - your bet comes back.
Chips 100 after 1 hand: 0 won, 0 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 100)> 15
Dealer: 9H ??
You: AC 2D - soft 13
h) hit s) stand d) double> d
You double to 30 and draw 4H: AC 2D 4H - soft 17
The dealer turns over 10D: 9H 10D - 19
The dealer wins, 19 against 17 - you lose 30.
Chips 70 after 2 hands: 0 won, 1 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 70)> 20
Dealer: 10H ??
You: 8D 3C - 11
h) hit s) stand d) double> d
You double to 40 and draw 5S: 8D 3C 5S - 16
The dealer turns over 9D: 10H 9D - 19
The dealer wins, 19 against 16 - you lose 40.
Chips 30 after 3 hands: 0 won, 2 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 30)> 5
Dealer: 8H KC
18
You: QS AD - blackjack
Blackjack! You win 7.
Chips 37 after 4 hands: 1 won, 2 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 37)> 10
Dealer: 10C ??
You: 5C 4S - 9
h) hit s) stand d) double> h
You draw 4C: 5C 4S 4C - 13
h) hit s) stand> h
You draw 7H: 5C 4S 4C 7H - 20
h) hit s) stand> s
The dealer turns over 8C: 10C 8C - 18
You win 10, 20 against 18.
Chips 47 after 5 hands: 2 won, 2 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 47)> 15
Dealer: 4D ??
You: 8S 7S - 15
h) hit s) stand d) double> d
You double to 30 and draw JS: 8S 7S JS - 25, bust
Bust - you lose 30.
Chips 17 after 6 hands: 2 won, 3 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 17)> 5
Dealer: JH ??
You: 5H 5D - 10
h) hit s) stand d) double> d
You double to 10 and draw 3S: 5H 5D 3S - 13
The dealer turns over 2H: JH 2H - 12
The dealer draws 2S: JH 2H 2S - 14
The dealer draws KD: JH 2H 2S KD - 24, bust
The dealer busts - you win 10.
Chips 27 after 7 hands: 3 won, 3 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
The deck is shuffled.
bet (1 to 27)> 20
Dealer: JC ??
You: 7D 5S - 12
h) hit s) stand> h
You draw 4D: 7D 5S 4D - 16
h) hit s) stand> h
You draw 8S: 7D 5S 4D 8S - 24, bust
Bust - you lose 20.
Chips 7 after 8 hands: 3 won, 4 lost, 1 pushed.
1) play a hand 2) new game 3) quit
choice> 1
bet (1 to 7)> 7
Dealer: AS JH
blackjack
You: 10D 2S - 12
The dealer has blackjack - you lose 7.
Chips 0 after 9 hands: 3 won, 5 lost, 1 pushed.
You are out of chips - start a new game to play on.
1) play a hand 2) new game 3) quit
choice> 3
Bye.
What was typed (30 lines)
1
25
h
s
1
15
d
1
20
d
1
5
1
10
h
h
s
1
15
d
1
5
d
1
20
h
h
1
7
3
Modules
The program as written, entry module first. Each module transpiles to its own Python file, which is what eml project run executes.
main.eml(entry)
eml# P049 blackjack: get closer to 21 than the dealer without going over. Aces
# count 1 or 11, faces 10. The dealer draws to 16 and stands on 17, a
# blackjack pays 3 to 2, and the deck is shuffled by EML's own random
# numbers, so a seed deals the same cards every time.
import cards
import rng
def trim(s):
0 => i
len(s) => j
while i < j and s[i] == " ":
i + 1 => i
while j > i and s[j - 1] == " ":
j - 1 => j
return s[i:j]
def number(s):
if s == "" or len(s) > 9:
return -1
0 => n
for c in s:
if not (c in "0123456789"):
return -1
n * 10 + int(c) => n
return n
def counted(n, word):
if n == 1:
return "1 " + word
return str(n) + " " + word + "s"
def start(chips, seed):
("A new game: " + str(chips) + " chips, seed " + str(seed) + ".") ^0
# [chips, the generator, the deck, next card, hands, won, lost, pushed]
return [chips, rng.Rng(seed), [], 0, 0, 0, 0, 0]
def shuffle(game):
cards.shuffled(cards.new_deck(), game[1]) => game[2]
0 => game[3]
def draw(game):
if game[3] == len(game[2]):
# Only a very long hand gets here; the cards on the table are not
# taken out of the new deck.
"The deck has run out - a new one is shuffled." ^0
shuffle(game)
game[2][game[3]] => card
game[3] + 1 => game[3]
return card
def table(player, dealer, hide):
("Dealer: " + cards.shown(dealer, hide)) ^0
if not hide:
(" " + cards.described(dealer)) ^0
("You: " + cards.shown(player, False) + " - " + cards.described(player)) ^0
def settle(game, won):
game[0] + won => game[0]
game[4] + 1 => game[4]
if won > 0:
game[5] + 1 => game[5]
elif won < 0:
game[6] + 1 => game[6]
else:
game[7] + 1 => game[7]
("Chips " + str(game[0]) + " after " + counted(game[4], "hand") + ": " + str(game[5]) + " won, " + str(game[6]) + " lost, " + str(game[7]) + " pushed.") ^0
if game[0] == 0:
"You are out of chips - start a new game to play on." ^0
def ask_bet(game):
while True:
trim(input("bet (1 to " + str(game[0]) + ")> ")) => answer
if answer == "":
return -1
number(answer) => n
if n >= 1 and n <= game[0]:
return n
("Type a bet from 1 to " + str(game[0]) + ".") ^0
def play_hand(game):
if game[0] == 0:
"You have no chips left - start a new game." ^0
return game
if len(game[2]) - game[3] < 15:
shuffle(game)
"The deck is shuffled." ^0
ask_bet(game) => bet
if bet == -1:
"Cancelled." ^0
return game
# Dealt in turn, as at a table: you, the dealer, you, the dealer - the
# dealer's second card face down.
[draw(game)] => player
[draw(game)] => dealer
player + [draw(game)] => player
dealer + [draw(game)] => dealer
if cards.blackjack(player) or cards.blackjack(dealer):
table(player, dealer, False)
cards.natural_result(player, dealer, bet) => won
if won == 0:
"Both have blackjack - a push, your bet comes back." ^0
elif won > 0:
("Blackjack! You win " + str(won) + ".") ^0
else:
("The dealer has blackjack - you lose " + str(bet) + ".") ^0
settle(game, won)
return game
table(player, dealer, True)
bet => stake
True => asking
while asking and cards.value(player)[0] < 21:
(len(player) == 2 and game[0] >= bet * 2) => can_double
if can_double:
trim(input("h) hit s) stand d) double> ")) => action
else:
trim(input("h) hit s) stand> ")) => action
if action == "h":
draw(game) => card
player + [card] => player
("You draw " + cards.name(card) + ": " + cards.shown(player, False) + " - " + cards.described(player)) ^0
elif action == "s":
False => asking
elif action == "d" and can_double:
bet * 2 => stake
draw(game) => card
player + [card] => player
("You double to " + str(stake) + " and draw " + cards.name(card) + ": " + cards.shown(player, False) + " - " + cards.described(player)) ^0
False => asking
elif can_double:
"Type h to take a card, s to stay, or d to double your bet for one card." ^0
else:
"Type h to take a card or s to stay." ^0
if cards.value(player)[0] > 21:
("Bust - you lose " + str(stake) + ".") ^0
settle(game, 0 - stake)
return game
("The dealer turns over " + cards.name(dealer[1]) + ": " + cards.shown(dealer, False) + " - " + cards.described(dealer)) ^0
while not cards.dealer_stands(dealer):
draw(game) => card
dealer + [card] => dealer
("The dealer draws " + cards.name(card) + ": " + cards.shown(dealer, False) + " - " + cards.described(dealer)) ^0
cards.result(player, dealer, stake) => won
cards.value(player)[0] => p
cards.value(dealer)[0] => d
if d > 21:
("The dealer busts - you win " + str(won) + ".") ^0
elif won > 0:
("You win " + str(won) + ", " + str(p) + " against " + str(d) + ".") ^0
elif won < 0:
("The dealer wins, " + str(d) + " against " + str(p) + " - you lose " + str(stake) + ".") ^0
else:
("A push at " + str(p) + " - your bet comes back.") ^0
settle(game, won)
return game
def ask_number(prompt, low, high):
while True:
trim(input(prompt + " (" + str(low) + " to " + str(high) + ")> ")) => answer
if answer == "":
return -1
number(answer) => n
if n >= low and n <= high:
return n
("Type a number from " + str(low) + " to " + str(high) + ".") ^0
def new_game(game):
ask_number("chips", 10, 1000) => chips
if chips == -1:
"Cancelled." ^0
return game
ask_number("seed", 0, 999999999) => seed
if seed == -1:
"Cancelled." ^0
return game
return start(chips, seed)
"== Blackjack ==" ^0
"Get closer to 21 than the dealer without going over. The dealer draws to 16 and stands on 17." ^0
start(100, 2026) => game
True => running
while running:
"" ^0
"1) play a hand 2) new game 3) quit" ^0
trim(input("choice> ")) => choice
if choice == "1":
play_hand(game) => game
elif choice == "2":
new_game(game) => game
elif choice == "3":
False => running
else:
"Pick a number from 1 to 3." ^0
"Bye." ^0
Python projection (main.py)
import cards
import rng
def trim(s):
i = 0
j = len(s)
while i < j and s[i] == " ":
i = i + 1
while j > i and s[j - 1] == " ":
j = j - 1
return s[i:j]
def number(s):
if s == "" or len(s) > 9:
return -1
n = 0
for c in s:
if not c in "0123456789":
return -1
n = n * 10 + int(c)
return n
def counted(n, word):
if n == 1:
return "1 " + word
return str(n) + " " + word + "s"
def start(chips, seed):
print("A new game: " + str(chips) + " chips, seed " + str(seed) + ".")
return [chips, rng.Rng(seed), [], 0, 0, 0, 0, 0]
def shuffle(game):
game[2] = cards.shuffled(cards.new_deck(), game[1])
game[3] = 0
def draw(game):
if game[3] == len(game[2]):
print("The deck has run out - a new one is shuffled.")
shuffle(game)
card = game[2][game[3]]
game[3] = game[3] + 1
return card
def table(player, dealer, hide):
print("Dealer: " + cards.shown(dealer, hide))
if not hide:
print(" " + cards.described(dealer))
print("You: " + cards.shown(player, False) + " - " + cards.described(player))
def settle(game, won):
game[0] = game[0] + won
game[4] = game[4] + 1
if won > 0:
game[5] = game[5] + 1
elif won < 0:
game[6] = game[6] + 1
else:
game[7] = game[7] + 1
print("Chips " + str(game[0]) + " after " + counted(game[4], "hand") + ": " + str(game[5]) + " won, " + str(game[6]) + " lost, " + str(game[7]) + " pushed.")
if game[0] == 0:
print("You are out of chips - start a new game to play on.")
def ask_bet(game):
while True:
answer = trim(input("bet (1 to " + str(game[0]) + ")> "))
if answer == "":
return -1
n = number(answer)
if n >= 1 and n <= game[0]:
return n
print("Type a bet from 1 to " + str(game[0]) + ".")
def play_hand(game):
if game[0] == 0:
print("You have no chips left - start a new game.")
return game
if len(game[2]) - game[3] < 15:
shuffle(game)
print("The deck is shuffled.")
bet = ask_bet(game)
if bet == -1:
print("Cancelled.")
return game
player = [draw(game)]
dealer = [draw(game)]
player = player + [draw(game)]
dealer = dealer + [draw(game)]
if cards.blackjack(player) or cards.blackjack(dealer):
table(player, dealer, False)
won = cards.natural_result(player, dealer, bet)
if won == 0:
print("Both have blackjack - a push, your bet comes back.")
elif won > 0:
print("Blackjack! You win " + str(won) + ".")
else:
print("The dealer has blackjack - you lose " + str(bet) + ".")
settle(game, won)
return game
table(player, dealer, True)
stake = bet
asking = True
while asking and cards.value(player)[0] < 21:
can_double = len(player) == 2 and game[0] >= bet * 2
if can_double:
action = trim(input("h) hit s) stand d) double> "))
else:
action = trim(input("h) hit s) stand> "))
if action == "h":
card = draw(game)
player = player + [card]
print("You draw " + cards.name(card) + ": " + cards.shown(player, False) + " - " + cards.described(player))
elif action == "s":
asking = False
elif action == "d" and can_double:
stake = bet * 2
card = draw(game)
player = player + [card]
print("You double to " + str(stake) + " and draw " + cards.name(card) + ": " + cards.shown(player, False) + " - " + cards.described(player))
asking = False
elif can_double:
print("Type h to take a card, s to stay, or d to double your bet for one card.")
else:
print("Type h to take a card or s to stay.")
if cards.value(player)[0] > 21:
print("Bust - you lose " + str(stake) + ".")
settle(game, 0 - stake)
return game
print("The dealer turns over " + cards.name(dealer[1]) + ": " + cards.shown(dealer, False) + " - " + cards.described(dealer))
while not cards.dealer_stands(dealer):
card = draw(game)
dealer = dealer + [card]
print("The dealer draws " + cards.name(card) + ": " + cards.shown(dealer, False) + " - " + cards.described(dealer))
won = cards.result(player, dealer, stake)
p = cards.value(player)[0]
d = cards.value(dealer)[0]
if d > 21:
print("The dealer busts - you win " + str(won) + ".")
elif won > 0:
print("You win " + str(won) + ", " + str(p) + " against " + str(d) + ".")
elif won < 0:
print("The dealer wins, " + str(d) + " against " + str(p) + " - you lose " + str(stake) + ".")
else:
print("A push at " + str(p) + " - your bet comes back.")
settle(game, won)
return game
def ask_number(prompt, low, high):
while True:
answer = trim(input(prompt + " (" + str(low) + " to " + str(high) + ")> "))
if answer == "":
return -1
n = number(answer)
if n >= low and n <= high:
return n
print("Type a number from " + str(low) + " to " + str(high) + ".")
def new_game(game):
chips = ask_number("chips", 10, 1000)
if chips == -1:
print("Cancelled.")
return game
seed = ask_number("seed", 0, 999999999)
if seed == -1:
print("Cancelled.")
return game
return start(chips, seed)
print("== Blackjack ==")
print("Get closer to 21 than the dealer without going over. The dealer draws to 16 and stands on 17.")
game = start(100, 2026)
running = True
while running:
print("")
print("1) play a hand 2) new game 3) quit")
choice = trim(input("choice> "))
if choice == "1":
game = play_hand(game)
elif choice == "2":
game = new_game(game)
elif choice == "3":
running = False
else:
print("Pick a number from 1 to 3.")
print("Bye.")
cards.eml
eml# P049 blackjack - cards, the deck and the hands. A card is [rank, suit]:
# rank 1 (ace) to 13 (king), suit 0 to 3 (spades, hearts, diamonds, clubs).
def new_deck():
[] => deck
for s in [0:3]:
for r in [1:13]:
deck + [[r, s]] => deck
return deck
def shuffled(deck, rng):
# Fisher-Yates, from the last position down: the card for position i is
# picked from positions 0 to i, so every order is equally likely - and a
# card may stay where it was. A uniform shuffle leaves one card in place
# on average, as the corpus case the-shuffle-left-one-in-place-as-expected
# works out; forbidding that would make the shuffle less random, not more.
deck[0:len(deck)] => d
len(d) => n
for k in [0:n - 2]:
n - 1 - k => i
rng.below(i + 1) => j
d[i] => t
d[j] => d[i]
t => d[j]
return d
def name(card):
str(card[0]) => rank
if card[0] == 1:
"A" => rank
elif card[0] == 11:
"J" => rank
elif card[0] == 12:
"Q" => rank
elif card[0] == 13:
"K" => rank
return rank + "SHDC"[card[1]]
def points(card):
# An ace is 1 here; value() decides when it counts 11.
if card[0] > 10:
return 10
return card[0]
def value(hand):
# [total, soft]. Aces count 1, and one of them counts 11 when that does
# not take the hand over 21 - the hand is then soft. Two aces at 11 would
# be 22, so at most one ever counts 11.
0 => total
False => ace
for card in hand:
total + points(card) => total
if card[0] == 1:
True => ace
if ace and total + 10 <= 21:
return [total + 10, True]
return [total, False]
def blackjack(hand):
# 21 with the first two cards: an ace and a ten, jack, queen or king.
return len(hand) == 2 and value(hand)[0] == 21
def shown(hand, hide_second):
"" => s
for k in [0:len(hand) - 1]:
if k > 0:
s + " " => s
if k == 1 and hide_second:
s + "??" => s
else:
s + name(hand[k]) => s
return s
def described(hand):
value(hand) => v
if v[0] > 21:
return str(v[0]) + ", bust"
if blackjack(hand):
return "blackjack"
if v[1]:
return "soft " + str(v[0])
return str(v[0])
def dealer_stands(hand):
# The dealer draws to 16 and stands on every 17, a soft 17 too.
return value(hand)[0] >= 17
def natural_result(player, dealer, bet):
# When either first hand is a blackjack the hand ends at once: both is a
# push, the player's alone pays 3 to 2 (rounded down), the dealer's alone
# takes the bet. Returns the chips won, negative for a loss.
if blackjack(player) and blackjack(dealer):
return 0
if blackjack(player):
return int(bet * 3 / 2)
return 0 - bet
def result(player, dealer, stake):
# Both hands finished, neither a blackjack: the chips won, negative for
# a loss. A player who busts loses even if the dealer would bust too -
# the dealer does not play then.
value(player)[0] => p
value(dealer)[0] => d
if p > 21:
return 0 - stake
if d > 21 or p > d:
return stake
if p < d:
return 0 - stake
return 0
Python projection (cards.py)
def new_deck():
deck = []
for s in range(0, 4):
for r in range(1, 14):
deck = deck + [[r, s]]
return deck
def shuffled(deck, rng):
d = deck[0:len(deck)]
n = len(d)
for k in range(0, n - 2+1):
i = n - 1 - k
j = rng.below(i + 1)
t = d[i]
d[i] = d[j]
d[j] = t
return d
def name(card):
rank = str(card[0])
if card[0] == 1:
rank = "A"
elif card[0] == 11:
rank = "J"
elif card[0] == 12:
rank = "Q"
elif card[0] == 13:
rank = "K"
return rank + "SHDC"[card[1]]
def points(card):
if card[0] > 10:
return 10
return card[0]
def value(hand):
total = 0
ace = False
for card in hand:
total = total + points(card)
if card[0] == 1:
ace = True
if ace and total + 10 <= 21:
return [total + 10, True]
return [total, False]
def blackjack(hand):
return len(hand) == 2 and value(hand)[0] == 21
def shown(hand, hide_second):
s = ""
for k in range(0, len(hand)):
if k > 0:
s = s + " "
if k == 1 and hide_second:
s = s + "??"
else:
s = s + name(hand[k])
return s
def described(hand):
v = value(hand)
if v[0] > 21:
return str(v[0]) + ", bust"
if blackjack(hand):
return "blackjack"
if v[1]:
return "soft " + str(v[0])
return str(v[0])
def dealer_stands(hand):
return value(hand)[0] >= 17
def natural_result(player, dealer, bet):
if blackjack(player) and blackjack(dealer):
return 0
if blackjack(player):
return int(bet * 3 / 2)
return 0 - bet
def result(player, dealer, stake):
p = value(player)[0]
d = value(dealer)[0]
if p > 21:
return 0 - stake
if d > 21 or p > d:
return stake
if p < d:
return 0 - stake
return 0
rng.eml
eml# P049 blackjack - random numbers written in EML: the linear congruential
# generator of P008 (number guessing), with the constants of the C
# standard's example rand(). Python's random module is not used, so a seed
# gives the same shuffle on every machine, and the interpreter can check a
# whole session byte for byte.
class Rng:
def __init__(self, seed):
seed % 2147483648 => self.state
def step(self):
(1103515245 * self.state + 12345) % 2147483648 => self.state
return self.state
def below(self, n):
# A number from 0 to n - 1, taken from the high bits of the state: the
# low bits of this generator repeat with short periods. Dividing by
# 65536 is exact in a float for a state below 2^31.
return int(self.step() / 65536) % n
Python projection (rng.py)
class Rng:
def __init__(self, seed):
self.state = seed % 2147483648
def step(self):
self.state = (1103515245 * self.state + 12345) % 2147483648
return self.state
def below(self, n):
return int(self.step() / 65536) % n