blackjack-fuzzy/FuzzyControlSystem.py
Andrzej Preibisz fca596c327 WIP
2023-02-01 23:14:14 +01:00

312 lines
11 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ść karty gracza (jednej z pary)
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
# In[12]:
def getSplitDecision(dealerCard, playerCard):
"""
Args:
dealerCard (int): value of the dealer card
playerCard (int): value of the player card (one of the pair)
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]))
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 (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)"
])
FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardValue", playerCard)
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[13]:
getSplitDecision(5, 3)
# In[7]:
#FS.plot_variable('dealerCardValue')
#FS.plot_variable('playerCardValue')
#FS.plot_variable('decision')
# ## Sterownik 3 - Decyzja jaką akcję podjąć (gracz bez asa wśród dwóch kart)
# ##### Dane wejściowe:
# - Wartość widocznej karty krupiera
# - Suma kart gracza
# - Suma zliczonych kart
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
# In[29]:
def getHardHandDecision(dealerCard, playerCardsVal, countedCardsVal, 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
"""
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]))
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]))
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]))
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:
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)"
])
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)",
])
FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", countedCardsVal)
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]:
# FS.plot_variable('dealerCardValue')
# FS.plot_variable('playerCardsValue')
# FS.plot_variable('countedCardsValue')
# FS.plot_variable('decision')
# ## Sterownik 4 - Decyzja jaką akcję podjąć (gracz z asem wśród dwóch kart)
# ##### Dane wejściowe:
# - Wartość widocznej karty krupiera
# - Wartość drugiej karty gracza
# - Suma zliczonych kart
#
# ##### Dane wyjściowe:
# - Decyzja dot. akcji w grze
# In[25]:
def getSoftHandDecision(dealerCard, playerCardsVal, countedCardsVal, playerCardsNum):
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]))
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]))
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]))
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:
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)",
])
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)"
])
FS.set_variable("dealerCardValue", dealerCard)
FS.set_variable("playerCardsValue", playerCardsVal)
FS.set_variable("countedCardsValue", 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]:
# FS.plot_variable('dealerCardValue')
# FS.plot_variable('playerCardValue')
# FS.plot_variable('countedCardsValue')
# FS.plot_variable('decision')