See Qiita article I tried to write it.
The basic functionality was easily made into code, but I'm wondering how to design it to expand the functionality.
# code summary
class Card
class Deck
class Player:
def deal ()
class Dealer (Player):
def deal ()
def blackjack ():
# initialize deck, player, dealer
# player.deal ()
# dealer.deal ()
# showdown
def confirm ()
def main ():
while True:
blackjack ()
confirm ()
Assuming a one-to-one player vs dealer,
initial deal
->player action
->dealer action
->showdown
code>initial dealandshowdown
are inblackjack ()
, and the other two are in each classdeal ()
is implemented.
Also,confirm ()
outside the class is called to confirm with the player whether to draw another card withplayer.deal ()
.
Considering the expansion of rules, the addition of players, and the use of each class for other playing card games, features specific to blackjack can be accessed fromPlayer
,Dealer
I think it should be divided.
I'm worried about whether I should describe all processing in the function ofblackjack ()
, or prepare a newBlackjack
class. Is it better to divide the processing in detail?
I have heard that processing within functions should fit within 30-40 lines.
If processing is complex, I would appreciate any advice on how to choose a function, class, or other form of implementation.
# Full code
# blackjack.py
from random import shuffle
class Card:
suits = ["H", "D", "S", "C"]
numbers = [i for i in range (1, 14)]
cards_converter = {** {i: i for i in range (2, 11)},
** {1: "A", 11: "J", 12: "Q", 13: "K"}}
def __init __ (self, suit, number):
self.suit = suit
self.number = number
def __repr __ (self):
return f "{self.suit}-{self.cards_converter [self.number]}"
class Deck (list):def __init __ (self):
super () .__ init __ (Card (suit, num) for suit in Card.suits for num in Card.numbers)
shuffle (self)
class Player:
def __init __ (self, deck: "Deck"):
self.deck = deck
self.hands = []
self._initial_deal ()
def __repr __ (self):
return f "{self .__ class __.__ name__}: {self.score} pts/{self.hands}"
def _initial_deal (self)->None:
for _ in range (2):
self.draw ()
print (self)
def draw (self)->int:
card = self.deck.pop ()
self.hands.append (card)
return self.score
def deal (self)->bool:
while confirm ("Keep drawing a card?"):
score = self.draw ()
print (self)
if score == 21:
print ("<You win!>\ n")
return False
elif score>21:
print ("<You lose ...>\ n")
return False
print_line ()
return True
@property
def score (self)->int:
# count royal cards as 10
score = sum (min (card.number, 10) for card in self.hands)
# exception of ace
if score<= 11 and 1 in {card.number for card in self.hands}:
score + = 10
return score
class Dealer (Player):
def _initial_deal (self)->None:
self.draw ()
print (self)self.draw () # hide the second hand
def deal (self)->bool:
while self.score<17:
self.draw ()
if self.score>21:
print (self)
print ("<You win!>\ n") # dealer loses, and player wins
return False
print_line ()
return True
def blackjack ()->None:
# initialize/initial deal
deck = Deck ()
player = Player (deck)
if player.score == 21:
print ("<You win!>\ n")
return
dealer = Dealer (deck)
# showdown
if player.deal () and dealer.deal ():
print (player, dealer, sep = "\ n")
if player.score == dealer.score:
print ("<Draw>\ n")
elif player.score>dealer.score:
print ("<You win!>\ n")
else:
print ("<You lose ...>\ n")
print_line ()
def confirm (message: str)->bool:
return input (f "{message} [y/n]"). lower () [0] == "y"
def print_line (length: int = 55)->None:
print ("-" * length)
def main ():
blackjack ()
while confirm ("Play again?"):
print_line ()
blackjack ()
if __name__ == "__main__":
main ()
-
Answer # 1
Related articles
- python - i want to add an article category sorting function on the django blog
- python 3x - i want to shorten the python function
- how to add python built-in class method
- python - yolo i want to detect only a specific class
- python - cannot inherit a class with multiple arguments
- python - i want to get rid of the error that the function is defined but not defined
- python - i'm looking for a method like the countif function in excel for pywin32
- python - i want to know the type of softmax function in pytorch
- python - pass a variable to the websocket on_message function
- python - arguments are passed even though the function inside the function is not in parentheses
- error in callback function in php class
- i want to create a function in python that all functions without class go through
- python - i want to create a function that finds the standard deviation sigma from x, y
- python - out of range of predict function used in image recognition (?)
- python - array elements cannot be used as function arguments ??
- i don't know the basic usage of the python generator function
- i want to create a function that calculates the absolute value in python
- python - excel function can be taken with get_as_dataframe
- python 3x - how to use python class
- optimal description of python def function
It ’s a masterpiece.
However, while being well-developed, there are places where it feels a little difficult to read.
A mix of game progression logic and player behavior
・ Particularly concerned about the dispersion ofwin/loss determination
In terms of the above points, solzard has already noticed in a different way.
Think about separation of playersRethinkplayer rolein separating players from the game itself.
What is the common behavior of players in a card game?
I thought as follows.
Draw cards from a given deck according to certain judgments
Put/Discard your hand according to certain judgment
Report your score according to specific judgment
If you can separate "specific judgment", you can use the player class for other games.
This is the so-called Strategy pattern.
You can ask for the user's judgment by calling it as follows:
You can make a computer like this.
However, since you will be peeking into the user's hand from an external function,
Think about separation of winning and losing decisionsIf you are worried about it, you can create a dedicated blackjack player class.
Score calculation is highly game dependent, so it should be separated from the player class.
As before, you should receive a function object for calculation from the outside.
The player only declares the score, and the caller is responsible for the decision.
CallerIf it is troublesome to do the score calculation method every time, it will be passed together at the time of instantiation.
Looks like this:
I'm writing with my imagination, so I think it needs to be adjusted a little more.
For example, we do not consider betting implementation.
I personally think that functions are enough.
I don't feel the need to inherit or create multiple instances.
However, if you want to implement another game, you should separate the modules.