This time, I would like to implement Dragon Quest poker using the deck in Previous article.
Normal poker is basically played between players,
For this reason, it ’s not poker between players, I would like to implement a one-person game like Dragon Quest poker.
Make a role in poker → Double your score in a double-up game That is the basic flow.
Role name | Card status | Example of hand | Score |
---|---|---|---|
1 pair | One pair of the same number | [♣️-4, ♠︎-4, ♦︎-Q, ♠︎-K, ❤︎-5] | 50 |
2 pairs | Two pairs of the same number | [♣️-4, ♠︎-4, ♦︎-Q, ♠︎-Q, ❤︎-5] | 100 |
3 cards | 3 same numbers | [♣️-4, ♠︎-4, ♦︎-4, ♠︎-Q, ❤︎-5] | 200 |
straight | The numbers are continuous | [♣️-3, ♠︎-4, ♦︎-5, ♠︎-6, ❤︎-7] | 300 |
flash | All marks are the same | [♠︎-3, ♠︎-4, ♠︎-5, ♠︎-Q, ♠︎-9] | 400 |
Full house | 3 same numbers+1 pair | [♠︎-3, ♠︎-4, ♠︎-5, ♠︎-Q, ♠︎-9] | 500 |
Four Cards | 4 same numbers | [♠︎-4, ♦︎-4, ♠︎-4, ♣️-4, ❤︎-9] | 1000 |
Straight flush | Flash and straight | [♠︎-4, ♠︎-5, ♠︎-6, ♠︎-7, ♠︎-8] | 2000 |
Royal straight flush | Flash and straight | [♠︎-10, ♠︎-J, ♠︎-Q, ♠︎-K, ♠︎-A] | 10000 |
We have prepared the following classes. I think there are other good ways. ..
I used the one created in this article as it is.
class Player:
"""
Player Score / Hand / Poker Victory Flag
"""
def __init__(self):
self.score = 0
self.hands = []
self.is_poker_win = True
def draw_card(self, deck, num=1):
"""
Draw a card from the deck and add it to your hand
* Even if different numbers are drawn, it is ok
Parameters
----------
num : int, default 1
Number of times to draw a card
Examples
--------
>>> player.draw_card(2) #2 draws[♠︎-J, ♠︎-10]
>>> player.draw_card(3) # [♦︎-9, ♣️-10, ♠︎-2]
>>> print(player.hands)
[♠︎-J, ♠︎-10, ♦︎-9, ♣️-10, ♠︎-2]
"""
self.hands_store = deck.pick_card(num)
self.hands.extend(self.hands_store)
class Game:
"""
Main game
Examples
--------
>>> game = Game()
>>> game.main() #Game start (displays the initial phase below)
"""
RANKS = (*"23456789", "10", *"JQKA")
VALUES = (range(2, 14 + 1))
#Associate the display mark with the score
RANK_TO_VALUES = dict(zip(RANKS, VALUES))
def main(self):
"""
The whole game (poker)+Double up chance)
"""
can_play_game = True
while can_play_game:
#Reset player information for each game
player = Player()
#Deck set (determine the number of sets)=Rebuild the deck for each game
deck = stock.Deck()
poker = Poker(deck, player)
poker.main_game()
#Double up chance with a role
print(player.is_poker_win)
if player.is_poker_win:
bonus_game = DoubleUp(player)
bonus_game.main_game()
#Game restart
restart_msg = "End the game with Q, start the game otherwise:"
start_res = input(restart_msg)
if start_res == 'Q':
can_play_game = False
if __name__ == '__main__':
game = Game()
game.main()
The flow chart below shows the combination judgment.
class Poker:
RANKS = (*"23456789", "10", *"JQKA")
VALUES = (range(2, 14 + 1))
#Associate the display mark with the score
RANK_TO_VALUES = dict(zip(RANKS, VALUES))
def __init__(self, deck, player):
self.deck = deck
self.player = player
def change_hands(self, player_hands):
"""
Let them exchange cards one by one and return the exchanged hand
Parameters
----------
player_hands : list
Player deck before card exchange
Returns
--------
changed_hands : list
Player deck after card exchange
"""
changed_hands = []
#Select either "Rubbing" or "Frog" for each card
print("Enter \"y\" to replace the card.")
for card_idx, change_card in enumerate(player_hands):
change_card_msg = f"{change_card}:"
change_card_res = input(change_card_msg)
#If you want to change it, draw from the deck and exchange the card
if change_card_res == "y":
#Draw from the deck and overwrite
change_card = self.deck.pick_card(1)[0]
self.player.hands[card_idx] = change_card
#Added to associative array
check_card_set = str(change_card).split("-")
# ❤︎
card_mark = check_card_set[0]
# K
card_rank = check_card_set[1]
# 13
card_number = self.RANK_TO_VALUES[card_rank]
#Add to check dictionary
changed_hands.append({
"mark": card_mark,
"rank": card_rank,
"number": card_number
})
return changed_hands
def calc_hand(self, check_hands):
"""
Calculation of roles from hand
Parameters
----------
check_hands : list
Player deck after card exchange
Returns
--------
hand_results : dict
The state of each role in the player's deck
"""
#Flash (same mark)
is_flash = True
#Straight (numbers are serial numbers)
is_straight = True
#Count of the same number
same_number_count = 0
same_number = 0
#Number of pairs (1 pair or 2 pairs)
match_pair_count = 0
#Sort from hand to card number in ascending order
check_hands_sorted = sorted(check_hands, key=lambda x: x["number"])
#Check one by one from 5 cards
for check_idx, check_card in enumerate(check_hands_sorted):
#Skip the first card because there is no previous card
if check_idx == 0:
continue
#Previous card{'mark': '♠︎', 'rank': '4', 'number': 4}
prev_card = check_hands_sorted[check_idx - 1]
#If the front and back marks are different, set the flash judgment to False.
if is_flash and check_card["mark"] != prev_card["mark"]:
is_flash = False
#If the numbers are not consecutive before and after, set the straight judgment to False.
if is_straight and check_card["number"] != prev_card["number"] + 1:
is_straight = False
#If the numbers match before and after, count the same number+1
if check_card["number"] == prev_card["number"]:
#Number of matches+ 1
same_number_count += 1
#Last card
if check_idx == 4:
if same_number_count == 1:
#Number of pairs+ 1
match_pair_count += 1
else:
#3 cards and 4 cards
same_number = same_number_count + 1
#For different numbers
else:
if same_number_count == 1:
#Number of pairs+ 1
match_pair_count += 1
elif same_number_count > 1:
#3 cards and 4 cards
same_number = same_number_count + 1
#Reset because it is a different number
same_number_count = 0
#State of each role in the hand
hand_results = {
"is_flash": is_flash,
"is_straight": is_straight,
"same_number_count": same_number_count,
"same_number": same_number,
"match_pair_count": match_pair_count
}
return hand_results
def showdown_hand(self, hand_status, check_hands):
"""
Determining the role from the state of the role, score calculation
Parameters
----------
hand_status : dict
The state of the player's role after exchanging cards
check_hands : list
player's hand
Returns
--------
hand_result_msg : str
Judgment sentence of the role
"""
#result
hand_result_msg = ""
#Flash and straight
if hand_status["is_flash"] and hand_status["is_straight"]:
#The smallest card is 10,The largest card is 14(A)
if check_hands[0]["number"] == 10 and \
check_hands[4]["number"] == 14:
hand_result_msg = "Royal straight flush"
self.player.score = 10000
else:
hand_result_msg = "Straight flush"
self.player.score = 2000
#4 cards
elif hand_status["same_number"] == 4:
hand_result_msg = "4 cards"
self.player.score = 1000
#3 cards,Full house judgment
elif hand_status["same_number"] == 3:
#3 cards and 1 pair
if hand_status["match_pair_count"] == 1:
hand_result_msg = "Full house"
self.player.score = 500
else:
hand_result_msg = "3 cards"
self.player.score = 250
#flash
elif hand_status["is_flash"]:
hand_result_msg = "flash"
self.player.score = 400
#straight
elif hand_status["is_straight"]:
hand_result_msg = "straight"
self.player.score = 300
#2 pairs
elif hand_status["match_pair_count"] == 2:
hand_result_msg = "2 pairs"
self.player.score = 200
#1 pair
elif hand_status["match_pair_count"] == 1:
hand_result_msg = "1 pair"
self.player.score = 150
return hand_result_msg
def main_game(self):
"""
Main game of poker
"""
print("Poker Game start")
#First draw 5 cards
self.player.draw_card(self.deck, 5)
#Initial card display
print(f"player's hands:{self.player.hands}")
#Card exchange phase
check_hands = self.change_hands(self.player.hands)
#Card display after exchange
print(f"player's hands:{self.player.hands}")
#Sort in ascending order based on the numbers in your hand
check_hands_sorted = sorted(check_hands, key=lambda x: x["number"])
#Calculation of roles from hand
hand_results = self.calc_hand(check_hands_sorted)
print(hand_results)
#Role judgment
hand_result_msg = self.showdown_hand(hand_results, check_hands_sorted)
#Lose if there is nothing
if hand_result_msg == "":
hand_result_msg = "There was no role..."
self.player.is_poker_win = False
#Result output
print(hand_result_msg)
import re
from deck import stock
class DoubleUp:
RANKS = (*"23456789", "10", *"JQKA")
VALUES = (range(2, 14 + 1))
#Associate the display mark with the score
RANK_TO_VALUES = dict(zip(RANKS, VALUES))
def __init__(self, player):
self.player = player
self.is_game_win = True
def add_check_hands(self, player_hands):
"""
Display cards one by one and assign numbers
Parameters
----------
player_hands : list
5 cards in hand
Returns
--------
check_hands : list
player's hand
"""
check_hands = []
for card_idx, card_val in enumerate(player_hands):
#Added to associative array
check_card_set = str(card_val).split("-")
# ❤︎
card_mark = check_card_set[0]
# K
card_rank = check_card_set[1]
# 13
card_number = self.RANK_TO_VALUES[card_rank]
#Add to check dictionary
check_hands.append({
"mark": card_mark,
"rank": card_rank,
"number": card_number
})
#The first cannot be selected
if card_idx >= 1:
#hide
# print(f"{card_idx}:*-*")
print(f"{card_idx}:{card_val}")
return check_hands
def win_judge_selected_card(self, input_res, check_hands):
"""
Game Victory Judgment (Compare selected card with face-up card)
Parameters
----------
input_res : str
The number entered in the command
check_hands : list
player's hand
"""
if re.compile(r'^[1-4]+$').match(input_res) is not None:
#Comparison of the number size of the card with the selected number and the face-up card
if check_hands[int(input_res)]["number"] >= check_hands[0]["number"]:
#Double the score if it is large
print("win!")
self.player.score *= 2
else:
#If small,Score 0 and start again from poker
print("lose..")
self.player.score = 0
self.is_game_win = False
else:
print("Is useless")
def main_game(self):
"""
Double-up main game
"""
while self.is_game_win:
#Reconstruction of deck
self.deck = stock.Deck()
print("double-Up Chance Game start")
print(f"Now, your score is {self.player.score} points.")
self.player.hands = []
#Deal 5 cards from the deck
self.player.draw_card(self.deck, 5)
#1 out of 5 is set face up, 4 is face down
print(f"player's hands:{self.player.hands[0]}, *-*, *-*, *-*, *-*")
#Display cards one by one and assign numbers
check_hands = self.add_check_hands(self.player.hands)
#Choose one of the four face-down cards that is stronger than the number on the face-up card
card_select_msg = f"Enter a card number that is stronger than {self.player.hands[0]}:"
card_select_res = input(card_select_msg)
#Choose one from numbers 1 to 4
self.win_judge_selected_card(card_select_res, check_hands)
print(self.player.score)
$ python main.py
Poker Game start
player's hands:[❤︎-4, ♠︎-9, ♣️-4, ♠︎-3, ♠︎-2]
Enter "y" to replace the card.
❤︎-4:
♠︎-9: y
♣️-4:
♠︎-3: y
♠︎-2: y
player's hands:[❤︎-4, ❤︎-K, ♣️-4, ♠︎-K, ♣️-6]
2 pairs
double-Up Chance Game start
Now, your score is 100 points.
player's hands:♠︎-6, *-*, *-*, *-*, *-*
1:*-*
2:*-*
3:*-*
4:*-*
Enter a card number that is stronger than ♠︎-6: 2
Selected card is ❤︎-12
win!
200
double-Up Chance Game start
Now, your score is 200 points.
player's hands:♠︎-K, *-*, *-*, *-*, *-*
1:*-*
2:*-*
3:*-*
4:*-*
Enter a card number that is stronger than ♠︎-K: 3
Selected card is ♦︎-2
lose..
0
End the game with Q, start the game otherwise: Q
Recommended Posts