# Motivation

Rock-Paper-Scissors is a popular game all over the world. Let's have a competition where you get to build your own program that plays Rock-Paper-Scissors! If you don't know how the game works, you can read about it here.

The interesting thing about this game is that if you play completely randomly, on average you will do as well as your opponent, regardless of what your opponent does (i.e. you will win 33% of the time, lose 33% of the time, and tie 33% of the time). However, in practice the game is usually not completely random, because human players don't play randomly, and try to psychologically out-smart their opponents. That way it's actually a fun game! But don't worry: we'll use a mechanism to prevent you from making a random bot to spoil the fun! So let's get to the specifics.

# The Program

Imagine you are playing rock, paper, scissors with someone, and you want to write a computer program to do your next move for you. You need to write a Python procedure (called player) that takes as input the sequence of your moves and the sequence of your opponents moves represented by a list consisting only of the strings 'rock', 'paper', and 'scissors', and produces as output, your next move (either 'rock', 'paper' or 'scissors'). Your program should only be one function (which can contain other functions), and should not store state (e.g. global variables). Here is an example program that just plays the last move your opponent played:

def player(my_moves, opp_moves):
if opp_moves != []:
return opp_moves[-1]
else:
return 'rock'


# Competition Rules

Your program will need to play against three programs I build that aren't very smart. It will play 1000 rounds against each of these bots, and we will let you test this (probably on an IDE quiz on our website before submitting your program). In other words, they will probably have patterns in what moves they do, and they won't try to take your program's moves into account. To get to the next level in the competition, your program will need to beat at least two of these programs with a win rate of at least 50% (if it played randomly, it would be around 33% of the time on average). Your code should take no more than 2 seconds to complete 1000 rounds. This is not a strict limit, but try to stay within that range. You can test your program against our bots here! (Note: This may have some bugs. If certain things aren't working, please tell us!)

If your program passes the first task, it will then enter a tournament with all of the other eligible programs. Each match will have approximately 1000 rounds that you won't see followed by a best 7 out of 13 match (i.e. whoever gets 7 wins first, wins the match). The first set of ~1000 rounds will give your algorithm a chance to learn your opponent's behavior. I haven't decided the logistics of the tournament, because it will depend on the number of submissions.

Your code should be submitted here by Thursday July 26th at 17:00 UTC. You are allowed to submit two programs. (Thank our friend @areke from CS 253 for the awesome submission form!)

There will be a live tournament on Saturday July 28th at 17:00 UTC. The tournament will be hosted on Cloud 9 IDE. I will give you a link to the workspace where you can join us on Saturday before the tournament begins. Check the forums before the tournament to get the link and instructions on what to do! You do not need to sign up for Cloud 9, you just open the link on your browser and enjoy!

# Final Remarks

This is very experimental. Let us know what you what you think of this tournament, and if you like this idea, and want similar competitions in the future, let us know by voting this post up. Thanks!

If you want to test two different programs against each other, you can use the following code. Or you can write your own more elegant code.

def match(player1, player2):
moves1 = []
moves2 = []
wins1 = 0
wins2 = 0
for i in range(1000):
move1 = player1(moves1, moves2)
move2 = player2(moves2, moves1)
moves1.append(move1)
moves2.append(move2)
if winner(move1, move2) == 1:
wins1 += 1
# print "Player 1 wins! (%s vs. %s)" %(move1, move2)
elif winner(move1, move2) == -1:
wins2 += 1
# print "Player 2 wins! (%s vs. %s)" %(move1, move2)
print "Player 1 won %d games and Player 2 won %d games" %(wins1, wins2)
return

def winner(move1, move2):
dict = {'rock': 0, 'paper': 1, 'scissors': 2}
a = dict[move1]
b = dict[move2]
if a == b:
return 0
elif a - b == 1 or a - b == -2:
return 1
else:
return -1


Shayan Doroudi ♦♦
3.1k31032
accept rate: 22%

Anthony Teate ♦♦
6.7k523

4

Are multiple entries per person allowed?

(20 Jul '12, 08:09)
2

I would also want you to consider setting a given number of iterations for the match and make it public. This is, if both players will play 1000 times as in the previous example, or 1e4 / 1e6 / 1e9 etc.

That would allow as to know (by input's length) how far we are in the match.

I would compare it to human vs human RPS tournaments where they play agains the other i.e. 10 times, or to any sports when they are given i.e. 90 minutes (scoccer) or a given structure of set and games (tennis).

(20 Jul '12, 12:03)
1

@Jin You are allowed two submissions. This is updated in the post.
@Marcos Manuel When you play against the bots in the first task it will be 1000 rounds. When you play against programs your peers have built, it will be best 5 out of 9 (i.e. first to 5 wins). This is to build excitement, but if people strongly disagree with this, I can change it. Sorry for not being clear on rules earlier! This is very experimental!

(20 Jul '12, 17:07)
2

I strongly disagree with the 5 out of 9 aspect. See my answer below.

(20 Jul '12, 17:20)
2

Is there a time limit? Since we're not allowed to store state, my agent has to re-do a lot of work each move, which takes a while...

(21 Jul '12, 05:50)
1

@Johannes the rules have been updated, so your agent is given his set of previous moves. There is also a time limit of 2 seconds for 1000 rounds.

(21 Jul '12, 13:49)

What should we name our program? 'player', or whatever we choose?

(25 Jul '12, 00:23)

There seems to be a bug with the submission form. Both the 'View your first entry' and 'View your second entry' buttons link to the second entry. As a result of this, I cannot edit my first entry. Am I the only one with this problem? Please fix this!

(25 Jul '12, 00:23)
1

I'm sorry about this problem, but I don't think it was because of me... My deployed version at arekelive.appspot.com doesn't seem to have this problem. @Shayan, @Anthony Try making sure that both your_entry, and your_entry2 are passed into the template and that the url for the first one is "/{{your_entry}}" and the second is "/{{your_entry2}}". It shouldn't be too hard of a fix.

(25 Jul '12, 05:30)
1

can we use functions inside of our function player()? and why aren't we allowed to store state? Not doing so requires redoing tons code and makes it take a while... Storing state makes it much, much quicker...

(25 Jul '12, 06:06)

Saturday, July 24th 21:28 UTC? Should be Tuesday!! or July 21th!!

(25 Jul '12, 16:45)

@areke @Manuel Vidaurre You cannot keep state. I'm sorry about this, but it's too late to change that now. I'll update the rules to make it more obvious. You can use functions inside of player. All of your code should be inside of player.

(25 Jul '12, 17:35)

@Manuel Vidaurre Thanks for pointing that out!

(25 Jul '12, 17:35)

Does it have to be within 2 seconds? Without storing state it takes much longer... Maybe even 15-20 seconds...

(25 Jul '12, 17:40)

@areke I would say that's too long. Try to get it down to less than 4 seconds or so. You might have to sacrifice your program's ability, but everyone has the same limitations. Sorry! You should keep your program though, in case we have a discussion about the best programs later on.

(25 Jul '12, 18:09)

Ok, I'll try my best.

(25 Jul '12, 18:21)

Are you able to say what the range of the number of games are? Like 750-1250 where the number of games won't go below 750, and won't go above 1250.

(25 Jul '12, 23:30)

@Shayan Doroudi: You said that all code should be inside of player. If my program has additional functions and imports outside of player(), and passes Task 1, will it be accepted? And if not, why?

(26 Jul '12, 06:34)

Really, what should we name our function, 'player', or whatever we want? I need to know before it is due!

(26 Jul '12, 11:06)

I named it player like in the quiz... I don't know if this is correct because there were no specifications.

(26 Jul '12, 12:55)
showing 10 of 20 show 10 more comments

 1 Seems like I heard about udacity's rock scissor paper tournament too late. But anyway there is a rock scissor paper tournament ongoing on the net for python programmers at http://www.rpscontest.com Everyone can try their luck there. Be warned though, the rsp bots over there are mean. Some use bayesian analysis, some neural nets, some markov chains, most use fancy meta strategies to decide which of their current strategies to choose... answered 28 Aug '12, 22:05 Fabian Beyer 425●3●5
 1 To make it even funnier, it should be the ˜Rock, Paper, Scissor, Lizard, Spock" game! :) answered 24 Aug '12, 00:31 Daniel Ambrosio 27●2
 0 Hey, great idea! Does anybody know any other competitions basing on this kind of format? Unfortunately, I didn't have enough free time to participate here but the whole idea of programming a bot for playing some game against the others is really exciting. So, do you happen to know something similar elsewhere (as I don't suppose this kind of competition will be held here again anytime soon)? answered 27 Jul '12, 07:15 Tigro-1 107●14 check out TopCoder.com (28 Jul '12, 13:27) Rohit Dua Thank you! Would you mind giving me more precise direction, though? I'm having quite a hard time finding this in that vastness of TopCoder :D (30 Jul '12, 09:49) Tigro-1
 1 6 minutes from 17:00, and still nothing .... answered 28 Jul '12, 12:55 Cabuzel Thierry 234●3●4●12 3 minutes now (28 Jul '12, 12:58) anthony-4 aand it's time... (28 Jul '12, 13:00) Silviu Danie... Youuuhoouuuuu !!!!! Too much echoes here... Is there somebody ???? :-) (28 Jul '12, 13:02) Cabuzel Thierry It is time to go to bed in my country. How about yours? (28 Jul '12, 13:07) Tran Duc Hieu-1 It is 19:00 here (28 Jul '12, 13:08) Cabuzel Thierry 6 O'Clock in the evening here in rainy Ireland (28 Jul '12, 13:09) anthony-4 I will leave my robot to work on its part. I deserve a good night :D (28 Jul '12, 13:14) Tran Duc Hieu-1 Who has a bot in the comp? (28 Jul '12, 13:14) anthony-4 Me. I have 2 bots. They could have at least put a message saying they will be late, I have cancelled a drink with a friend to be here :-/ (28 Jul '12, 13:34) Cabuzel Thierry @Cabuzel, look here. :-) (28 Jul '12, 13:39) Emil-1

## echo! echo! is tournament live?

Rohit Dua
332

(28 Jul '12, 13:37)
 1 It seems like the tournament will be cancelled? There's no more update from officers. Hello!!! Helloooo!!! Anybody here? J/k. answered 28 Jul '12, 06:11 Tran Duc Hieu-1 2.6k●13●27●44 2 The tournament is not cancelled. We are getting it set up currently. Check the forums before 17:00 UTC for more info! (28 Jul '12, 09:24) Shayan Doroudi ♦♦ It should be 20 minutes from now. Will there be a delay? (28 Jul '12, 12:42) Silviu Danie...
 2 I just had an evil thought. The match() function as shown lets us modify the parameters. I'm not sure right now how I could take advantage of that, and honest cross-my-heart I wouldn't actually do it anyway, but I'd rather not have to worry about the possibility. So even though it would slow down match() a bit, it seems better to pass us tuples. answered 21 Jul '12, 21:20 Barbara Morris 1.3k●1●3●23 Oh the best way to use it would be to rewrite a part of your recent past so that it confuses the hell out of your opponent. Whatever you need of your past you can store it at the tail end :). This is really evil though. Hope this loophole is plugged. (27 Jul '12, 22:27) srean list
 5 How many codes have been qualified to second round so far? answered 27 Jul '12, 01:15 Tran Duc Hieu-1 2.6k●13●27●44 I have been wondering that as well. (27 Jul '12, 02:57) Mark
 0 import random import pickle try: output = open('movement.pck','rb') moves = pickle.load(output) output.close() except: moves = [] dict_options = {} reply = {'rock':'paper','paper':'scissors','scissors':'rock'} dict_opt = {'rock': 0, 'paper': 1, 'scissors': 2} answer = {'r':'rock','p':'paper','s':'scissors'} count1,count2 = 0,0 p1,p2 = 0,0 def learn(): if len(moves) > 2: two = moves[-1] one = moves[-2] if one == 'rock' and two == 'paper' or one == 'paper' and two == 'scissors' or one == 'scissors' and two == 'rock': if two[0] == 'p': d = answer['s'] elif two[0] == 'r': d = answer['p'] d = answer['r'] return reply[d] else: return '' def choice(): dict_options[moves.count('rock')] = 'rock' dict_options[moves.count('paper')] = 'paper' dict_options[moves.count('scissors')] = 'scissors' return dict_options[max(dict_options)] def choice2(): if not moves: return choice() my_choice = moves[-1] return reply[my_choice] def player(): "Hybrid version" trick = random.randint(0,1) smart = learn() if smart: return smart elif trick: return choice2() return reply[choice()] answered 27 Jul '12, 02:40 samuel muiru... 58●5
Question text:

Markdown Basics

• *italic* or _italic_
• **bold** or __bold__
• image?![alt text](/path/img.jpg "Title")
• numbered list: 1. Foo 2. Bar
• to add a line break simply add two spaces to where you would like the new line to be.
• basic HTML tags are also supported

×8,445
×2,260
×105
×22
×3