This Video link and the text below it are essentially
the same, except the links in the text are hot:
RPS Introduction (No) Video (0 minutes) Transcript follows below
How to play Rock Paper ScissorsRock Paper Scissors is a hand-motion game played between two people. Today we will write a computer program (in English) that plays one of those people (the other player is still a person). You should design your program as a description of what the one player does -- except the computer has no hands and watching the other person is too hard at your present skill level, so we will use text input and output instead of hand motions.
By this time, you should have already worked your way through PBJ, Calculator, and the Guessing Game. You should already be familiar with the process of defining your computer program in English, then converting every part of that description into one of the Five Concepts, after which it should run in the English Computer. If you missed or skipped over these informational sessions, or if you find the next step difficult, you might go back and review one or more of these preparational sessions:
1. You Already Know HowThree times you watched me go from a vague idea to runnable code, three different programs.
2. Conditionals & Input
3. Iteration & Variables
4. Calculator
5. Guessing Game
Now you try it on your own. Click this button to open our "Integrated Development Environment" in a new window, which you can position to one side or above or below the instructions in this page:
If you don't know how to begin, Watch this video to see if it helps:
Button to open IDE
RPS Design Video (2 minutes) Transcript below
If you are doing fine, but don't know how to generate
a random number for the computer play, Watch this video (or read the transcript):
Choosing Random Rock Paper or Scissors (2 minutes) Transcript belowIf you cannot find a simple way to compare the computer and human plays, Watch this video (or read the transcript):
Comparing Rock Paper and Scissors (6 minutes) Transcript belowIf you have an English description of your game, but you do not know how to turn it into lines of "Five Concepts" items, Raise your hand in Zoom to get a Mentor to look at your description and suggest a way forward.
If each line of the English description of your game already begins with one of the keywords in the Reference section from the English IDE, but your program misbehaves when you try to run it, Watch this video to see if it helps:
Debugging Video (0 minutes) (Transcript) [video & transcript not ready yet]If you didn't see anything in the video to help your situation, Raise your hand in Zoom to get a Mentor to look at your program and suggest a way forward.
When your game runs, Raise your hand in Zoom to continue.
If you are like me and prefer to read at your own pace instead of whatever pace set in some video, You can read the transcripts here.
First of all, we will consider a single play. It has three parts:
1. SynchronizationThe synchronization is faked. The computer is very much faster than any human, so we will have it print out the words at one-second intervals, nothing more.
The computer can decide its play any time before reading the human play as input. There are numerous internet resources that purport to offer a winning strategy, but if any of them actually worked, and if both players used that strategy, it wouldn't work. I suggest your first cut use a random number to decide (more about random numbers later). Your program will then announce both plays,...
and decide who won (or if it's a tie), and print out that decision. More about the decision later.
In simple English, the program looks like this
Print "One"
Wait 1 second
Print "Two"
Wait 1 second
Print "Three"
{decide what to play}
Let myPlay = {whatever}
Input HumPlay
Print "I played " myPlay ", you played " HumPlay
{compare plays}
{announce winner}
Random rit will set variable r to some random fractional number between 0 and 1 (always less than 1). Most programming languages have a library routine that does the same thing. What we want is a discrete random number that comes back with one of only three values (rock, paper, or scissors). This is a very common requirement in games -- flip a coin: either heads or tails; roll a die: one of six; pick a card out of a shuffled deck: one out of 52; etc. -- so most random number generators have a variant that does that. When we get to Java you will learn how they spell it (it's exactly the same result, just a matter of spelling).
You can get there with simple arithmetic on the default random number by multiplying that default random fraction times the number of values you want it to choose from, then truncating it to an integer (whole number), like this:
Random rOr you can use the built-in random integer option in English:
let r = r*3
Truncate r
Random r < 3which reads "Give me a random number less than 3."
Converting that to the computer play is as simple as:
Random r < 3
if r=0 then Let myPlay = "rock"
if r=1 then Let myPlay = "paper"
Otherwise Let myPlay = "scissors"
Don't forget to declare myPlay to be a variable somewhere.
You can do that in English by presetting it as the default:
Variable myPlay = "scissors"
Random r < 3
if r=0 then Let myPlay = "rock"
if r=1 then Let myPlay = "paper"
If the English computer didn't know about random numbers, you could
still get something like that from the time of day, basically derived from
the remainder when the number of seconds in the wall clock time is divided
by three. The human player will take some variable number of seconds to
type in their input, so that the wall clock time cannot be accurately predicted.
That makes it a pretty good random number.
For example, at 8:44:29 in the morning, the seconds (from midnight) is 31469. If you divide this by 3 and truncate it to a whole number, you get 10489. Multiply that times 3 again gives 31467, so the remainder of the original division is the difference, =2. The remainder will always be 0 or 1 or 2, so you can use it to choose between rock, paper, or scissors for your play, and it will be reasonably random.
In English you'd write:
put the seconds into sDon't forget to declare Variable myPlay somewhere.
let d = s/3
Truncate d {to a whole number}
let r = s-d*3 {= the remainder}
if r=0 let myPlay = "rock"
if r=1 let myPlay = "paper"
otherwise let myPlay = "scissors"
print "Seconds = " s ", I got " r "=" myPlay {for testing only}
if myPlay = "rock" then if HumPlay = "rock" then let score = 0or you could preset a default, and reduce it to the six comparisons that are not a tie:
if myPlay = "rock" then if HumPlay = "paper" then let score = -1
if myPlay = "rock" then if HumPlay = "scissors" then let score = 1
if myPlay = "paper" then if HumPlay = "rock" then let score = 1
...
let score = 0You cannot use "otherwise" here because the mixed true/false tests confuse the English computer (for example, if both the human and the computer chose rock, the first compare is true, so English assumes no otherwise applies).
if myPlay = "rock" then if HumPlay = "paper" then let score = 1
if myPlay = "rock" then if HumPlay = "scissors" then let score = -1
...
Some programming languages let you combine the multiple conditions using "and" or "or" but the English computer does not understand those words.
When you are playing this game, you will quickly see what a drag it is to type in the whole eight letters of "scissors" (or even the four or five of "rock" or "paper"), and if you don't spell it exactly right, the compare will fail and you can't win. Usually games like this let the user type in just a single letter (the first letter is unique among the three). The English computer will even capitalize it for you, so that it doesn't matter whether the user has caps-lock set or not:
Input HumPlay,1Of course you must change the generated myPlay to be "R", "P", or "S" to match.
This much works, and you can stop here.
If you like math, there's a really elegant approach you might be interested in. If math is not your thing, just stop here, and you will have a working program. Otherwise...
If you convert the two plays into numbers (basically reverse the calculation you did for deciding the computer play) and multiply either of them (not both) times a larger number (three or ten) then adding them together gives you one of nine unique numbers, which you can test with a single conditional (so otherwise works) and your code is a little simpler, but not so easy to understand:
let h = 0
if HumPlay = "P" then let h = 1
if HumPlay = "S" then let h = 2
let score = h*10+r {r is still 0/1/2 from the random calc}
if score=01 then let score = -1 {h=rock, r=paper, comp wins}
if score=10 then let score = 1 {r=rock, h=paper, hum wins}
if score=12 then let score = -1 {h=paper, r=scis, comp wins}
...
otherwise let score = 0 {00 or 11 or 22 = tie}
A more mathematical approach would be where you convert the plays
into the ternary number system (base 3, assuming they taught you that in
school), then the difference would be the desired score. [If you do not
understand strange number systems like ternary, then you might have trouble
understanding this, but you could Google "ternary number" for a better
understanding.] Where other number systems are generally all positive,
base-3 is often represented as zero and plus or minus 1. Here is the subtraction
table (read the human play along the top, minus the computer play down
the left, and the score is the table value:
For example, if the human plays rock (1st column) and the computer plays rock also (1st row), then the difference is zero, a tie. If the computer plays paper (zero, second row), that beats the computer's rock (-1: the human lost). If the computer plays scissors (bottom row) to the human rock, rock breaks scissors (+1, the human won). And so on.
H-C -1=R 0=P 1=S -1=R 0 1 -1 0=P -1 0 1 1=S 1 -1 0
So your code might look something like this:
let score = 0
if HumPlay = "R" then let score = -1
if HumPlay = "Z" then let score = 1
if myPlay = "R" then let score = score+1
if myPlay = "S" then let score = score-1
if score>1 then let score = -1
if score<-1 then let score = 1
The first three lines convert the human play to ternary. The next
two combine turning the computer play into ternary and subtracting it from
the human play. The difference (in ternary, but not decimal) will be +1
if the human won, and -1 if the computer won, which is exactly what we
want to know.
You already have numbers for the computer play (from Random), you can subtract one from that value to convert it into signed ternary, and then those two "myPlay" conditionals turn into a simple subtract:
let score = score-(r-1)
You can also combine those last two lines into one. If you subtract
-1 from +1, the result (in decimal) is +2, which is out of range, it needs
to be wrapped around to -1; that's the first of the two lines. The other
way around it goes negative to -2 and must wrap around to +1 in the other
line. In both cases the intermediate result is (plus or minus) two, which
squared is +4. The wrap-around wants to be the negative of whatever you
had, but one instead of two, like this:
if score*score=4 then let score = -score/2
This is a little shorter than the six compare lines, but carries
oh so much more bragging rights (assuming you understand how it works).
If you get lost in the math, stick with the
six compare
lines above: it's much more important that you understand what your
program does (and therefore it works and you can explain it) than that
it looks elegant but fails in ways you do not understand and Bad Things
Happen. Programmers do not go to jail* for writing
bad code
today, but in your lifetime that will start to happen.
Don't be one of them: it might be too late after you find out.
If you still have trouble,
Raise your hand in Zoom
to get a Mentor to look at your program and suggest a way forward.
[2021 August 31]
* Jail: Most of the people designing autonomous
cars truly believe that cars can be smarter than the people who designed
them. If they convince enough legislatures and governors to agree, there
will be a million autonomous cars and trucks out there on the streets in
your lifetime. Even if the cars are smarter than people (and the physics
says otherwise), accidents will happen, stupid people will get in the way
of the cars, and at first they will blame the owner. Then a celebrity will
lose her child and hire a high-priced law firm, and they will go after
the manufacturers, who will offer up the programmers as scape-goats. That
will be the end of autonomous vehicles on city streets for a couple centuries,
but the floodgates will already be open. Once they get a few programmers
in jail, all those fine-print "Licenses" you must agree to when you start
up a new program will go in the trash and programmers everywhere will be
required to defend their code or go to jail. You need to be ready for it,
because this will happen in your lifetime.