diff --git a/FuzzyControlSystem.py b/FuzzyControlSystem.py new file mode 100644 index 0000000..5779d2f --- /dev/null +++ b/FuzzyControlSystem.py @@ -0,0 +1,309 @@ +#!/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="leave") + O2 = TriangleFuzzySet(0,13,25, term="play") + O3 = TriangleFuzzySet(13,25,25, term="playDouble") + FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25])) + + FS.add_rules([ + "IF (numLossInRow IS average) AND (chipValue IS average) THEN (decision IS play)", + "IF (numLossInRow IS low) OR (chipValue IS low) THEN (decision IS leave)", + "IF (numLossInRow IS high) AND (chipValue IS high) THEN (decision IS playDouble)", + ]) + + 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("playerCardValue", LinguisticVariable([ + TriangleFuzzySet(0,0,5, term="low"), + TriangleFuzzySet(4,6,8, term="average"), + TriangleFuzzySet(7,9,9, term="high")], + universe_of_discourse=[0, 9])) + + 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 (playerCardValue IS average) AND (dealerCardValue IS average) THEN (decision IS double down)", + "IF (playerCardValue IS high) THEN (decision IS Stand)", + "IF (playerCardValue 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 (playerCardValue IS high) THEN (decision IS Stand)", + "IF (playerCardValue IS low) THEN (decision IS hit)", + "IF (playerCardValue IS average) AND (dealerCardValue IS high) THEN (decision IS Hit)", + "IF (playerCardValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue IS high) THEN (decision IS Stand)", + "IF (playerCardValue IS average) AND (dealerCardValue IS average) AND (countedCardsValue IS low) THEN (decision IS Hit)" + ]) + + FS.set_variable("dealerCardValue", dealerCard) + FS.set_variable("playerCardValue", playerCardsVal) + FS.set_variable("countedCardsValue", playerCardsNum) + + 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') + diff --git a/cards.py b/cards.py index 106ac84..9708c7b 100644 --- a/cards.py +++ b/cards.py @@ -1,6 +1,6 @@ # import itertools import random - +from FuzzyControlSystem import getStartDecision, getSplitDecision, getHardHandDecision, getSoftHandDecision def shoe(n_of_decks: int = 1) -> list: """Create shuffled shoe of n decks of cards