This commit is contained in:
Andrzej Preibisz 2023-02-01 23:45:29 +01:00
commit 1e0f50c1a7
2 changed files with 138 additions and 92 deletions

View File

@ -72,7 +72,7 @@ getStartDecision(7, 7)
# ## Sterownik 2 - Decyzja o strategii w przypadku pary # ## Sterownik 2 - Decyzja o strategii w przypadku pary
# ##### Dane wejściowe: # ##### Dane wejściowe:
# - Wartość widocznej karty krupiera # - Wartość widocznej karty krupiera
# - Wartość karty gracza (jednej z pary) # - Wartość kart gracza
# #
# ##### Dane wyjściowe: # ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze # - Decyzja dot. akcji w grze
@ -80,22 +80,27 @@ getStartDecision(7, 7)
# In[12]: # In[12]:
def getSplitDecision(dealerCard, playerCard): def getSplitDecision(dealerCard, playerCardsVal):
""" """
Args: Args:
dealerCard (int): value of the dealer card dealerCard (int): value of the dealer card
playerCard (int): value of the player card (one of the pair) playerCardsVal (int): sum of the player cards
Returns: Returns:
str: decision str: decision
""" """
FS = FuzzySystem(show_banner=False) FS = FuzzySystem(show_banner=False)
T1 = TriangleFuzzySet(0,0,6, term="low") FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
T2 = TriangleFuzzySet(4,6,8, term="average") FuzzySet([[0,1], [6,1], [7,0]], term='low'),
T3 = TriangleFuzzySet(6,11,11, term="high") FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([T1, T2, T3], universe_of_discourse=[0, 11])) FuzzySet([[7,0], [8,1]], term='very_high')
FS.add_linguistic_variable("playerCardValue", LinguisticVariable([T1, T2, T3], universe_of_discourse=[0, 11])) ], 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") O1 = TriangleFuzzySet(0,0,15, term="continue")
@ -103,17 +108,14 @@ def getSplitDecision(dealerCard, playerCard):
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2], universe_of_discourse=[0, 25])) FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2], universe_of_discourse=[0, 25]))
FS.add_rules([ FS.add_rules([
"IF (playerCardValue IS high) THEN (decision IS split)", "IF (splitValue IS high) THEN (decision IS split)",
"IF (playerCardValue IS average) AND (dealerCardValue IS average) THEN (decision IS split)", "IF (splitValue IS low) AND (dealerCardValue IS low) THEN (decision IS split)",
"IF (playerCardValue IS average) AND (dealerCardValue IS low) THEN (decision IS split)", "IF (splitValue IS low) AND (dealerCardValue IS high) THEN (decision IS continue)",
"IF (playerCardValue IS low) AND (dealerCardValue IS high) THEN (decision IS continue)", "IF (splitValue IS low) AND (dealerCardValue IS very_high) THEN (decision IS continue)",
"IF (playerCardValue IS low) AND (dealerCardValue IS average) THEN (decision IS split)",
"IF (playerCardValue IS low) AND (dealerCardValue IS low) THEN (decision IS continue)",
"IF (playerCardValue IS low) AND (dealerCardValue IS high) THEN (decision IS continue)"
]) ])
FS.set_variable("dealerCardValue", dealerCard) FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardValue", playerCard) FS.set_variable("splitValue", playerCardsVal)
result = FS.inference() 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')] 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')]
@ -121,11 +123,6 @@ def getSplitDecision(dealerCard, playerCard):
return endDecision return endDecision
# In[13]:
getSplitDecision(5, 3)
# In[7]: # In[7]:
@ -135,11 +132,11 @@ getSplitDecision(5, 3)
#FS.plot_variable('decision') #FS.plot_variable('decision')
# ## Sterownik 3 - Decyzja jaką akcję podjąć (gracz bez asa wśród dwóch kart) # ## Sterownik 3 - Decyzja jaką akcję podjąć (twarda ręka)
# ##### Dane wejściowe: # ##### Dane wejściowe:
# - Wartość widocznej karty krupiera # - Wartość widocznej karty krupiera
# - Suma kart gracza # - Suma kart gracza
# - Suma zliczonych kart # - Liczba kart gracza
# #
# ##### Dane wyjściowe: # ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze # - Decyzja dot. akcji w grze
@ -147,12 +144,11 @@ getSplitDecision(5, 3)
# In[29]: # In[29]:
def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCardsNum): def getHardHandDecision(dealerCard, playerCardsVal, playerCardsNum):
""" """
Args: Args:
dealerCard (int): value of the dealer card dealerCard (int): value of the dealer card
playerCardsVal (int): sum of the players hand playerCardsVal (int): sum of the players hand
countedCardsVal (int): value of the counted cards
playerCardsNum (int): number of cards in players hadn playerCardsNum (int): number of cards in players hadn
Returns: Returns:
str: decision str: decision
@ -161,22 +157,27 @@ def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
FS = FuzzySystem(show_banner=False) FS = FuzzySystem(show_banner=False)
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([ FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
TriangleFuzzySet(0,0,6, term="low"), FuzzySet([[0,1], [6,1], [7,0]], term='low'),
TriangleFuzzySet(4,6,8, term="average"), FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
TriangleFuzzySet(6,11,11, term="high")], FuzzySet([[7,0], [8,1]], term='very_high')
universe_of_discourse=[0, 11])) ], universe_of_discourse=[0, 11]))
FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([ FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([
TriangleFuzzySet(0,0,12, term="low"), FuzzySet([[0,1], [11,1], [12,0]], term='low'),
TriangleFuzzySet(11,14,17, term="average"), FuzzySet([[11,0], [12,1], [16,1], [17, 0]], term='medium'),
TriangleFuzzySet(12,21,21, term="high")], FuzzySet([[16,0], [17,1], [18,0]], term='high'),
universe_of_discourse=[0, 21])) FuzzySet([[17,0], [18,1]], term='very_high')
], universe_of_discourse=[0, 21]))
FS.add_linguistic_variable("countedCardsValue", LinguisticVariable([ # FS.add_linguistic_variable('splitValue', LinguisticVariable([
TriangleFuzzySet(-20,-20,0, term="low"), # FuzzySet([[0,1], [2,1], [3,0], [9,0], [10,1]], term='split_high'),
TriangleFuzzySet(-5,0,5, term="average"), # FuzzySet([[2,0], [3,1], [4.5,1], [5,0], [5.5,1], [9,1], [9,1], [10,0]], term='split_low'),
TriangleFuzzySet(0,20,20, term="high")], # ], universe_of_discourse=[0, 20]))
universe_of_discourse=[-20, 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") O1 = TriangleFuzzySet(0,0,13, term="double down")
@ -185,40 +186,36 @@ def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25])) FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25]))
if playerCardsNum == 2: if playerCardsNum == 2: # gdy początek rozgrywki
FS.add_rules([ FS.add_rules([
"IF (playerCardsValue IS low) THEN (decision IS double down)", "IF (doubleValue IS high) THEN (decision IS double down)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS double down)", "IF (doubleValue IS low) AND (dealerCardValue IS low) THEN (decision IS double down)",
"IF (playerCardsValue IS high) THEN (decision IS stand)", "IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS stand)", "IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS double down)" "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)",
]) ])
else: else:
FS.add_rules([ FS.add_rules([
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS low) THEN (decision IS hit)", "IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS low) THEN (decision IS stand)", "IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS hit)", "IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue IS low) THEN (decision IS hit)", "IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
]) ])
FS.set_variable("dealerCardValue", dealerCard) FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal) FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", countedCardsVal) FS.set_variable("doubleValue", playerCardsVal)
result = FS.inference() 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')] 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] endDecision = max(decision_terms, key=lambda item:item[1])[0]
return endDecision return endDecision
# In[19]:
getHardHandDecision(4, 10, 0, 2)
# In[7]: # In[7]:
@ -229,11 +226,11 @@ getHardHandDecision(4, 10, 0, 2)
# FS.plot_variable('decision') # FS.plot_variable('decision')
# ## Sterownik 4 - Decyzja jaką akcję podjąć (gracz z asem wśród dwóch kart) # ## Sterownik 4 - Decyzja jaką akcję podjąć (miękka ręka)
# ##### Dane wejściowe: # ##### Dane wejściowe:
# - Wartość widocznej karty krupiera # - Wartość widocznej karty krupiera
# - Wartość drugiej karty gracza # - Wartość kart gracza
# - Suma zliczonych kart # - Liczba kart gracza
# #
# ##### Dane wyjściowe: # ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze # - Decyzja dot. akcji w grze
@ -241,27 +238,40 @@ getHardHandDecision(4, 10, 0, 2)
# In[25]: # In[25]:
def getSoftHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCardsNum): 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 = FuzzySystem(show_banner=False)
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([ FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
TriangleFuzzySet(0,0,6, term="low"), FuzzySet([[0,1], [6,1], [7,0]], term='low'),
TriangleFuzzySet(4,6,8, term="average"), FuzzySet([[6,0], [7,1], [7.5,0]], term='high'),
TriangleFuzzySet(6,11,11, term="high")], FuzzySet([[7,0], [8,1]], term='very_high')
universe_of_discourse=[0, 11])) ], universe_of_discourse=[0, 11]))
FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([ FS.add_linguistic_variable("playerCardsValue", LinguisticVariable([
TriangleFuzzySet(0,0,12, term="low"), FuzzySet([[0,1], [11,1], [12,0]], term='low'),
TriangleFuzzySet(11,14,17, term="average"), FuzzySet([[11,0], [12,1], [16,1], [17, 0]], term='medium'),
TriangleFuzzySet(12,21,21, term="high")], FuzzySet([[16,0], [17,1], [18,0]], term='high'),
universe_of_discourse=[0, 21])) FuzzySet([[17,0], [18,1]], term='very_high')
], universe_of_discourse=[0, 21]))
FS.add_linguistic_variable("countedCardsValue", LinguisticVariable([ # FS.add_linguistic_variable('splitValue', LinguisticVariable([
TriangleFuzzySet(-20,-20,0, term="low"), # FuzzySet([[0,1], [2,1], [3,0], [9,0], [10,1]], term='split_high'),
TriangleFuzzySet(-5,0,5, term="average"), # FuzzySet([[2,0], [3,1], [4.5,1], [5,0], [5.5,1], [9,1], [9,1], [10,0]], term='split_low'),
TriangleFuzzySet(0,20,20, term="high")], # ], universe_of_discourse=[0, 20]))
universe_of_discourse=[-20, 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") O1 = TriangleFuzzySet(0,0,13, term="double down")
@ -269,38 +279,37 @@ def getSoftHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
O3 = TriangleFuzzySet(13,25,25, term="stand") O3 = TriangleFuzzySet(13,25,25, term="stand")
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25])) FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25]))
if playerCardsNum == 2:
if playerCardsNum == 2: # gdy początek rozgrywki
FS.add_rules([ FS.add_rules([
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS double down)", "IF (doubleValue IS high) THEN (decision IS double down)",
"IF (playerCardsValue IS high) THEN (decision IS stand)", "IF (doubleValue IS low) AND (dealerCardValue IS low) THEN (decision IS double down)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS hit)", "IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardValue IS low) AND (dealerCardValue 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)",
]) ])
else: else:
FS.add_rules([ FS.add_rules([
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS low) THEN (decision IS hit)", "IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS Hit)", "IF (playerCardsValue IS medium) AND (dealerCardValue IS high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue IS high) THEN (decision IS stand)", "IF (playerCardsValue IS medium) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue IS low) THEN (decision IS Hit)" "IF (playerCardsValue IS high) AND (dealerCardValue IS very_high) THEN (decision IS hit)",
]) ])
FS.set_variable("dealerCardValue", dealerCard) FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal) FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", playerCardsVal) FS.set_variable("doubleValue", playerCardsVal)
result = FS.inference() 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')] 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] endDecision = max(decision_terms, key=lambda item:item[1])[0]
return endDecision return endDecision
# In[26]:
getSoftHandDecision(2, 8, 0, 3)
# In[2]: # In[2]:
@ -309,3 +318,40 @@ getSoftHandDecision(2, 8, 0, 3)
# FS.plot_variable('countedCardsValue') # FS.plot_variable('countedCardsValue')
# FS.plot_variable('decision') # 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)

View File

@ -1,5 +1,5 @@
import random import random
from FuzzyControlSystem import getStartDecision, getSplitDecision, getHardHandDecision, getSoftHandDecision from FuzzyControlSystem import getStartDecision, getSplitDecision, getHardHandDecision, getSoftHandDecision, getDecision
def shoe(n_of_decks: int = 1) -> list: def shoe(n_of_decks: int = 1) -> list:
"""Create shuffled shoe of n decks of cards """Create shuffled shoe of n decks of cards
@ -81,6 +81,8 @@ def AI(hand: list, face_up: str, losses_in_row: int) -> str:
Returns: Returns:
list: player decision list: player decision
""" """
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
cards_count = len(hand) cards_count = len(hand)
highlow = count_highlow(hand) highlow = count_highlow(hand)
@ -90,11 +92,9 @@ def AI(hand: list, face_up: str, losses_in_row: int) -> str:
evaluation = evaluation[1] evaluation = evaluation[1]
else: else:
evaluation = evaluation[0] evaluation = evaluation[0]
is_pair = any([hand.count(val) > 1 for val in vals])
decision = '' decision = ''
if 'ace' in hand: decision = getDecision(face_up, hand, is_pair)
decision = getSoftHandDecision(face_up, evaluation, highlow,cards_count)
else:
decision = getHardHandDecision(face_up, evaluation, highlow,cards_count)
return decision return decision
def show_game_state(player_hand: list, dealer_hand: list, splited: bool, decision: str='') -> None: def show_game_state(player_hand: list, dealer_hand: list, splited: bool, decision: str='') -> None: