Compare commits
No commits in common. "master" and "zaklady" have entirely different histories.
@ -1,376 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# In[1]:
|
||||
|
||||
|
||||
from simpful import *
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
# ## Sterownik 1 - Decyzja o udziale w grze
|
||||
# ##### Dane wejściowe:
|
||||
# - Wartość żetonów
|
||||
# - Liczba przegranych z rzędu
|
||||
#
|
||||
# ##### Dane wyjściowe:
|
||||
# - Decyzja dot. udziału w grze
|
||||
|
||||
# In[27]:
|
||||
|
||||
|
||||
def getStartDecision(chipVal, lossNum):
|
||||
"""
|
||||
Args:
|
||||
chipVal (int): current value of the player's chips
|
||||
lossNum (int): number of losses in a row
|
||||
Returns:
|
||||
str: decision
|
||||
"""
|
||||
|
||||
FS = FuzzySystem(show_banner=False)
|
||||
|
||||
FS.add_linguistic_variable("chipValue", AutoTriangle(3, terms=['low', 'average', 'high'], universe_of_discourse=[0, 10]))
|
||||
FS.add_linguistic_variable("numLossInRow", AutoTriangle(3, terms=['low', 'average', 'high'], universe_of_discourse=[0, 10]))
|
||||
|
||||
O1 = TriangleFuzzySet(0,0,13, term="surrender")
|
||||
O2 = TriangleFuzzySet(0,13,25, term="hit")
|
||||
O3 = TriangleFuzzySet(13,15,17, term="double_down")
|
||||
O4 = TriangleFuzzySet(16,21,21, term="stand")
|
||||
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3, O4], universe_of_discourse=[0, 25]))
|
||||
|
||||
FS.add_rules([
|
||||
"IF (numLossInRow IS average) AND (chipValue IS average) THEN (decision IS hit)",
|
||||
"IF (numLossInRow IS high) OR (chipValue IS low) THEN (decision IS surrender)",
|
||||
"IF (numLossInRow IS low) AND (chipValue IS average) THEN (decision IS double_down)",
|
||||
"IF chipValue IS high THEN decision IS stand"
|
||||
])
|
||||
|
||||
FS.set_variable("chipValue", chipVal)
|
||||
FS.set_variable("numLossInRow", lossNum)
|
||||
|
||||
result = FS.inference()
|
||||
decision_terms = [(i.get_term(), FS.get_fuzzy_set('decision', i.get_term()).get_value(result['decision'])) for i in FS.get_fuzzy_sets('decision')]
|
||||
endDecision = max(decision_terms, key=lambda item:item[1])[0]
|
||||
return endDecision
|
||||
|
||||
|
||||
# In[28]:
|
||||
|
||||
|
||||
getStartDecision(7, 7)
|
||||
|
||||
|
||||
# In[1]:
|
||||
|
||||
|
||||
# FS.plot_variable('chipValue')
|
||||
# FS.plot_variable('numLossInRow')
|
||||
# FS.plot_variable('decision')
|
||||
|
||||
|
||||
# ## Sterownik 2 - Decyzja o strategii w przypadku pary
|
||||
# ##### Dane wejściowe:
|
||||
# - Wartość widocznej karty krupiera
|
||||
# - Wartość kart gracza
|
||||
#
|
||||
# ##### Dane wyjściowe:
|
||||
# - Decyzja dot. akcji w grze
|
||||
|
||||
# In[12]:
|
||||
|
||||
|
||||
def getSplitDecision(dealerCard, playerCardsVal):
|
||||
"""
|
||||
Args:
|
||||
dealerCard (int): value of the dealer card
|
||||
playerCardsVal (int): sum of the player cards
|
||||
Returns:
|
||||
str: decision
|
||||
"""
|
||||
|
||||
FS = FuzzySystem(show_banner=False)
|
||||
|
||||
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
|
||||
FuzzySet([[0,1], [6,1], [7,0]], term='low'),
|
||||
FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
|
||||
FuzzySet([[7,0], [8,1]], term='very_high')
|
||||
], universe_of_discourse=[0, 11]))
|
||||
|
||||
FS.add_linguistic_variable('splitValue', LinguisticVariable([
|
||||
FuzzySet([[0,1], [2,1], [3,0], [9,0], [10,1]], term='high'),
|
||||
FuzzySet([[2,0], [3,1], [4.5,1], [5,0], [5.5,1], [9,1], [9,1], [10,0]], term='low'),
|
||||
], universe_of_discourse=[0, 20]))
|
||||
|
||||
|
||||
O1 = TriangleFuzzySet(0,0,15, term="continue")
|
||||
O2 = TriangleFuzzySet(11,25,25, term="split")
|
||||
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2], universe_of_discourse=[0, 25]))
|
||||
|
||||
FS.add_rules([
|
||||
"IF (splitValue IS high) THEN (decision IS split)",
|
||||
"IF (splitValue IS low) AND (dealerCardValue IS low) THEN (decision IS split)",
|
||||
"IF (splitValue IS low) AND (dealerCardValue IS high) THEN (decision IS continue)",
|
||||
"IF (splitValue IS low) AND (dealerCardValue IS very_high) THEN (decision IS continue)",
|
||||
])
|
||||
|
||||
FS.set_variable("dealerCardValue", dealerCard)
|
||||
FS.set_variable("splitValue", playerCardsVal)
|
||||
|
||||
result = FS.inference()
|
||||
decision_terms = [(i.get_term(), FS.get_fuzzy_set('decision', i.get_term()).get_value(result['decision'])) for i in FS.get_fuzzy_sets('decision')]
|
||||
endDecision = max(decision_terms, key=lambda item:item[1])[0]
|
||||
return endDecision
|
||||
|
||||
|
||||
|
||||
# In[7]:
|
||||
|
||||
|
||||
#FS.plot_variable('dealerCardValue')
|
||||
#FS.plot_variable('playerCardValue')
|
||||
#FS.plot_variable('decision')
|
||||
|
||||
|
||||
# ## Sterownik 3 - Decyzja jaką akcję podjąć (twarda ręka)
|
||||
# ##### Dane wejściowe:
|
||||
# - Wartość widocznej karty krupiera
|
||||
# - Suma kart gracza
|
||||
# - Liczba kart gracza
|
||||
#
|
||||
# ##### Dane wyjściowe:
|
||||
# - Decyzja dot. akcji w grze
|
||||
|
||||
# In[29]:
|
||||
|
||||
|
||||
def getHardHandDecision(dealerCard, playerCardsVal, playerCardsNum):
|
||||
"""
|
||||
Args:
|
||||
dealerCard (int): value of the dealer card
|
||||
playerCardsVal (int): sum of the players hand
|
||||
playerCardsNum (int): number of cards in players hadn
|
||||
Returns:
|
||||
str: decision
|
||||
"""
|
||||
|
||||
FS = FuzzySystem(show_banner=False)
|
||||
|
||||
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
|
||||
FuzzySet([[0,1], [6,1], [7,0]], term='low'),
|
||||
FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
|
||||
FuzzySet([[7,0], [8,1]], term='very_high')
|
||||
], universe_of_discourse=[0, 11]))
|
||||
|
||||
FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([
|
||||
FuzzySet([[0,1], [11,1], [12,0]], term='low'),
|
||||
FuzzySet([[11,0], [12,1], [16,1], [17, 0]], term='medium'),
|
||||
FuzzySet([[16,0], [17,1], [18,0]], term='high'),
|
||||
FuzzySet([[17,0], [18,1]], term='very_high')
|
||||
], universe_of_discourse=[0, 21]))
|
||||
|
||||
# FS.add_linguistic_variable('splitValue', LinguisticVariable([
|
||||
# FuzzySet([[0,1], [2,1], [3,0], [9,0], [10,1]], term='split_high'),
|
||||
# FuzzySet([[2,0], [3,1], [4.5,1], [5,0], [5.5,1], [9,1], [9,1], [10,0]], term='split_low'),
|
||||
# ], universe_of_discourse=[0, 20]))
|
||||
|
||||
FS.add_linguistic_variable('doubleValue', LinguisticVariable([
|
||||
FuzzySet([[7,0], [8,1], [9,1], [10,0]], term='low'),
|
||||
FuzzySet([[9,0], [10,1], [11,1], [12,0]], term='high'),
|
||||
], universe_of_discourse=[0, 21]))
|
||||
|
||||
|
||||
O1 = TriangleFuzzySet(0,0,13, term="double down")
|
||||
O2 = TriangleFuzzySet(0,13,25, term="hit")
|
||||
O3 = TriangleFuzzySet(13,25,25, term="stand")
|
||||
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25]))
|
||||
|
||||
|
||||
if playerCardsNum == 2: # gdy początek rozgrywki
|
||||
FS.add_rules([
|
||||
"IF (doubleValue IS high) THEN (decision IS double down)",
|
||||
"IF (doubleValue IS low) AND (dealerCardValue IS low) THEN (decision IS double down)",
|
||||
"IF (playerCardsValue IS low) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS very_high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS very_high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
])
|
||||
|
||||
else:
|
||||
FS.add_rules([
|
||||
"IF (playerCardsValue IS low) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS very_high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS very_high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
])
|
||||
|
||||
|
||||
FS.set_variable("dealerCardValue", dealerCard)
|
||||
FS.set_variable("playerCardsValue", playerCardsVal)
|
||||
FS.set_variable("doubleValue", playerCardsVal)
|
||||
|
||||
result = FS.inference()
|
||||
decision_terms = [(i.get_term(), FS.get_fuzzy_set('decision', i.get_term()).get_value(result['decision'])) for i in FS.get_fuzzy_sets('decision')]
|
||||
endDecision = max(decision_terms, key=lambda item:item[1])[0]
|
||||
|
||||
return endDecision
|
||||
|
||||
|
||||
|
||||
# In[7]:
|
||||
|
||||
|
||||
# FS.plot_variable('dealerCardValue')
|
||||
# FS.plot_variable('playerCardsValue')
|
||||
# FS.plot_variable('countedCardsValue')
|
||||
# FS.plot_variable('decision')
|
||||
|
||||
|
||||
# ## Sterownik 4 - Decyzja jaką akcję podjąć (miękka ręka)
|
||||
# ##### Dane wejściowe:
|
||||
# - Wartość widocznej karty krupiera
|
||||
# - Wartość kart gracza
|
||||
# - Liczba kart gracza
|
||||
#
|
||||
# ##### Dane wyjściowe:
|
||||
# - Decyzja dot. akcji w grze
|
||||
|
||||
# In[25]:
|
||||
|
||||
|
||||
def getSoftHandDecision(dealerCard, playerCardsVal, playerCardsNum):
|
||||
"""
|
||||
Args:
|
||||
dealerCard (int): value of the dealer card
|
||||
playerCardsVal (int): sum of the players hand
|
||||
playerCardsNum (int): number of cards in players hadn
|
||||
Returns:
|
||||
str: decision
|
||||
"""
|
||||
|
||||
FS = FuzzySystem(show_banner=False)
|
||||
|
||||
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
|
||||
FuzzySet([[0,1], [6,1], [7,0]], term='low'),
|
||||
FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
|
||||
FuzzySet([[7,0], [8,1]], term='very_high')
|
||||
], universe_of_discourse=[0, 11]))
|
||||
|
||||
FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([
|
||||
FuzzySet([[0,1], [11,1], [12,0]], term='low'),
|
||||
FuzzySet([[11,0], [12,1], [16,1], [17, 0]], term='medium'),
|
||||
FuzzySet([[16,0], [17,1], [18,0]], term='high'),
|
||||
FuzzySet([[17,0], [18,1]], term='very_high')
|
||||
], universe_of_discourse=[0, 21]))
|
||||
|
||||
# FS.add_linguistic_variable('splitValue', LinguisticVariable([
|
||||
# FuzzySet([[0,1], [2,1], [3,0], [9,0], [10,1]], term='split_high'),
|
||||
# FuzzySet([[2,0], [3,1], [4.5,1], [5,0], [5.5,1], [9,1], [9,1], [10,0]], term='split_low'),
|
||||
# ], universe_of_discourse=[0, 20]))
|
||||
|
||||
FS.add_linguistic_variable('doubleValue', LinguisticVariable([
|
||||
FuzzySet([[12,0], [13,1], [16,1], [17,0]], term='low'),
|
||||
FuzzySet([[16,0], [17,1], [18,0]], term='high'),
|
||||
], universe_of_discourse=[0, 21]))
|
||||
|
||||
|
||||
O1 = TriangleFuzzySet(0,0,13, term="double down")
|
||||
O2 = TriangleFuzzySet(0,13,25, term="hit")
|
||||
O3 = TriangleFuzzySet(13,25,25, term="stand")
|
||||
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25]))
|
||||
|
||||
|
||||
if playerCardsNum == 2: # gdy początek rozgrywki
|
||||
FS.add_rules([
|
||||
"IF (doubleValue IS high) THEN (decision IS double down)",
|
||||
"IF (doubleValue IS low) AND (dealerCardValue IS low) THEN (decision IS double down)",
|
||||
"IF (playerCardsValue IS low) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS very_high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS very_high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
])
|
||||
|
||||
else:
|
||||
FS.add_rules([
|
||||
"IF (playerCardsValue IS low) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
|
||||
"IF (playerCardsValue IS very_high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS high) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS medium) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
"IF (playerCardsValue IS very_high) AND (dealerCardValue IS low) THEN (decision IS stand)",
|
||||
])
|
||||
|
||||
|
||||
FS.set_variable("dealerCardValue", dealerCard)
|
||||
FS.set_variable("playerCardsValue", playerCardsVal)
|
||||
FS.set_variable("doubleValue", playerCardsVal)
|
||||
|
||||
result = FS.inference()
|
||||
decision_terms = [(i.get_term(), FS.get_fuzzy_set('decision', i.get_term()).get_value(result['decision'])) for i in FS.get_fuzzy_sets('decision')]
|
||||
endDecision = max(decision_terms, key=lambda item:item[1])[0]
|
||||
|
||||
return endDecision
|
||||
|
||||
|
||||
# In[2]:
|
||||
|
||||
|
||||
# FS.plot_variable('dealerCardValue')
|
||||
# FS.plot_variable('playerCardValue')
|
||||
# FS.plot_variable('countedCardsValue')
|
||||
# FS.plot_variable('decision')
|
||||
|
||||
|
||||
|
||||
# ## Funkcja do obsługi sterowników
|
||||
# ##### Dane wejściowe:
|
||||
# - Wartość widocznej karty krupiera
|
||||
# - Lista kart gracza
|
||||
# - Flaga określająca czt jest para (ustawiona na 1 tylko gdy kest para i gdy jest to początek rozgrywki!)
|
||||
#
|
||||
# ##### Dane wyjściowe:
|
||||
# - Decyzja dot. akcji w grze
|
||||
|
||||
# In[25]:
|
||||
|
||||
def getDecision(dealerCard, playerCards, isPair):
|
||||
"""
|
||||
Args:
|
||||
dealerCard (int): value of the dealer card
|
||||
playerCards (list): list of player cards
|
||||
isPair (int): is pair in players hand - 1 only at the beggining of the game
|
||||
Returns:
|
||||
str: decision
|
||||
"""
|
||||
playerCardsNum = len(playerCards)
|
||||
if 1 in playerCards: # soft hand
|
||||
playerCardsVal = sum([x if x != 1 else 10 for x in playerCards])
|
||||
if sum(playerCards) == 2: # is pair of aces
|
||||
return 'split'
|
||||
else: # controller for soft hand
|
||||
return getSoftHandDecision(dealerCard, playerCardsVal, playerCardsNum)
|
||||
|
||||
else: # hard hand
|
||||
playerCardsVal = sum(playerCards)
|
||||
if isPair and getSplitDecision(dealerCard, playerCardsVal) != 'continue': # if pair - controller for splitting
|
||||
return 'split'
|
||||
else: # controller for hard hand
|
||||
return getHardHandDecision(dealerCard, playerCardsVal, playerCardsNum)
|
218
cards.py
218
cards.py
@ -1,5 +1,6 @@
|
||||
# import itertools
|
||||
import random
|
||||
from FuzzyControlSystem import getStartDecision, getSplitDecision, getHardHandDecision, getSoftHandDecision, getDecision
|
||||
|
||||
|
||||
def shoe(n_of_decks: int = 1) -> list:
|
||||
"""Create shuffled shoe of n decks of cards
|
||||
@ -10,18 +11,19 @@ def shoe(n_of_decks: int = 1) -> list:
|
||||
Returns:
|
||||
list: shoe- shuffled decks of cards
|
||||
"""
|
||||
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
|
||||
vals = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'jack', 'queen', 'king', 'ace']
|
||||
suits = ['spades', 'clubs', 'hearts', 'diamonds']
|
||||
|
||||
deck = []
|
||||
for _ in range(n_of_decks):
|
||||
for _ in suits:
|
||||
deck.extend(vals)
|
||||
# deck.extend(itertools.product(vals, suits))
|
||||
|
||||
random.shuffle(deck)
|
||||
return deck
|
||||
|
||||
def cards_eval(hand: list) -> list:
|
||||
def cards_eval(hand: list, agent: str) -> list:
|
||||
"""Evaluate hand value. Will return two values if there is an ace
|
||||
in the hand and both values are below 21.
|
||||
|
||||
@ -31,10 +33,18 @@ def cards_eval(hand: list) -> list:
|
||||
Returns:
|
||||
list: returns a list of values of the hand
|
||||
"""
|
||||
evaluation = [sum(hand), sum(hand)]
|
||||
evaluation = [0, 0]
|
||||
for value in hand:
|
||||
if value == 1:
|
||||
print(f"{agent} : {value}")
|
||||
if value in ['jack', 'queen', 'king']:
|
||||
evaluation[0] += 10
|
||||
evaluation[1] += 10
|
||||
elif value == 'ace':
|
||||
evaluation[0] += 1
|
||||
evaluation[1] += 11
|
||||
else:
|
||||
evaluation[0] += int(value)
|
||||
evaluation[1] += int(value)
|
||||
if evaluation[0] == evaluation[1]:
|
||||
return [evaluation[0]]
|
||||
elif evaluation[1] > 21:
|
||||
@ -52,24 +62,13 @@ def dealer(hand: list, shoe: iter) -> int:
|
||||
Returns:
|
||||
int: dealer hand value
|
||||
"""
|
||||
evaluation = cards_eval(hand)
|
||||
evaluation = cards_eval(hand, "dealer")
|
||||
while max(evaluation) <= 17: #solve soft 17
|
||||
hand.append(next(shoe))
|
||||
evaluation = cards_eval(hand)
|
||||
evaluation = cards_eval(hand, "dealer")
|
||||
return max(evaluation)
|
||||
|
||||
def count_highlow(hand: list) -> int:
|
||||
highlow = 0
|
||||
low_cards = [1, 2, 3, 4, 5, 6, 7]
|
||||
|
||||
for card in hand:
|
||||
if card in low_cards:
|
||||
highlow -= 1
|
||||
elif card == 10:
|
||||
highlow += 1
|
||||
return highlow
|
||||
|
||||
def AI(hand: list, face_up: str, losses_in_row: int) -> str:
|
||||
def AI(hand: list, face_up: str) -> str:
|
||||
#TODO: add fuzzy logic
|
||||
"""Fuzzy AI
|
||||
possible player decision:
|
||||
@ -77,146 +76,123 @@ def AI(hand: list, face_up: str, losses_in_row: int) -> str:
|
||||
Args:
|
||||
hand (list): player hand
|
||||
face_up (str): dealer face up card
|
||||
losses_in_row: number of losses in row in the current game
|
||||
|
||||
Returns:
|
||||
list: player decision
|
||||
"""
|
||||
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
|
||||
|
||||
cards_count = len(hand)
|
||||
|
||||
highlow = count_highlow(hand)
|
||||
|
||||
evaluation = cards_eval(hand)
|
||||
if len(evaluation) != 1:
|
||||
evaluation = evaluation[1]
|
||||
### temp
|
||||
# if face_up == 'ace':
|
||||
# return 'surrender'
|
||||
# else:
|
||||
evaluation = cards_eval(hand, "player")
|
||||
if max(evaluation) == 11:
|
||||
return 'double down'
|
||||
if max(evaluation) <= 17:
|
||||
return 'hit'
|
||||
else:
|
||||
evaluation = evaluation[0]
|
||||
is_pair = any([hand.count(val) > 1 for val in vals])
|
||||
decision = ''
|
||||
decision = getDecision(face_up, hand, is_pair)
|
||||
return decision
|
||||
return 'stand'
|
||||
### temp
|
||||
|
||||
def show_game_state(player_hand: list, dealer_hand: list, splited: bool, decision: str='') -> None:
|
||||
"""Print dealer and player card values and player decision
|
||||
def has_blackjack_occured(hand: list):
|
||||
"""Method assumes that hand value == 21 """
|
||||
if len(hand) != 2:
|
||||
return False
|
||||
if "ace" in hand and any([value in hand for value in ['jack', 'queen', 'king']]):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
Args:
|
||||
player_hand (list): List of cards in player hand
|
||||
dealer_hand (list): List of cards in dealer hand
|
||||
splited (bool): True if it is subprocess by spliting
|
||||
decision (str, optional): Player decision. Will not be printed if defaults to ''.
|
||||
|
||||
"""
|
||||
if decision and cards_eval(player_hand)[0] > 21:
|
||||
print("split| " if splited else '', end='')
|
||||
print(f"dealer: {cards_eval(dealer_hand)} player: {cards_eval(player_hand)} fail")
|
||||
elif decision:
|
||||
print("split| " if splited else '', end='')
|
||||
print(f"dealer: {cards_eval(dealer_hand)} player: {cards_eval(player_hand)} decision: {decision}")
|
||||
elif not cards_eval(player_hand)[0] > 21:
|
||||
print("split| " if splited else '', end='')
|
||||
print(f"dealer: {cards_eval(dealer_hand)} player: {cards_eval(player_hand)}")
|
||||
|
||||
def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list=[], bet: int=10, losses_in_row: int=0) -> str:
|
||||
def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list =[], bet: int =10) -> str:
|
||||
"""Single blackjack round
|
||||
|
||||
Args:
|
||||
shoe (iter): shoe iterator
|
||||
dealer_hand (list, optional): dealer hand. Should be non empty only in SPLIT.
|
||||
player_hand (list, optional): player hand. Should be non empty only in SPLIT.
|
||||
bet: amount of money the player betted
|
||||
losses_in_row: number of losses in row in the current game
|
||||
|
||||
Returns:
|
||||
str: game result
|
||||
"""
|
||||
splited = False
|
||||
if dealer_hand == [] and player_hand == []:
|
||||
dealer_hand = [next(shoe), next(shoe)]
|
||||
player_hand = [next(shoe), next(shoe)]
|
||||
else:
|
||||
splited = True
|
||||
|
||||
#dealer turn
|
||||
face_up = dealer_hand[0]
|
||||
dealer_value = dealer(dealer_hand, shoe)
|
||||
|
||||
|
||||
decision = ''
|
||||
while decision not in ['stand', 'surrender']:
|
||||
decision = AI(player_hand, face_up, losses_in_row)
|
||||
show_game_state(player_hand, [face_up], splited, decision)
|
||||
while decision != 'stand' or decision != 'surrender':
|
||||
decision = AI(player_hand, face_up)
|
||||
print(f"Decision: {decision}")
|
||||
if decision == 'hit':
|
||||
player_hand.append(next(shoe))
|
||||
elif decision == 'double down':
|
||||
# breakpoint()
|
||||
bet *= 2
|
||||
player_hand.append(next(shoe))
|
||||
elif decision == 'split':
|
||||
#this work reccursevly
|
||||
player_hand = [player_hand[0]]
|
||||
splited_ai = True #temp
|
||||
blackjack(shoe, dealer_hand, player_hand.copy(), bet)#new wager start
|
||||
#this wont work!
|
||||
#it will need to
|
||||
# dealer_value = dealer(dealer_hand, shoe)
|
||||
#be calculated before and passed to blackjack()
|
||||
#so both wager have the same dealer_value!
|
||||
##this will work reccursevly
|
||||
player_hand = player_hand[0]
|
||||
blackjack(shoe, dealer_hand, player_hand, bet)#new wager start
|
||||
#old wager continue
|
||||
elif decision == 'surrender':
|
||||
break
|
||||
elif decision == 'stand':
|
||||
#dealer_hand.append(next(shoe))
|
||||
#dealer_value = dealer(dealer_hand, shoe)
|
||||
break
|
||||
player_value = max(cards_eval(player_hand))
|
||||
|
||||
show_game_state(player_hand, dealer_hand, splited)
|
||||
print("split| " if splited else '', end='')
|
||||
if player_value == 21 and 1 in player_hand:
|
||||
print('player blackjack', "="*50, sep='\n')
|
||||
return 'player blackjack', bet
|
||||
#dealer turn
|
||||
dealer_value = dealer(dealer_hand, shoe)
|
||||
player_value = max(cards_eval(player_hand, "player"))
|
||||
# print(dealer_value, player_value) #debug
|
||||
|
||||
#round end
|
||||
print(f"Dealer's deck value: {dealer_value}")
|
||||
print(f"Player's deck value: {player_value}")
|
||||
if player_value == 21 and has_blackjack_occured(player_hand):
|
||||
return 'player blackjack', bet
|
||||
elif player_value > 21:
|
||||
print('dealer win', "="*50, sep='\n')
|
||||
return 'dealer win', bet
|
||||
elif dealer_value > 21:
|
||||
print('player win', "="*50, sep='\n')
|
||||
return 'player win', bet
|
||||
elif player_value > dealer_value:
|
||||
print('player win', "="*50, sep='\n')
|
||||
return 'player win', bet
|
||||
elif player_value == dealer_value:
|
||||
print('push', "="*50, sep='\n')
|
||||
return 'push', bet #keep money, no win no lose 0$
|
||||
else:
|
||||
print('dealer win', "="*50, sep='\n')
|
||||
return 'dealer win', bet
|
||||
#TODO: add adidtional return with wager value like +10$ or -20$
|
||||
|
||||
def game_loop(balance, bet) -> None:
|
||||
wins, losses, draws = 0, 0, 0
|
||||
player_blackjack = 0
|
||||
|
||||
shoe_iter = iter(shoe(10))
|
||||
losses_in_row = 0
|
||||
notable_results = ['player win', 'dealer win', 'player blackjack']
|
||||
while True:
|
||||
#round start
|
||||
try:
|
||||
balance -= bet
|
||||
result, game_bet = blackjack(shoe_iter, bet=bet, losses_in_row=losses_in_row)
|
||||
result, game_bet = blackjack(shoe_iter, bet=bet)
|
||||
except StopIteration:
|
||||
break
|
||||
if result == 'player win':
|
||||
wins += 1
|
||||
balance += (2*game_bet)
|
||||
losses_in_row = 0
|
||||
|
||||
elif result == 'player blackjack':
|
||||
wins += 1
|
||||
# player_blackjack += 1
|
||||
player_blackjack += 1
|
||||
balance += (2*game_bet) + (game_bet/2)
|
||||
losses_in_row = 0
|
||||
|
||||
elif result == 'dealer win':
|
||||
losses += 1
|
||||
losses_in_row += 1
|
||||
|
||||
elif result == 'push':
|
||||
balance += game_bet
|
||||
draws += 1
|
||||
return wins, losses, draws, balance #player_blackjack
|
||||
if result in notable_results:
|
||||
print(result)
|
||||
print("===="*10)
|
||||
return wins, losses, draws, balance, player_blackjack
|
||||
|
||||
def calculate_bet(wins, losses, hand):
|
||||
pass
|
||||
@ -225,45 +201,25 @@ def calculate_bet(wins, losses, hand):
|
||||
# print(game_loop())
|
||||
|
||||
if __name__ == '__main__':
|
||||
statistics = [0, 0, 0]
|
||||
money_sum = 0
|
||||
total_wins, total_losses, total_draws = 0, 0, 0
|
||||
total_p_blackjack = 0
|
||||
balance = 0
|
||||
bet = 10
|
||||
|
||||
import time
|
||||
#don't use time.time() for counting code execution time!
|
||||
start = time.perf_counter()
|
||||
for i in range(10):
|
||||
wins, loses, draws, money = game_loop(0, 10)
|
||||
statistics[0] += wins
|
||||
statistics[1] += loses
|
||||
statistics[2] += draws
|
||||
money_sum += money
|
||||
|
||||
for i in range(100):
|
||||
wins, loses, draws, balance, p_blackjack = game_loop(balance, bet)
|
||||
total_wins += wins
|
||||
total_losses += loses
|
||||
total_draws += draws
|
||||
total_p_blackjack += p_blackjack
|
||||
|
||||
end = time.perf_counter()
|
||||
result = end - start
|
||||
print(f'time: {round(result, 3)} seconds')
|
||||
print(f'wins: {statistics[0]} | losses: {statistics[1]} | draws: {statistics[2]}')
|
||||
print(f'win {round((statistics[0]/sum(statistics)*100), 2)}%')
|
||||
print(f'balance: {money_sum}')
|
||||
|
||||
# print(f'moeny return {round((money_sum)*100, 2)}%')
|
||||
# total_wins, total_losses, total_draws = 0, 0, 0
|
||||
# total_p_blackjack = 0
|
||||
# balance = 0
|
||||
# bet = 10
|
||||
|
||||
# import time
|
||||
# #don't use time.time() for counting code execution time!
|
||||
# start = time.perf_counter()
|
||||
# for i in range(100):
|
||||
# wins, loses, draws, balance, p_blackjack = game_loop(balance, bet)
|
||||
# total_wins += wins
|
||||
# total_losses += loses
|
||||
# total_draws += draws
|
||||
# total_p_blackjack += p_blackjack
|
||||
|
||||
# end = time.perf_counter()
|
||||
# result = end - start
|
||||
# print(result)
|
||||
# print(f"Wins: {total_wins}, Losses: {total_losses}, Draws: {total_draws}")
|
||||
# print(f"Wins/Losses ratio: {total_wins/sum([total_wins, total_losses])}")
|
||||
# print(f"Balance: {balance}")
|
||||
# print(f"Times player hit blackjack: {total_p_blackjack}")
|
||||
print(result)
|
||||
print(f"Wins: {total_wins}, Losses: {total_losses}, Draws: {total_draws}")
|
||||
print(f"Wins/Losses ratio: {total_wins/sum([total_wins, total_losses])}")
|
||||
print(f"Balance: {balance}")
|
||||
print(f"Times player hit blackjack: {total_p_blackjack}")
|
||||
|
Loading…
Reference in New Issue
Block a user