Remove tests and alternative Python implementations

Ad discussed here:
https://github.com/coding-horror/basic-computer-games/issues/548#issuecomment-1081008471
This commit is contained in:
Martin Thoma
2022-03-29 06:56:06 +02:00
parent 6f9cb1bac2
commit 17a75813b1
32 changed files with 1 additions and 2352 deletions

View File

@@ -1,136 +0,0 @@
"""
AceyDuchy
From: BASIC Computer Games (1978)
Edited by David Ahl
"The original BASIC program author was Bill Palmby
of Prairie View, Illinois."
Python port by Aviyam Fischer, 2022
"""
from typing import List, Literal, TypeAlias, get_args
Suit: TypeAlias = Literal["\u2665", "\u2666", "\u2663", "\u2660"]
Rank: TypeAlias = Literal[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
class Card:
def __init__(self, suit: Suit, rank: Rank) -> None:
self.suit = suit
self.rank = rank
def __str__(self) -> str:
r = str(self.rank)
r = {"11": "J", "12": "Q", "13": "K", "14": "A"}.get(r, r)
return f"{r}{self.suit}"
class Deck:
def __init__(self) -> None:
self.cards: List[Card] = []
self.build()
def build(self) -> None:
for suit in get_args(Suit):
for rank in get_args(Rank):
self.cards.append(Card(suit, rank))
def shuffle(self) -> None:
import random
random.shuffle(self.cards)
def deal(self) -> Card:
return self.cards.pop()
class Game:
def __init__(self) -> None:
self.deck = Deck()
self.deck.shuffle()
self.card_a = self.deck.deal()
self.card_b = self.deck.deal()
self.money = 100
self.not_done = True
def play(self) -> None:
while self.not_done:
while self.money > 0:
card_a = self.card_a
card_b = self.card_b
if card_a.rank > card_b.rank:
card_a, card_b = card_b, card_a
if card_a.rank == card_b.rank:
self.card_b = self.deck.deal()
card_b = self.card_b
print(f"You have:\t ${self.money} ")
print(f"Your cards:\t {card_a} {card_b}")
bet = int(input("What is your bet? "))
player_card = self.deck.deal()
if 0 < bet <= self.money:
print(f"Your deal:\t {player_card}")
if card_a.rank < player_card.rank < card_b.rank:
print("You Win!")
self.money += bet
else:
print("You Lose!")
self.money -= bet
self.not_done = False
else:
print("Chicken!")
print(f"Your deal should have been: {player_card}")
if card_a.rank < player_card.rank < card_b.rank:
print("You could have won!")
else:
print("You would lose, so it was wise of you to chicken out!")
self.not_done = False
break
if len(self.deck.cards) <= 3:
print("You ran out of cards. Game over.")
self.not_done = False
break
self.card_a = self.deck.deal()
self.card_b = self.deck.deal()
if self.money == 0:
self.not_done = False
def game_loop() -> None:
game_over = False
while not game_over:
game = Game()
game.play()
print(f"You have ${game.money} left")
print("Would you like to play again? (y/n)")
if input() == "n":
game_over = True
def main():
print(
"""
Acey Ducey is a card game where you play against the computer.
The Dealer(computer) will deal two cards facing up.
You have an option to bet or not bet depending on whether or not you
feel the card will have a value between the first two.
If you do not want to bet input a 0
"""
)
game_loop()
print("\nThanks for playing!")
if __name__ == "__main__":
main()

View File

@@ -1,212 +0,0 @@
"""aceyducey.py contains game code"""
########################################################
#
# Acey Ducey
#
# From: BASIC Computer Games (1978)
# Edited by David Ahl
#
# "This is a simulation of the Acey Ducey card game.
# In the game, the dealer (the computer) deals two
# cards face up. You have an option to bet or not to
# bet depending on whether or not you feel the next
# card dealt will have a value between the first two.
#
# "Your initial money is set to $100. The game keeps
# going on until you lose all your money or interrupt
# the program.
#
# "The original BASIC program author was Bill Palmby
# of Prairie View, Illinois."
#
# Python port by Jeff Jetton, 2019
#
########################################################
import random
# "You may alter [the following statement] if you want
# to start with more or less than $100."
DEFAULT_BANKROLL = 100
def deal_card_num() -> int:
"""Get card number"""
return random.randint(0, 12)
def get_card_name(number: int) -> str:
"""Get card name"""
card_names = (
" 2",
" 3",
" 4",
" 5",
" 6",
" 7",
" 8",
" 9",
" 10",
"Jack",
"Queen",
"King",
"Ace",
)
return card_names[number]
def display_bankroll(bank_roll: int) -> None:
"""Print current bankroll"""
if bank_roll > 0:
print(f"You now have {bank_roll} dollars\n")
def main() -> None:
"""Display initial title and instructions."""
print("\n Acey Ducey Card Game")
print("Creative Computing Morristown, New Jersey")
print("\n\n")
print("Acey-Ducey is played in the following manner")
print("The dealer (computer) deals two cards face up")
print("You have an option to bet or not bet depending")
print("on whether or not you feel the card will have")
print("a value between the first two.")
print("If you do not want to bet, input a 0")
multiple_game_loop()
print("OK Hope you had fun\n")
def multiple_game_loop() -> None:
"""Loop for series of multiple games."""
keep_playing = True
while keep_playing:
# Initialize bankroll at start of each game
BANK_ROLL = DEFAULT_BANKROLL
display_bankroll(BANK_ROLL)
single_round(BANK_ROLL)
print("\n\nSorry, friend but you blew your wad")
player_response = input("Try again (yes or no) ")
if player_response.lower() == "yes":
print()
else:
keep_playing = False
def single_round(BANK_ROLL: int) -> None:
"""Loop for a single round. Repeat until out of money."""
while BANK_ROLL > 0:
# Deal out dealer cards
print("Here are your next two cards")
dealer1 = deal_card_num()
# If the cards match, we redeal 2nd card until they don't
dealer2 = dealer1
while dealer1 == dealer2:
dealer2 = deal_card_num()
# Organize the cards in order if they're not already
if dealer1 >= dealer2:
(dealer1, dealer2) = (dealer2, dealer1) # Ya gotta love Python!
# Show dealer cards to the player
# (use card name rather than internal number)
print(get_card_name(dealer1))
print(get_card_name(dealer2) + "\n")
# Get and handle player bet choice
BET_IS_VALID = False
while not BET_IS_VALID:
curr_bet_str = input("What is your bet? ")
try:
curr_bet = int(curr_bet_str)
except ValueError:
# Bad input? Just loop back up and ask again...
pass
else:
if curr_bet == 0:
BET_IS_VALID = True
print("Chicken!!\n")
elif curr_bet > BANK_ROLL:
print("Sorry, my friend but you bet too much")
print(f"You have only {BANK_ROLL} dollars to bet\n")
else:
# Deal player card
BET_IS_VALID = True
player = deal_card_num()
print(get_card_name(player))
# Did we win?
if dealer1 < player < dealer2:
print("You win!!!")
BANK_ROLL += curr_bet
else:
print("Sorry, you lose")
BANK_ROLL -= curr_bet
# Update player on new bankroll level
display_bankroll(BANK_ROLL)
if __name__ == "__main__":
main()
########################################################
#
# Porting notes:
#
# The original BASIC version had a variable named N
# that was initialized to 100 and then never used.
# Maybe it did something in feature that was edited
# out of the final version used in the book?
#
# The original program simply generated random numbers
# for each card. It did not simulate a true card deck,
# where the dealing of a card eliminates it from the
# deck and reduces the chances of the same value
# being drawn. This "infinite deck" logic (or "deal,
# with replacement after") has NOT been changed.
#
# In the interests of historical fidelity, the bug
# in the original BASIC listing that let you input a
# negative bet value has been faithfully reproduced.
# This lets the player lose money when they win and
# earn money when they lose! :-)
#
#
# Ideas for Modifications
#
# Give the user the ability to quit the game, perhaps
# by typing "quit" instead of making a bet. Provide a
# final assessment based on how much of the original
# bankroll they have left.
#
# Or have the game run for a set number of rounds or
# until a certain bankroll goal is attained.
#
# Implement an "ante"--a set amount the player has to
# bet each time rather than having the option to lay
# out entirely.
#
# See "porting notes" above about negative bet values.
# How would you fix this?
#
# When the player "chickens out", show them what the
# next card would've been and point out whether they
# made a good or bad decision.
#
# In what situations are the odds of winning high
# enough to justify making a bet? Create a cheat mode
# where the program identifies these situations and
# lets the player know.
#
# Change the card dealing to simulate deals from a
# single deck (or a user-selectable number of decks).
#
# Implement a two-player mode where players take turns
# betting (or both bet on the same dealer cards and
# get their own player card dealt).
#
########################################################

View File

@@ -1,29 +0,0 @@
import io
from unittest import mock
from typing import TypeVar
from _pytest.capture import CaptureFixture
from _pytest.monkeypatch import MonkeyPatch
from acey_ducey import play_game
@mock.patch("random.shuffle")
def test_play_game_lose(
mock_random_shuffle, monkeypatch: MonkeyPatch, capsys: CaptureFixture
) -> None:
monkeypatch.setattr("sys.stdin", io.StringIO("100\n100"))
T = TypeVar("T")
def identity(x: T) -> T:
return x
mock_random_shuffle = identity # noqa: F841
play_game()
captured = capsys.readouterr()
assert captured.out == (
"You now have 100 dollars\n\n"
"Here are you next two cards\n King\n Ace\n\n"
"What is your bet? Queen\n"
"Sorry, you lose\n"
"Sorry, friend, but you blew your wad\n"
)

View File

@@ -1,36 +0,0 @@
from acey_ducey_oo import Card, Deck, Game
def test_card_init() -> None:
card = Card("\u2665", 2)
assert card.suit == "\u2665"
assert card.rank == 2
def test_card_str() -> None:
card = Card("\u2665", 2)
assert str(card) == "2\u2665"
def test_deck_init() -> None:
deck = Deck()
assert len(deck.cards) == 52
assert deck.cards[0].suit == "\u2665"
assert deck.cards[0].rank == 2
def test_deck_shuffle() -> None:
deck = Deck()
deck.shuffle()
def test_deck_deal() -> None:
deck = Deck()
card = deck.deal()
assert card.rank == 14
assert card.suit == "\u2660"
def test_game_init() -> None:
game = Game()
assert len(game.deck.cards) == 50 # two are already dealt