How to build a world-class rock-paper-scissors bot

@notthepoint

@notthepoint

@notthepoint

@notthepoint

@notthepoint

@notthepoint

@notthepoint

@notthepoint

            Icons made by 
                
                
                Freepik from www.flaticon.com 
                
                
                CC 3.0 BY
            
        

@notthepoint

@notthepoint

imperfect information

@notthepoint

zero sum

@notthepoint

Crystal ball

@notthepoint

Difficulty:

tattoo play

@notthepoint

Difficulty:

@notthepoint

19

99




  # random bot

  my_move_history = []
  their_move_history = []

  def next_turn(their_last_move)
    ['r','p','s'].sample
  end

@notthepoint




  # always rock bot

  my_move_history = []
  their_move_history = []

  def next_turn(their_last_move)
    'r'
  end

@notthepoint



  # frequency counting bot

  their_move_history = {
    'r' => 0,
    'p' => 0,
    's' => 0
  }

  counter_moves = { 'r' => 'p', 'p' => 's', 's' => 'r' }

  def next_turn(their_last_move)  
    their_move_history[their_last_move] += 1

    their_move = their_move_history.max_by{ |_,v| v }[0]

    counter_moves[their_move]
  end

@notthepoint



  # Fixed string bot

  string = 'rrpspprss'
  current_position = -1

  def next_move(opp_prev_move)
    current_position =
      (current_position + 1) % string.length

    string[current_position]
  end

@notthepoint

De Bruijn

a de Bruijn sequence of order n on a size-k alphabet A is a cyclic sequence in which every possible length-n string on A occurs exactly once as a substring

@notthepoint

rrpspprss

@notthepoint

r r r p s p p r s s

Count: 1

s s p p s p r s s r
s r r r r p s p p r

first move

latest move

@notthepoint

Count: 1

first move

latest move

s r r r r p s p p r
s s p p s p r s s r
r r r p s p p r s s

@notthepoint

Count: 2

first move

latest move

s r r r r p s p p r
s s p p s p r s s r
r r r p s p p r s s

@notthepoint

Count: 2

first move

latest move

s r r r r p s p p r
s s p p s p r s s r
r r r p s p p r s s

@notthepoint

 WINDOW SIZE         COUNT    FOLLOWING            MOVES
  10   1   p
  9   1   p
  8   1   p
  7   1   p
  6   1   p
  5   1   p
  4   2   p, r
  3   2   p, r
  2   2   p, r

@notthepoint



  # direct history bot

  their_move_history = ""
  
  counter_moves = { 'r' => 'p', 'p' => 's', 's' => 'r' }

  def next_turn(their_last_move)
    their_move_history << their_last_move
    
    regexp = /([rps]{3})([rps])[rps]*\1$/
    matches = regexp.match(their_move_str)
    their_move = matches.captures[1]

    counter_moves[their_move]
  end

@notthepoint

end of the line

get first capture

spsrrrspssssrrr

([rps]{3})([rps])[rps]*\1$

@notthepoint

([rps]{3})([rps])[rps]*\1$

exactly 3

spsrrrspssssrrr

@notthepoint

spsrrrspssssrrr

([rps]{3})([rps])[rps]*\1$

@notthepoint

0 or more

([rps]{3})([rps])[rps]*\1$

spsrrrspssssrrr

@notthepoint

STRATEGIES
Random
Frequency counting
Direct history - fixed 'window' size
Direct history - highest frequency of matches
Direct history - highest frequency of following move
Direct history - longest repeating pattern

@notthepoint

@notthepoint

@notthepoint

A

B

@notthepoint

@notthepoint

A

B

A'

@notthepoint

@notthepoint

A

B

A'

B'

@notthepoint

@notthepoint

A'

B'

@notthepoint

@notthepoint

A

B

A'

B'

A''

@notthepoint

A

B

A'

B'

A''

B''

@notthepoint

No bluff Bluff Double bluff
Random
 
Frequency counter
 
Direct history - fixed window size
Direct history - highest frequency of matches
Direct history - highest frequency of following move
Direct history - longest repeating pattern

@notthepoint

No bluff Bluff Double bluff
Random
 
  0   0   0
Frequency counter
 
  0   0   0
Direct history - fixed window size   0   0   0
Direct history - highest frequency of matches   0   0   0
Direct history - highest frequency of following move   0   0   0
Direct history - longest repeating pattern   0   0   0

@notthepoint

No bluff Bluff Double bluff
Random
 
  0   0   0
Frequency counter
 
  0   0   0
Direct history - fixed window size   1   0   0
Direct history - highest frequency of matches   0   0   0
Direct history - highest frequency of following move   0   0   0
Direct history - longest repeating pattern   0   0   0

@notthepoint

No bluff Bluff Double bluff
Random
 
  0   0   0
Frequency counter
 
  0   0   0
Direct history - fixed window size   1   0   0
Direct history - highest frequency of matches   0   0   -1
Direct history - highest frequency of following move   0   0   0
Direct history - longest repeating pattern   0   0   0

@notthepoint

No bluff Bluff Double bluff
Random, over last 10 rounds
 
  0   0   0
Frequency counter, last 10 rounds
 
  0   0   0
Direct history - fixed window size, over last 10 rounds   0   0   0
Direct history - highest frequency of matches, over last 10 rounds   0   0   0
Direct history - highest frequency of following move, over last 10 rounds   0   0   0
Direct history - longest repeating pattern, over last 10 rounds   0   0   0
Random, over last 100 rounds   0   0   0
Frequency counter, last 100 rounds   0   0   0
Direct history - fixed window size, over last 100 rounds   0   0   0
Direct history - highest frequency of matches, over last 100 rounds   0   0   0
Direct history - highest frequency of following move, over last 100 rounds   0   0   0
Direct history - longest repeating pattern, over last 100 rounds   0   0   0

@notthepoint

No bluff Bluff Double bluff
Random, over last 10 rounds
 
  0   0   0
Frequency counter, last 10 rounds
 
  0   0   0
Direct history - fixed window size, over last 10 rounds   0   0   0
Direct history - highest frequency of matches, over last 10 rounds   0   0   0
Direct history - highest frequency of following move, over last 10 rounds   0   0   0
Direct history - longest repeating pattern, over last 10 rounds   0   0   0
Random, over last 100 rounds   0   0   0
Frequency counter, last 100 rounds   0   0   0
Direct history - fixed window size, over last 100 rounds   0   0   0
Direct history - highest frequency of matches, over last 100 rounds   0   0   0
Direct history - highest frequency of following move, over last 100 rounds   0   0   0
Direct history - longest repeating pattern, over last 100 rounds   0   0   0
No bluff Bluff Double bluff
Random, over last 10 rounds
 
  0   0   0
Frequency counter, last 10 rounds
 
  0   0   0
Direct history - fixed window size, over last 10 rounds   0   0   0
Direct history - highest frequency of matches, over last 10 rounds   0   0   0
Direct history - highest frequency of following move, over last 10 rounds   0   0   0
Direct history - longest repeating pattern, over last 10 rounds   0   0   0
Random, over last 100 rounds   0   0   0
Frequency counter, last 100 rounds   0   0   0
Direct history - fixed window size, over last 100 rounds   0   0   0
Direct history - highest frequency of matches, over last 100 rounds   0   0   0
Direct history - highest frequency of following move, over last 100 rounds   0   0   0
Direct history - longest repeating pattern, over last 100 rounds   0   0   0

Over the past 10

Over the past 100

Iocaine powder

@notthepoint

thank you

@notthepoint

Ruby Paper Scissors

By dorothyjane

Ruby Paper Scissors

  • 1,123