blackjack-fuzzy/.ipynb_checkpoints/FuzzyControlSystem-checkpoint.ipynb
2023-01-29 19:54:59 +01:00

19 KiB

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
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", 7) 
FS.set_variable("numLossInRow", 7) 

result = FS.inference(verbose=True)
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
 * Processing output for variable 'decision'
   whose universe of discourse is: [0, 25]
   contains the following fuzzy sets: [<Fuzzy set (function), term='leave'>, <Fuzzy set (function), term='play'>, <Fuzzy set (function), term='playDouble'>]
 ** Rule composition: f.(c.(numLossInRow IS average) AND c.(chipValue IS average)) -> ('decision', 'play', '1.0') , output variable: 'decision' with term: 'play'
 ** Rule composition: f.(c.(numLossInRow IS low) OR c.(chipValue IS low)) -> ('decision', 'leave', '1.0') , output variable: 'decision' with term: 'leave'
 ** Rule composition: f.(c.(numLossInRow IS high) AND c.(chipValue IS high)) -> ('decision', 'playDouble', '1.0') , output variable: 'decision' with term: 'playDouble'
 * Indices: {'play': 1, 'leave': 0, 'playDouble': 2}
 * Weighted values: 6201.36	Values: 458.14	CoG: 13.54
'play'
# 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
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", 5) 
FS.set_variable("playerCardValue", 3) 

result = FS.inference(verbose=True)
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
 * Processing output for variable 'decision'
   whose universe of discourse is: [0, 25]
   contains the following fuzzy sets: [<Fuzzy set (function), term='continue'>, <Fuzzy set (function), term='split'>]
 ** Rule composition: c.(playerCardValue IS high) -> ('decision', 'split', '1.0') , output variable: 'decision' with term: 'split'
 ** Rule composition: f.(c.(playerCardValue IS average) AND c.(dealerCardValue IS average)) -> ('decision', 'split', '1.0') , output variable: 'decision' with term: 'split'
 ** Rule composition: f.(c.(playerCardValue IS low) AND c.(dealerCardValue IS average)) -> ('decision', 'split', '1.0') , output variable: 'decision' with term: 'split'
 ** Rule composition: f.(c.(playerCardValue IS low) AND c.(dealerCardValue IS low)) -> ('decision', 'continue', '1.0') , output variable: 'decision' with term: 'continue'
 ** Rule composition: f.(c.(playerCardValue IS low) AND c.(dealerCardValue IS high)) -> ('decision', 'continue', '1.0') , output variable: 'decision' with term: 'continue'
 * Indices: {'split': 1, 'continue': 0}
 * Weighted values: 4597.07	Values: 290.67	CoG: 15.82
'split'
# 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
# dodatkowy argument określający liczbę kart gracza - w przypadku rozpoczęcia rozgrywki możliwa jest decyzja o podwojeniu
playerCardsNum = 3

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="doubleDown")
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 doubleDown)",
        "IF (playerCardsValue IS average) AND (dealerCardValue IS high) THEN (decision IS doubleDown)",
        "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 doubleDown)"
        ])
    
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", 4) 
FS.set_variable("playerCardsValue", 10)
FS.set_variable("countedCardsValue", 0)

result = FS.inference(verbose=True)
print(result)
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
 * Processing output for variable 'decision'
   whose universe of discourse is: [0, 25]
   contains the following fuzzy sets: [<Fuzzy set (function), term='doubleDown'>, <Fuzzy set (function), term='hit'>, <Fuzzy set (function), term='stand'>]
 ** Rule composition: c.(playerCardsValue IS high) -> ('decision', 'stand', '1.0') , output variable: 'decision' with term: 'stand'
 ** Rule composition: c.(playerCardsValue IS low) -> ('decision', 'hit', '1.0') , output variable: 'decision' with term: 'hit'
 ** Rule composition: f.(c.(playerCardsValue IS average) AND c.(dealerCardValue IS low)) -> ('decision', 'stand', '1.0') , output variable: 'decision' with term: 'stand'
 ** Rule composition: f.(c.(playerCardsValue IS average) AND c.(dealerCardValue IS high)) -> ('decision', 'hit', '1.0') , output variable: 'decision' with term: 'hit'
 ** Rule composition: f.(c.(playerCardsValue IS average) AND f.(c.(dealerCardValue IS average) AND c.(countedCardsValue IS low))) -> ('decision', 'hit', '1.0') , output variable: 'decision' with term: 'hit'
 * Indices: {'stand': 2, 'hit': 1}
 * Weighted values: 1913.98	Values: 152.62	CoG: 12.54
{'decision': 12.540414715943523}
'hit'
# 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
# dodatkowy argument określający liczbę kart gracza - w przypadku rozpoczęcia rozgrywki możliwa jest decyzja o podwojeniu
playerCardsNum = 3

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="doubleDown")
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 doubleDown)",
        "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", 2) 
FS.set_variable("playerCardValue", 8)
FS.set_variable("countedCardsValue", 0)

result = FS.inference(verbose=True)
print(result)
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
 * Processing output for variable 'decision'
   whose universe of discourse is: [0, 25]
   contains the following fuzzy sets: [<Fuzzy set (function), term='doubleDown'>, <Fuzzy set (function), term='hit'>, <Fuzzy set (function), term='stand'>]
 ** Rule composition: c.(playerCardValue IS high) -> ('decision', 'Stand', '1.0') , output variable: 'decision' with term: 'Stand'
 ** Rule composition: c.(playerCardValue IS low) -> ('decision', 'hit', '1.0') , output variable: 'decision' with term: 'hit'
 ** Rule composition: f.(c.(playerCardValue IS average) AND c.(dealerCardValue IS high)) -> ('decision', 'Hit', '1.0') , output variable: 'decision' with term: 'Hit'
 ** Rule composition: f.(c.(playerCardValue IS average) AND f.(c.(dealerCardValue IS average) AND c.(countedCardsValue IS high))) -> ('decision', 'Stand', '1.0') , output variable: 'decision' with term: 'Stand'
 ** Rule composition: f.(c.(playerCardValue IS average) AND f.(c.(dealerCardValue IS average) AND c.(countedCardsValue IS low))) -> ('decision', 'Hit', '1.0') , output variable: 'decision' with term: 'Hit'
 * Indices: {'Stand': -1, 'hit': 1, 'Hit': -1}
 * Weighted values: 3662.59	Values: 180.07	CoG: 20.34
{'decision': 20.339814678947857}
'stand'
# FS.plot_variable('dealerCardValue')
# FS.plot_variable('playerCardValue')
# FS.plot_variable('countedCardsValue')
# FS.plot_variable('decision')