377 lines
14 KiB
Python
377 lines
14 KiB
Python
#!/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)
|