markov hunter

Authorzacstewart
Submission date2019-09-04 03:44:58.179853
Rating5165
Matches played224
Win rate49.55

Use rpsrunner.py to play unranked matches on your computer.

Source code:

from random import sample, choice
from collections import defaultdict


class Markov(object):
  MAX_SUBMOVE = 10
  BEATS = {
      'R': 'P',
      'P': 'S',
      'S': 'R'
      }

  def __init__(self):
    self.moves = []
    self.reset()

  def incrememnt_next_move(self, preceding_moves, move):
    if not preceding_moves in self.next_moves:
      self.next_moves[preceding_moves] = []
    self.next_moves[preceding_moves].append(move)

  def add_moves(self, moves):
    move = moves[-1]
    preceding_moves = tuple(moves[:-1])

    self.incrememnt_next_move(preceding_moves, move)

  def add_move(self, move):
    self.moves.append(move)

    for n in range(self.MAX_SUBMOVE):
      if len(self.moves) > n:
        self.add_moves(self.moves[-(n+2):])

  def reset(self):
    self.next_moves = {}

  # Least likely choice
  def choice(self):
    candiate_moves = list('RPS')

    for n in range(self.MAX_SUBMOVE):
      preceding_moves = tuple(self.moves[-(n+2):])

      if preceding_moves in self.next_moves:
        candiate_moves += self.next_moves[preceding_moves]

    freqs = defaultdict(int)
    for candiate_move in candiate_moves:
        freqs[candiate_move] += 1

    return min(freqs, key=freqs.get)


class MarkovHunter(object):

    PATTERN_LENGTH = 10
    BEATS = {
        'R': 'P',
        'P': 'S',
        'S': 'R'
    }

    def __init__(self):
        pass
        self.markov = Markov()
        self.pattern = [choice(self.BEATS.keys()) for _ in range(self.PATTERN_LENGTH)]
        self.i = 0
        self.matches_played = 0

    def choice(self):
        if self.matches_played > 10:
            move = self.markov.choice()
        else:
            move = self.pattern[self.i]
            self.i = (self.i + 1) % self.PATTERN_LENGTH

        self.markov.add_move(move)
        self.matches_played += 1
        return move

output = choice('RPS')

if input == '':
    model = MarkovHunter()
else:
    output = model.choice()