BUTT DESTROYER V3

This program has been disqualified.


AuthorJFreegman
Submission date2012-07-28 06:32:43.210319
Rating6176
Matches played48
Win rate64.58

Source code:

# Author: JFreegman
# Contact: JFreegman@gmail.com
# Date: July 28, 2012
# v3.0

# All code is written from scratch. The general idea is based off Iocaine Powder 
# by Dan Egnor (http://ofb.net/~egnor/iocaine.html).

import random

def get_history_match(hist, n=20, s=False):
    start = len(hist) - min(len(hist) / 2, n)
    end = len(hist)
    for i in xrange(start, end):
        partition = hist[i:end]
        match = hist[:-1].rfind(partition)
        if match != -1:
            return hist[match+len(partition)]
    if not s:
        return random_weapon()
    return None

def get_probs(total_moves, n):
    last = get_move_freq(total_moves[-n:])
    probs = {}
    t = last['total']
    probs['R'] = float(last['R']) / t
    probs['S'] = float(last['S']) / t
    probs['P'] = float(last['P']) / t
    return probs

def get_move_freq(moves):
    mov_freq = {'R': 0, 'P': 0, 'S': 0}
    count = 0
    for move in moves:
        if move == 'R':
            mov_freq['R'] += 1
        elif move == 'P':
            mov_freq['P'] += 1
        elif move == 'S':
            mov_freq['S'] += 1
        else:
            raise ValueError, 'Invalid move'
        count += 1
    mov_freq['total'] = count
    return mov_freq

def random_weapon():
    return random.choice(['R', 'P', 'S'])

if not input:
    last_strats = {}
    tot_move_freq = {'R': 0, 'P': 0, 'S': 0, 'total': 0}

    winning_move = {'R': 'P', 'P': 'S', 'S': 'R'}

    losing_move = {'R': 'S', 'P': 'R', 'S': 'P'}

    plays = {'Rr': 'W', 'Rp': 'G', 'Rs': 'E', 'Pp': 'Q', 'Pr': 'L', 
             'Ps': 'B', 'Ss': 'C', 'Sr': 'A', 'Sp': 'J'}

    opposite_plays = {'W': 'Rr', 'G': 'Rp', 'E': 'Rs', 'Q': 'Pp', 'L': 'Pr',
                      'B': 'Ps', 'C': 'Ss', 'A': 'Sr', 'J': 'Sp'}

    strat_success = {'freq20': 0,'hist': 0, 'random': 0, 'freq100': 0, 
                     'freq5': 0, 'hist5': 0,'hist20': 0,'my_hist': 0, 
                     'c_my_move_my_hist': 0, 'c1_my_move_my_hist': 0,
                     'opp_seq': 0, 'my_seq': 0, 'c_opp_seq': 0, 'c1_opp_seq': 0,
                     'c_my_seq': 0, 'c1_my_seq': 0,}
    output = random_weapon()
    opp_moves = ""
    sequences = ""
    my_moves = output

else:
    opp_moves += input
    last_opp_move = input
    sequences += plays[input+my_moves[-1].lower()]
    tot_move_freq[last_opp_move] += 1
    tot_move_freq['total'] += 1
    beat_opp = winning_move[last_opp_move]
    lose_opp = losing_move[last_opp_move]
    # update strategy success rates based on last round results
    for s in last_strats:
        if last_strats[s] == beat_opp:
            strat_success[s] += 1
        elif last_strats[s] == lose_opp:
            strat_success[s] -= 1

    # opponent's most probable move based on frequency and historic patterns
    opp_freq5 = get_probs(opp_moves, 5)
    opp_prob_f_5 = max(opp_freq5, key=opp_freq5.get)
    opp_freq20 = get_probs(opp_moves, 20)
    opp_prob_f_20 = max(opp_freq20, key=opp_freq20.get)
    opp_freq100 = get_probs(opp_moves, 100)
    opp_prob_f_100 = max(opp_freq100, key=opp_freq100.get)
    opp_prob_h = get_history_match(opp_moves)
    opp_prob_h20 = get_history_match(opp_moves, 20)
    opp_prob_h5 = get_history_match(opp_moves, 5)

    # my most probable move based on history
    my_prob_h = get_history_match(my_moves)

    # moves for each strategy
    my_move_freq5 = winning_move[opp_prob_f_5]
    my_move_freq20 = winning_move[opp_prob_f_20]
    my_move_freq100 = winning_move[opp_prob_f_100]
    my_move_hist = winning_move[opp_prob_h]
    my_move_hist20 = winning_move[opp_prob_h20]    
    my_move_hist5 = winning_move[opp_prob_h5]
    my_move_my_hist = losing_move[my_prob_h]
    c_my_move_my_hist = losing_move[my_move_my_hist]
    c1_my_move_my_hist = losing_move[c_my_move_my_hist]
    random_move = random_weapon()

    strats = {'freq20': my_move_freq20, 'freq100': my_move_freq100, 
              'hist': my_move_hist, 'random': random_move,
              'freq5': my_move_freq5,'c1_my_move_my_hist': c1_my_move_my_hist,
              'hist5': my_move_hist5, 'hist20': my_move_hist20,
              'my_hist': my_move_my_hist, 'c_my_move_my_hist': c_my_move_my_hist,
              }

    # most probable moves based on sequence pattern matches
    seq_match = get_history_match(sequences, 15, True)
    if seq_match:
        opp_prob_seq = winning_move[opposite_plays[seq_match][0]]
        my_prob_seq = losing_move[opposite_plays[seq_match][1].upper()]
        strats['opp_seq'] = opp_prob_seq
        strats['c_opp_seq'] = losing_move[opp_prob_seq]
        strats['c1_opp_seq'] = winning_move[opp_prob_seq]
        strats['my_seq'] = my_prob_seq
        strats['c_my_seq'] = losing_move[my_prob_seq]
        strats['c1_my_seq'] = winning_move[my_prob_seq]
    # Pick the strategy with the highest current success rate
    strat = max(strats, key=lambda x: strat_success[x])
    output = strats[strat]
    if random.random() <= .1:
        output = random_weapon()
    my_moves += output
    last_strats = strats