switching19_fix

This program has been disqualified.


Authorpyfex
Submission date2011-06-23 19:31:15.186639
Rating5004
Matches played2
Win rate50.0

Source code:

# See http://overview.cc/RockPaperScissors for more information about rock, paper, scissors
# Switching with multiple different switching strategies. 450 different predictors. Maybe
# it gets disqualified for that, but let's see.

import random
import operator
from collections import defaultdict

if input == "":
  both_hist = ""
  my_hist = ""
  opp_hist = ""
  my_stats = {'R':0, 'P':0, 'S': 0}
  beat = {'P': 'S', 'S': 'R', 'R': 'P'}
  cede = {'P': 'R', 'S': 'P', 'R': 'S'}

  both_patterns = defaultdict(str)
  opp_patterns = defaultdict(str)
  my_patterns = defaultdict(str)

  def shift(n, move):
    return {0: move, 1:beat[move], 2:cede[move]}[n%2]
    
  def unshift(n, move):
    return {0: move, 1:cede[move], 2:beat[move]}[n%2]
    
  score = {'RR': 0, 'PP': 0, 'SS': 0, 'PR': 1, 'RS': 1, 'SP': 1,'RP': -1, 'SR': -1, 'PS': -1,}
  output = random.choice(["R", "P", "S"])

  candidates = [output] * 450

  performance = [[(2,0)]*6, [(2,0)]*6, [0]*6, [(2,0)]*450, 0, 0]
  main_performance = [0, 0, 0, 0, 0, 0]
  main_candidates = [output] * 6
  indices = [0, 0, 0, 0] # only the first 4 main strats are switching strats
  main_index = 0
  wins = losses = ties = 0
else:
  my_stats[output] += 1

  sc = score[output+input]
  if sc == 1:
    wins += 1
  elif sc == 0:
    ties += 1
  elif sc == -1:
    losses += 1

  both_hist += output+input
  my_hist += output
  opp_hist += input

  for length in range(min(5, len(my_hist)), 0, -1):
    opp_patterns[opp_hist[-length:]] += output + input
    my_patterns[my_hist[-length:]] += output + input
    both_patterns[both_hist[-2*length:]] += output + input

  for i, c in enumerate(candidates[:6]):
    performance[0][i] = ({1:performance[0][i][0]+1, 0: 2, -1: 2}[score[c+input]],  
                   performance[0][i][1]+score[c+input])
    performance[1][i] = ({1:performance[1][i][0]+1, 0: performance[1][i][0], -1: 2}[score[c+input]],  
                   performance[1][i][1]+score[c+input])
    performance[2][i] += score[c+input] 

  for i, c in enumerate(candidates):
    performance[3][i] = ({1:performance[3][i][0]+1, 0: 2, -1: 2}[score[c+input]],  
                   performance[3][i][1]+score[c+input])

  indices[0] = performance[0].index(max(performance[0], key=lambda x: x[0]**3+x[1]))
  indices[1] = performance[1].index(max(performance[1], key=lambda x: x[0]**3+x[1]))
  indices[2] = performance[2].index(max(performance[2]))
  indices[3] = performance[3].index(max(performance[3], key=lambda x: x[0]**3+x[1]))

  for i, c in enumerate(main_candidates):
    main_performance[i] += score[c+input]

  main_index = main_performance.index(max(main_performance))

  output = random.choice(['R', 'P', 'S'])
  candidates = [output] * 450

  for length in range(min(5, len(my_hist)), 0, -1):
    p = both_patterns[both_hist[-2*length:]]
    if p != "":
      opp = p[-1]
      my = p[-2]
      candidates[0] = beat[opp]
      candidates[1] = cede[my]
      candidates[2] = opp
      candidates[3] = my
      candidates[4] = cede[opp]
      candidates[5] = beat[my]
      for i, a in enumerate(candidates[:6]):
        for offset in range(3):
          candidates[6+24*i+offset*8] = shift(offset+wins, a)
          candidates[6+24*i+offset*8+1] = shift(offset+wins+ties, a)
          candidates[6+24*i+offset*8+2] = shift(offset+losses+ties, a)
          candidates[6+24*i+offset*8+3] = shift(offset+losses, a)
          candidates[6+24*i+offset*8+4] = unshift(offset+wins, a)
          candidates[6+24*i+offset*8+5] = unshift(offset+wins+ties, a)
          candidates[6+24*i+offset*8+6] = unshift(offset+losses+ties, a)
          candidates[6+24*i+offset*8+7] = unshift(offset+losses, a)
      main_candidates[4] = beat[opp]
      break

  for length in range(min(5, len(my_hist)), 0, -1):
    p = my_patterns[my_hist[-length:]]
    if p != "":
      opp = p[-1]
      my = p[-2]
      candidates[150] = beat[opp]
      candidates[151] = cede[my]
      candidates[152] = opp
      candidates[153] = my
      candidates[154] = cede[opp]
      candidates[155] = beat[my]
      for i, a in enumerate(candidates[150:156]):
        for offset in range(3):
          candidates[150+6+24*i+offset*8] = shift(offset+wins, a)
          candidates[150+6+24*i+offset*8+1] = shift(offset+wins+ties, a)
          candidates[150+6+24*i+offset*8+2] = shift(offset+losses+ties, a)
          candidates[150+6+24*i+offset*8+3] = shift(offset+losses, a)
          candidates[150+6+24*i+offset*8+4] = unshift(offset+wins, a)
          candidates[150+6+24*i+offset*8+5] = unshift(offset+wins+ties, a)
          candidates[150+6+24*i+offset*8+6] = unshift(offset+losses+ties, a)
          candidates[150+6+24*i+offset*8+7] = unshift(offset+losses, a)
      break

  for length in range(min(5, len(opp_hist)), 0, -1):
    p = opp_patterns[opp_hist[-length:]]
    if p != "":
      opp = p[-1]
      my = p[-2]
      candidates[300] = beat[opp]
      candidates[301] = cede[my]
      candidates[302] = opp
      candidates[303] = my
      candidates[304] = cede[opp]
      candidates[305] = beat[my]
      for i, a in enumerate(candidates[300:306]):
        for offset in range(3):
          candidates[300+6+24*i+offset*8] = shift(offset+wins, a)
          candidates[300+6+24*i+offset*8+1] = shift(offset+wins+ties, a)
          candidates[300+6+24*i+offset*8+2] = shift(offset+losses+ties, a)
          candidates[300+6+24*i+offset*8+3] = shift(offset+losses, a)
          candidates[300+6+24*i+offset*8+4] = unshift(offset+wins, a)
          candidates[300+6+24*i+offset*8+5] = unshift(offset+wins+ties, a)
          candidates[300+6+24*i+offset*8+6] = unshift(offset+losses+ties, a)
          candidates[300+6+24*i+offset*8+7] = unshift(offset+losses, a)
      break

  for i in range(4):
    main_candidates[i] = candidates[indices[i]]
  
  main_candidates[5] = cede[max([e for e in my_stats.items()], key=operator.itemgetter(1))[0]]
  output = main_candidates[main_index]