Skip to content

Instantly share code, notes, and snippets.

@20esaua
Last active May 29, 2019 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 20esaua/49198915c77cf3cf1386b81da637614c to your computer and use it in GitHub Desktop.
Save 20esaua/49198915c77cf3cf1386b81da637614c to your computer and use it in GitHub Desktop.
markov chain based rock paper scissors game (in progress)
from random import choice as random
ROCK = 1
PAPER = 2
SCISSORS = 3
out_of = 3
best = out_of -1
MOVES = {
'r' : ROCK,
'p' : PAPER,
's' : SCISSORS
}
BEAT = {
ROCK : PAPER,
PAPER : SCISSORS,
SCISSORS : ROCK
}
NAMES = {
ROCK : 'rock',
PAPER : 'paper',
SCISSORS : 'scissors'
}
class Node:
def __init__(self, parent, type):
self.children = []
self.count = 0
self.parent = parent
self.type = type
if not self.get_parent() is None:
self.get_parent().add_child(self)
def get_weight(self):
sum = 0
for child in self.get_parent().get_children():
sum += child.count
return self.count / sum
def get_children(self):
return self.children
def add_child(self, child):
self.children.append(child)
return self
def get_type(self):
return self.type
def get_parent(self):
return self.parent
root = Node(None, None)
current_node = root
default_scores = {
'you' : 0,
'me' : 0
}
global_weights = {
ROCK : 0,
PAPER : 0,
SCISSORS : 0
}
header = '\n\nYou v.s. me. Best %s out of %s.\n\n' % (best, out_of)
scores = default_scores
print(header)
while True:
# predict the player's move
predicted_move = ROCK
greatest_child = None
for child in current_node.get_children():
if greatest_child is None:
greatest_child = child
elif child.get_weight() > greatest_child.get_weight:
greatest_child = child
# no data, so just pick a random one and yolo it
if greatest_child is None:
greatest_child = {'key' : ROCK, ROCK : 0}
for child in global_weights:
if greatest_child[greatest_child['key']] < global_weights[child]:
greatest_child['key'] = child
greatest_child[child] = global_weights[child]
if greatest_child is None:
greatest_child = random([ROCK, PAPER, SCISSORS])
if not type(greatest_child) is int:
greatest_child = greatest_child.get_type()
predicted_move = greatest_child
use_move = BEAT[predicted_move]
# get player's actual move
move = 0
while True:
move = input('Your move: ').lower().strip()
for possible_move in MOVES:
if move.startswith(possible_move):
move = MOVES[possible_move]
break
if type(move) is int:
break
# check who wins
message = 'I went with %s. ' % NAMES[use_move]
if move == use_move:
message += 'Tie!'
elif BEAT[move] == use_move:
message += 'I won that round!'
scores['me'] += 1
elif move == BEAT[use_move]:
message += 'You won that round!'
scores['you'] += 1
print(message + '\n')
winner = None
for player in scores:
if scores[player] >= best:
scores = default_scores
winner = player
if not winner is None:
print('\n%s wins!' % winner)
scores = default_scores
print(header)
# update markov chain
found = False
for node in current_node.get_children():
if node.get_type() == move:
found = node
break
if not found:
current_node = Node(current_node, move)
current_node.count += 1
else:
found.count += 1
current_node = found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment