Fuzzy WIP

This commit is contained in:
Andrzej Preibisz 2023-01-31 21:55:50 +01:00
parent 6c385a2282
commit 30924a6260
2 changed files with 31 additions and 18 deletions

View File

@ -30,18 +30,20 @@ def getStartDecision(chipVal, lossNum):
FS = FuzzySystem(show_banner=False) FS = FuzzySystem(show_banner=False)
FS.add_linguistic_variable("chipValue", AutoTriangle(3, terms=['low', 'average', 'high'], universe_of_discourse=[0, 21])) 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])) FS.add_linguistic_variable("numLossInRow", AutoTriangle(3, terms=['low', 'average', 'high'], universe_of_discourse=[0, 10]))
O1 = TriangleFuzzySet(0,0,13, term="leave") O1 = TriangleFuzzySet(0,0,13, term="surrender")
O2 = TriangleFuzzySet(0,13,25, term="play") O2 = TriangleFuzzySet(0,13,25, term="hit")
O3 = TriangleFuzzySet(13,25,25, term="playDouble") O3 = TriangleFuzzySet(13,15,17, term="double_down")
FS.add_linguistic_variable("decision", LinguisticVariable([O1, O2, O3], universe_of_discourse=[0, 25])) 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([ FS.add_rules([
"IF (numLossInRow IS average) AND (chipValue IS average) THEN (decision IS play)", "IF (numLossInRow IS average) AND (chipValue IS average) THEN (decision IS hit)",
"IF (numLossInRow IS low) OR (chipValue IS low) THEN (decision IS leave)", "IF (numLossInRow IS high) OR (chipValue IS low) THEN (decision IS surrender)",
"IF (numLossInRow IS high) AND (chipValue IS high) THEN (decision IS playDouble)", "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("chipValue", chipVal)

View File

@ -58,7 +58,7 @@ def dealer(hand: list, shoe: iter) -> int:
evaluation = cards_eval(hand) evaluation = cards_eval(hand)
return max(evaluation) return max(evaluation)
def AI(hand: list, face_up: str) -> str: def AI(hand: list, face_up: str, losses_in_row: int) -> str:
#TODO: add fuzzy logic #TODO: add fuzzy logic
"""Fuzzy AI """Fuzzy AI
possible player decision: possible player decision:
@ -66,7 +66,7 @@ def AI(hand: list, face_up: str) -> str:
Args: Args:
hand (list): player hand hand (list): player hand
face_up (str): dealer face up card face_up (str): dealer face up card
losses_in_row: number of losses in row in the current game
Returns: Returns:
list: player decision list: player decision
""" """
@ -74,10 +74,12 @@ def AI(hand: list, face_up: str) -> str:
# if face_up == 'ace': # if face_up == 'ace':
# return 'surrender' # return 'surrender'
# else: # else:
evaluation = cards_eval(hand) evaluation = max(cards_eval(hand))
if max(evaluation) == 11: decision = getStartDecision(evaluation, losses_in_row)
print(evaluation, decision)
if evaluation == 11:
return 'double down' return 'double down'
if max(evaluation) <= 17: if evaluation <= 17:
return 'hit' return 'hit'
else: else:
return 'stand' return 'stand'
@ -98,14 +100,15 @@ def show_game_state(player_hand: list, dealer_hand: list, decision: str='') -> N
elif not cards_eval(player_hand)[0] > 21: elif not cards_eval(player_hand)[0] > 21:
print(f"dealer: {cards_eval(dealer_hand)} player: {cards_eval(player_hand)}") print(f"dealer: {cards_eval(dealer_hand)} player: {cards_eval(player_hand)}")
def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list=[], bet: int=10) -> str: def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list=[], bet: int=10, losses_in_row: int=0) -> str:
"""Single blackjack round """Single blackjack round
Args: Args:
shoe (iter): shoe iterator shoe (iter): shoe iterator
dealer_hand (list, optional): dealer hand. Should be non empty only in SPLIT. dealer_hand (list, optional): dealer hand. Should be non empty only in SPLIT.
player_hand (list, optional): player hand. Should be non empty only in SPLIT. player_hand (list, optional): player hand. Should be non empty only in SPLIT.
bet: amount of money the player betted
losses_in_row: number of losses in row in the current game
Returns: Returns:
str: game result str: game result
""" """
@ -116,7 +119,7 @@ def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list=[], bet: int=1
decision = '' decision = ''
while decision != 'stand' or decision != 'surrender': while decision != 'stand' or decision != 'surrender':
decision = AI(player_hand, face_up) decision = AI(player_hand, face_up, losses_in_row)
show_game_state(player_hand, dealer_hand, decision) show_game_state(player_hand, dealer_hand, decision)
if decision == 'hit': if decision == 'hit':
player_hand.append(next(shoe)) player_hand.append(next(shoe))
@ -160,28 +163,36 @@ def blackjack(shoe: iter, dealer_hand: list=[], player_hand: list=[], bet: int=1
def game_loop(balance, bet) -> None: def game_loop(balance, bet) -> None:
wins, losses, draws = 0, 0, 0 wins, losses, draws = 0, 0, 0
player_blackjack = 0 player_blackjack = 0
shoe_iter = iter(shoe(10)) shoe_iter = iter(shoe(10))
losses_in_row = 0
notable_results = ['player win', 'dealer win', 'player blackjack'] notable_results = ['player win', 'dealer win', 'player blackjack']
while True: while True:
#round start #round start
try: try:
balance -= bet balance -= bet
result, game_bet = blackjack(shoe_iter, bet=bet) result, game_bet = blackjack(shoe_iter, bet=bet, losses_in_row=losses_in_row)
except StopIteration: except StopIteration:
break break
if result == 'player win': if result == 'player win':
wins += 1 wins += 1
balance += (2*game_bet) balance += (2*game_bet)
losses_in_row = 0
elif result == 'player blackjack': elif result == 'player blackjack':
wins += 1 wins += 1
# player_blackjack += 1 # player_blackjack += 1
balance += (2*game_bet) + (game_bet/2) balance += (2*game_bet) + (game_bet/2)
losses_in_row = 0
elif result == 'dealer win': elif result == 'dealer win':
losses += 1 losses += 1
losses_in_row += 1
elif result == 'push': elif result == 'push':
balance += game_bet balance += game_bet
draws += 1 draws += 1
losses_in_row = 0
if result in notable_results: if result in notable_results:
print(result) print(result)
print("="*50) print("="*50)