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
# ##### Dane wejściowe:
# - Wartość widocznej karty krupiera
# - Wartość karty gracza (jednej z pary)
# - Wartość kart gracza
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
@ -80,22 +80,27 @@ getStartDecision(7, 7)
# In[12]:
def getSplitDecision(dealerCard, playerCard):
def getSplitDecision(dealerCard, playerCardsVal):
"""
Args:
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:
str: decision
"""
FS = FuzzySystem(show_banner=False)
T1 = TriangleFuzzySet(0,0,6, term="low")
T2 = TriangleFuzzySet(4,6,8, term="average")
T3 = TriangleFuzzySet(6,11,11, term="high")
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([T1, T2, T3], universe_of_discourse=[0, 11]))
FS.add_linguistic_variable("playerCardValue", LinguisticVariable([T1, T2, T3], universe_of_discourse=[0, 11]))
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")
@ -103,17 +108,14 @@ def getSplitDecision(dealerCard, playerCard):
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2], universe_of_discourse=[0, 25]))
FS.add_rules([
"IF (playerCardValue IS high) THEN (decision IS split)",
"IF (playerCardValue IS average) AND (dealerCardValue IS average) THEN (decision IS split)",
"IF (playerCardValue IS average) AND (dealerCardValue IS low) THEN (decision IS split)",
"IF (playerCardValue IS low) AND (dealerCardValue IS 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)"
"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("playerCardValue", playerCard)
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')]
@ -121,11 +123,6 @@ def getSplitDecision(dealerCard, playerCard):
return endDecision
# In[13]:
getSplitDecision(5, 3)
# In[7]:
@ -135,11 +132,11 @@ getSplitDecision(5, 3)
#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:
# - Wartość widocznej karty krupiera
# - Suma kart gracza
# - Suma zliczonych kart
# - Liczba kart gracza
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
@ -147,12 +144,11 @@ getSplitDecision(5, 3)
# In[29]:
def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCardsNum):
def getHardHandDecision(dealerCard, playerCardsVal, playerCardsNum):
"""
Args:
dealerCard (int): value of the dealer card
playerCardsVal (int): sum of the players hand
countedCardsVal (int): value of the counted cards
playerCardsNum (int): number of cards in players hadn
Returns:
str: decision
@ -161,22 +157,27 @@ def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
FS = FuzzySystem(show_banner=False)
FS.add_linguistic_variable("dealerCardValue", LinguisticVariable([
TriangleFuzzySet(0,0,6, term="low"),
TriangleFuzzySet(4,6,8, term="average"),
TriangleFuzzySet(6,11,11, term="high")],
universe_of_discourse=[0, 11]))
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([
TriangleFuzzySet(0,0,12, term="low"),
TriangleFuzzySet(11,14,17, term="average"),
TriangleFuzzySet(12,21,21, term="high")],
universe_of_discourse=[0, 21]))
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("countedCardsValue", LinguisticVariable([
TriangleFuzzySet(-20,-20,0, term="low"),
TriangleFuzzySet(-5,0,5, term="average"),
TriangleFuzzySet(0,20,20, term="high")],
universe_of_discourse=[-20, 20]))
# 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")
@ -185,40 +186,36 @@ def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
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([
"IF (playerCardsValue IS low) THEN (decision IS double down)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS double down)",
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS stand)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS double down)"
"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)",
])
else:
FS.add_rules([
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS low) THEN (decision IS stand)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS hit)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue 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)",
])
FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", countedCardsVal)
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[19]:
getHardHandDecision(4, 10, 0, 2)
# In[7]:
@ -229,11 +226,11 @@ getHardHandDecision(4, 10, 0, 2)
# 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:
# - Wartość widocznej karty krupiera
# - Wartość drugiej karty gracza
# - Suma zliczonych kart
# - Wartość kart gracza
# - Liczba kart gracza
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
@ -241,27 +238,40 @@ getHardHandDecision(4, 10, 0, 2)
# 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.add_linguistic_variable("dealerCardValue", LinguisticVariable([
TriangleFuzzySet(0,0,6, term="low"),
TriangleFuzzySet(4,6,8, term="average"),
TriangleFuzzySet(6,11,11, term="high")],
universe_of_discourse=[0, 11]))
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([
TriangleFuzzySet(0,0,12, term="low"),
TriangleFuzzySet(11,14,17, term="average"),
TriangleFuzzySet(12,21,21, term="high")],
universe_of_discourse=[0, 21]))
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("countedCardsValue", LinguisticVariable([
TriangleFuzzySet(-20,-20,0, term="low"),
TriangleFuzzySet(-5,0,5, term="average"),
TriangleFuzzySet(0,20,20, term="high")],
universe_of_discourse=[-20, 20]))
# 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")
@ -269,38 +279,37 @@ def getSoftHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCards
O3 = TriangleFuzzySet(13,25,25, term="stand")
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([
"IF (playerCardsValue IS average) AND (dealerCardValue IS average) THEN (decision IS double down)",
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS hit)",
"IF (playerCardValue IS low) AND (dealerCardValue IS low) THEN (decision IS hit)",
"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)",
])
else:
FS.add_rules([
"IF (playerCardsValue IS high) THEN (decision IS stand)",
"IF (playerCardsValue IS low) THEN (decision IS hit)",
"IF (playerCardsValue IS average) 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 average) AND (dealerCardValue IS average) AND (countedCardsValue 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)",
])
FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", 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[26]:
getSoftHandDecision(2, 8, 0, 3)
# In[2]:
@ -309,3 +318,40 @@ getSoftHandDecision(2, 8, 0, 3)
# 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)

View File

@ -1,5 +1,5 @@
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:
"""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:
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)
@ -90,11 +92,9 @@ def AI(hand: list, face_up: str, losses_in_row: int) -> str:
evaluation = evaluation[1]
else:
evaluation = evaluation[0]
is_pair = any([hand.count(val) > 1 for val in vals])
decision = ''
if 'ace' in hand:
decision = getSoftHandDecision(face_up, evaluation, highlow,cards_count)
else:
decision = getHardHandDecision(face_up, evaluation, highlow,cards_count)
decision = getDecision(face_up, hand, is_pair)
return decision
def show_game_state(player_hand: list, dealer_hand: list, splited: bool, decision: str='') -> None: