Rock-paper-scissors

From Rosetta Code
Task
Rock-paper-scissors
You are encouraged to solve this task according to the task description, using any language you may know.

The task is to implement the classic children's game Rock-paper-scissors, as well as a simple predictive AI player.

Rock Paper Scissors is a two player game. Each player chooses one of rock, paper or scissors, without knowing the other player's choice. The winner is decided by a set of rules:

  • Rock beats scissors
  • Scissors beat paper
  • Paper beats rock.

If both players choose the same thing, there is no winner for that round.

For this task, the computer will be one of the players. The operator will select Rock, Paper or Scissors and the computer will keep a record of the choice frequency, and use that information to make a weighted random choice in an attempt to defeat its opponent.

Extra credit: easy support for additional weapons.

Ada

<lang Ada>with Ada.Text_IO; with Ada.Numerics.Float_Random;

procedure Rock_Paper_Scissors is

  package Rand renames Ada.Numerics.Float_Random;
  Gen: Rand.Generator;
  type Choice is (Rock, Paper, Scissors);
  Cnt: array (Choice) of Natural := (1, 1, 1);
    -- for the initialization: pretend that each of Rock, Paper, 
    -- and Scissors, has been played once by the human
    -- else the first computer choice would be deterministic
  function Computer_Choice return Choice is
     Random_Number: Natural :=
       Integer(Rand.Random(Gen)
         * (Float(Cnt(Rock)) + Float(Cnt(Paper)) + Float(Cnt(Scissors))));
  begin
     if Random_Number < Cnt(Rock) then
        -- guess the human will choose Rock
        return Paper;
     elsif Random_Number - Cnt(Rock) < Cnt(Paper) then
        -- guess the human will choose Paper
        return Scissors;
     else -- guess the human will choose Scissors
        return Rock;
     end if;
  end Computer_Choice;
  Finish_The_Game: exception;
  function Human_Choice return Choice is
     Done: Boolean := False;
     T: constant String
       := "enter ""r"" for Rock, ""p"" for Paper, or ""s"" for Scissors""!";
     U: constant String
       := "or enter ""q"" to Quit the game";
     Result: Choice;
  begin
     Ada.Text_IO.Put_Line(T);
     Ada.Text_IO.Put_Line(U);
     while not Done loop
        Done := True;
        declare
           S: String := Ada.Text_IO.Get_Line;
        begin
           if S="r" or S="R" then
              Result := Rock;
           elsif S="p" or S = "P" then
              Result := Paper;
           elsif S="s" or S="S" then
              Result := Scissors;
           elsif S="q" or S="Q" then
              raise Finish_The_Game;
           else
              Done := False;
           end if;
        end;
     end loop;
     return Result;
  end Human_Choice;
  type Result is (Human_Wins, Draw, Computer_Wins);
  function "<" (X, Y: Choice) return Boolean is
     -- X < Y if X looses against Y
  begin
     case X is
        when Rock => return  (Y = Paper);
        when Paper => return (Y = Scissors);
        when Scissors => return (Y = Rock);
     end case;
  end "<";
  Score: array(Result) of Natural := (0, 0, 0);
  C,H: Choice;
  Res: Result;

begin

  -- play the game
  loop
     C := Computer_Choice;  -- the computer makes its choice first
     H := Human_Choice;     -- now ask the player for his/her choice
     Cnt(H) := Cnt(H) + 1;  -- update the counts for the AI
     if C < H then
        Res := Human_Wins;
     elsif H < C then
        Res := Computer_Wins;
     else
        Res := Draw;
     end if;
     Ada.Text_IO.Put_Line("COMPUTER'S CHOICE: " & Choice'Image(C)
                            & "       RESULT: " & Result'Image(Res));
     Ada.Text_IO.New_Line;
     Score(Res) := Score(Res) + 1;
  end loop;

exception

  when Finish_The_Game =>
     Ada.Text_IO.New_Line;
     for R in Score'Range loop
        Ada.Text_IO.Put_Line(Result'Image(R) & Natural'Image(Score(R)));
     end loop;

end Rock_Paper_Scissors;</lang>

First and last few lines of the output of a game, where the human did permanently choose Rock:

./rock_paper_scissors 
enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: SCISSORS       RESULT: HUMAN_WINS

enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: ROCK       RESULT: DRAW

enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: SCISSORS       RESULT: HUMAN_WINS

enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: ROCK       RESULT: DRAW


[...]


enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: ROCK       RESULT: DRAW

enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
r
COMPUTER'S CHOICE: PAPER       RESULT: COMPUTER_WINS

enter "r" for Rock, "p" for Paper, or "s" for Scissors"!
or enter "q" to Quit the game
q

HUMAN_WINS 2
DRAW 5
COMPUTER_WINS 21

AutoHotkey

<lang AHK>#Warn DllCall("AllocConsole") Write("Welcome to Rock-Paper-Scissors`nMake a choice: ")

cR := cP := cS := 0 ; user choice count userChoice := Read() Write("My choice: " . cpuChoice := MakeChoice(1, 1, 1))

Loop { Write(DecideWinner(userChoice, cpuChoice) . "`nMake A Choice: ") cR += SubStr(userChoice, 1, 1) = "r", cP += InStr(userChoice, "P"), cS += InStr(userChoice, "S") userChoice := Read() Write("My Choice: " . cpuChoice := MakeChoice(cR, cP, cS)) }

MakeChoice(cR, cP, cS){ ; parameters are number of times user has chosen each item total := cR + cP + cS

Random, rand, 0.0, 1.0 if (rand >= 0 and rand <= cR / total) return "Paper" else if (rand > cR / total and rand <= (cR + cP) / total) return "Scissors" else return "Rock" }

DecideWinner(user, cpu){ user := SubStr(user, 1, 1), cpu := SubStr(cpu, 1, 1) if (user = cpu) return "`nTie!" else if (user = "r" and cpu = "s") or (user = "p" and cpu = "r") or (user = "s" and cpu = "p") return "`nYou Win!" else return "`nI Win!" }

Read(){ FileReadLine, a, CONIN$, 1 return a } Write(txt){ FileAppend, % txt, CONOUT$ }</lang>

AutoIt

I´ve created a GUI to play and show results, no Console Input

<lang autoit> RPS()

Func RPS() Local $ai_Played_games[4] $ai_Played_games[0] = 3 For $I = 1 To 3 $ai_Played_games[$I] = 1 Next $RPS = GUICreate("Rock Paper Scissors", 338, 108, 292, 248) $Rock = GUICtrlCreateButton("Rock", 8, 8, 113, 25, 131072) $Paper = GUICtrlCreateButton("Paper", 8, 40, 113, 25, 131072) $Scissors = GUICtrlCreateButton("Scissors", 8, 72, 113, 25, 131072) $Label1 = GUICtrlCreateLabel("W:", 136, 8, 18, 17) $Wins = GUICtrlCreateLabel("0", 160, 8, 36, 17) $Label3 = GUICtrlCreateLabel("L:", 208, 8, 13, 17) $Looses = GUICtrlCreateLabel("0", 224, 8, 36, 17) $Label5 = GUICtrlCreateLabel("D:", 272, 8, 15, 17) $Deuce = GUICtrlCreateLabel("0", 296, 8, 36, 17) $Displaybutton = GUICtrlCreateButton("", 136, 48, 193, 49, 131072) GUICtrlSetState($ai_Played_games, 128) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case -3 Exit Case $Rock $Ret = _RPS_Eval(1, $ai_Played_games) GUICtrlSetData($Displaybutton, $Ret) If $Ret = "Deuce" Then GUICtrlSetData($Deuce, Guictrlread($Deuce)+1) Elseif $Ret = "You Loose" Then GUICtrlSetData($Looses, Guictrlread($Looses)+1) Elseif $Ret = "You Win" Then GUICtrlSetData($Wins, Guictrlread($Wins)+1) EndIf Case $Paper $Ret = _RPS_Eval(2, $ai_Played_games) GUICtrlSetData($Displaybutton, $Ret) If $Ret = "Deuce" Then GUICtrlSetData($Deuce, Guictrlread($Deuce)+1) Elseif $Ret = "You Loose" Then GUICtrlSetData($Looses, Guictrlread($Looses)+1) Elseif $Ret = "You Win" Then GUICtrlSetData($Wins, Guictrlread($Wins)+1) EndIf Case $Scissors $Ret = _RPS_Eval(3, $ai_Played_games) GUICtrlSetData($Displaybutton, $Ret) If $Ret = "Deuce" Then GUICtrlSetData($Deuce, Guictrlread($Deuce)+1) Elseif $Ret = "You Loose" Then GUICtrlSetData($Looses, Guictrlread($Looses)+1) Elseif $Ret = "You Win" Then GUICtrlSetData($Wins, Guictrlread($Wins)+1) EndIf EndSwitch WEnd

EndFunc  ;==>RPS

Func _RPS_Eval($i_Player_Choose, $ai_Played_games) Local $i_choice = 1 $i_rnd = Random(1, 1000, 1) $i_choose_1 = ($ai_Played_games[1] / $ai_Played_games[0] * 1000) $i_choose_2 = ($ai_Played_games[2] / $ai_Played_games[0] * 1000) $i_choose_3 = ($ai_Played_games[3] / $ai_Played_games[0] * 1000) If $i_rnd < $i_choose_1 Then $i_choice = 2 ElseIf $i_rnd < $i_choose_1 + $i_choose_2 And $i_rnd > $i_choose_1 Then $i_choice = 3 ElseIf $i_rnd < $i_choose_1 + $i_choose_2 + $i_choose_3 And $i_rnd > $i_choose_1 + $i_choose_2 Then $i_choice = 1 EndIf $ai_Played_games[0] += 1 If $i_Player_Choose = 1 Then $ai_Played_games[1] += 1 If $i_choice = 1 Then Return "Deuce" If $i_choice = 2 Then Return "You Loose" If $i_choice = 3 Then Return "You Win" ElseIf $i_Player_Choose = 2 Then $ai_Played_games[2] += 1 If $i_choice = 2 Then Return "Deuce" If $i_choice = 3 Then Return "You Loose" If $i_choice = 1 Then Return "You Win" ElseIf $i_Player_Choose = 3 Then $ai_Played_games[3] += 1 If $i_choice = 3 Then Return "Deuce" If $i_choice = 1 Then Return "You Loose" If $i_choice = 2 Then Return "You Win" EndIf EndFunc  ;==>_RPS_Eval

</lang>

BASIC

Works with: QBasic

<lang qbasic>DIM pPLchoice(1 TO 3) AS INTEGER, pCMchoice(1 TO 3) AS INTEGER DIM choices(1 TO 3) AS STRING DIM playerwins(1 TO 3) AS INTEGER DIM playerchoice AS INTEGER, compchoice AS INTEGER DIM playerwon AS INTEGER, compwon AS INTEGER, tie AS INTEGER DIM tmp AS INTEGER

' Do it this way for QBasic; FreeBASIC supports direct array assignment. DATA "rock", "paper", "scissors" FOR tmp = 1 to 3

   READ choices(tmp)

NEXT DATA 3, 1, 2 FOR tmp = 1 to 3

   READ playerwins(tmp)

NEXT

RANDOMIZE TIMER

DO

   ' Computer chooses first to ensure there's no "cheating".
   compchoice = INT(RND * (pPLchoice(1) + pPLchoice(2) + pPLchoice(3) + 3))
   SELECT CASE compchoice
       CASE 0 to (pPLchoice(1))
           ' Player past choice: rock; choose paper.
           compchoice = 2
       CASE (pPLchoice(1) + 1) TO (pPLchoice(1) + pPLchoice(2) + 1)
           ' Player past choice: paper; choose scissors.
           compchoice = 3
       CASE (pPLchoice(1) + pPLchoice(2) + 2) TO (pPLchoice(1) + pPLchoice(2) + pPLchoice(3) + 2)
           ' Player past choice: scissors; choose rock.
           compchoice = 1
   END SELECT
   PRINT "Rock, paper, or scissors ";
   DO
       PRINT "[1 = rock, 2 = paper, 3 = scissors, 0 to quit]";
       INPUT playerchoice
   LOOP WHILE (playerchoice < 0) OR (playerchoice > 3)
   IF 0 = playerchoice THEN EXIT DO
   pCMchoice(compchoice) = pCMchoice(compchoice) + 1
   pPLchoice(playerchoice) = pPLchoice(playerchoice) + 1
   PRINT "You chose "; choices(playerchoice); " and I chose "; choices(compchoice); ". ";
   IF (playerchoice) = compchoice THEN
       PRINT "Tie!"
       tie = tie + 1
   ELSEIF (compchoice) = playerwins(playerchoice) THEN
       PRINT "You won!"
       playerwon = playerwon + 1
   ELSE
       PRINT "I won!"
       compwon = compwon + 1
   END IF

LOOP

PRINT "Some useless statistics:" PRINT "You won "; STR$(playerwon); " times, and I won "; STR$(compwon); " times; "; STR$(tie); " ties." PRINT , choices(1), choices(2), choices(3) PRINT "You chose:", pPLchoice(1), pPLchoice(2), pPLchoice(3) PRINT " I chose:", pCMchoice(1), pCMchoice(2), pCMchoice(3)</lang>

A sample game:

$ ./rokpprscr
Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 1
You chose rock and I chose paper. I won!
Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 1
You chose rock and I chose scissors. You won!

[... 56 more times choosing "rock"...]

Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 1
You chose rock and I chose paper. I won!
Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 1
You chose rock and I chose paper. I won!
Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 3
You chose scissors and I chose paper. You won!
Rock, paper, or scissors [1 = rock, 2 = paper, 3 = scissors, 0 to quit]? 
Some useless statistics:
You won  5 times, and I won  54 times;  2 ties.
              rock          paper         scissors
You chose:     60            0             1 
  I chose:     2             55            4
Works with: uBasic

This works with a tiny, integer BASIC interpreter. The expression:

CHOOSE X=3

Is equivalent to:

LET X=INT(RND(1)*3)

This implementation uses a 6-bits binary scheme, where the lower three bits represent the choice of the user and the higher three bits the choice of the computer:

<lang ubasic> 20 LET P=0: LET Q=0: LET Z=0

30 INPUT "Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? ", A
40 IF A>3 THEN GOTO 400
50 IF A=3 THEN LET A=4
60 IF A<1 THEN GOTO 400
70 CHOOSE C=3 : LET D=4: FOR B=1 TO C+1 : LET D = D+D : NEXT : GOTO (A+D)*10
90 Z=Z+1 : PRINT "We both chose 'rock'. It's a draw." : GOTO 30

100 P=P+1 : PRINT "You chose 'paper', I chose 'rock'. You win.." : GOTO 30 120 Q=Q+1 : PRINT "You chose 'scissors', I chose 'rock'. I win!" : GOTO 30 170 Q=Q+1 : PRINT "You chose 'rock', I chose 'paper'. I win!" : GOTO 30 180 Z=Z+1 : PRINT "We both chose 'paper'. It's a draw." : GOTO 30 200 P=P+1 : PRINT "You chose 'scissors', I chose 'paper'. You win.." : GOTO 30 330 P=P+1 : PRINT "You chose 'rock', I chose 'scissors'. You win.." : GOTO 30 340 Q=Q+1 : PRINT "You chose 'paper', I chose 'scissors'. I win!" : GOTO 30 360 Z=Z+1 : PRINT "We both chose 'scissors'. It's a draw." : GOTO 30 400 PRINT "There were ";Z;" draws. I lost ";P;" times, you lost ";Q;" times." : END</lang>

A sample game:

Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 1
You chose 'rock', I chose 'paper'. I win!
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 2
You chose 'paper', I chose 'scissors'. I win!
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 3
You chose 'scissors', I chose 'paper'. You win..
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 1
You chose 'rock', I chose 'paper'. I win!
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 2
We both chose 'paper'. It's a draw.
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 3
You chose 'scissors', I chose 'rock'. I win!
Rock, paper, or scissors (1 = rock, 2 = paper, 3 = scissors)? 4
There were 1 draws. I lost 1 times, you lost 4 times.

BBC BASIC

<lang bbcbasic>PRINT"Welcome to the game of rock-paper-scissors" PRINT "Each player guesses one of these three, and reveals it at the same time." PRINT "Rock blunts scissors, which cut paper, which wraps stone." PRINT "If both players choose the same, it is a draw!" PRINT "When you've had enough, choose Q." DIM rps%(2),g$(3) g$()="rock","paper","scissors" total%=0 draw%=0 pwin%=0 cwin%=0 c%=RND(3) PRINT"What is your move (press R, P, or S)?" REPEAT

 REPEAT q$=GET$ UNTIL INSTR("RPSrpsQq",q$)>0
 g%=(INSTR("RrPpSsQq",q$)-1) DIV 2
 IF g%>2 THEN PROCsummarise:END
 total%+=1
 rps%(g%)+=1
 PRINT"You chose ";g$(g%);" and I chose ";g$(c%);
 CASE g%-c% OF
   WHEN 0:
     PRINT ". It's a draw"
     draw%+=1
   WHEN 1,-2:
     PRINT ". You win!"
     pwin%+=1
   WHEN -1,2:
     PRINT ". I win!"
     cwin%+=1
   ENDCASE
 c%=FNmove(rps%(),total%)

UNTIL FALSE END

DEFPROCsummarise PRINT "You won ";pwin%;", and I won ";cwin%;". There were ";draw%;" draws" PRINT "Thanks for playing!" ENDPROC

DEFFNmove(p%(),t%) LOCAL r% r%=RND(total%) IF r%<=p%(0) THEN =1 IF r%<=p%(0)+p%(1) THEN =2 =0</lang>

Sample output:

Welcome to the game of rock-paper-scissors
Each player guesses one of these three, and reveals it at the same time.
Rock blunts scissors, which cut paper, which wraps stone.
If both players choose the same, it is a draw!
When you've had enough, choose Q.
What is your move (press R, P, or S)?
You chose rock and I chose paper. I win!
You chose scissors and I chose paper. You win!
You chose scissors and I chose paper. You win!
You chose scissors and I chose paper. You win!
You chose scissors and I chose paper. You win!
You chose scissors and I chose rock. I win!
You chose paper and I chose paper. It's a draw
You chose paper and I chose rock. You win!
You chose paper and I chose rock. You win!
You chose paper and I chose paper. It's a draw
You chose paper and I chose paper. It's a draw
You chose paper and I chose rock. You win!
You chose scissors and I chose rock. I win!
You chose scissors and I chose scissors. It's a draw
You chose scissors and I chose rock. I win!
You chose scissors and I chose scissors. It's a draw
You chose scissors and I chose rock. I win!
You won 7, and I won 5. There were 5 draws
Thanks for playing!

C

<lang C>#include <stdio.h>

  1. include <stdlib.h>

int rand_i(int n) { int rand_max = RAND_MAX - (RAND_MAX % n); int ret; while ((ret = rand()) >= rand_max); return ret/(rand_max / n); }

int weighed_rand(int *tbl, int len) { int i, sum, r; for (i = 0, sum = 0; i < len; sum += tbl[i++]); if (!sum) return rand_i(len);

r = rand_i(sum) + 1; for (i = 0; i < len && (r -= tbl[i]) > 0; i++); return i; }

int main() { int user_action, my_action; int user_rec[] = {0, 0, 0}; const char *names[] = { "Rock", "Paper", "Scissors" }; char str[2]; const char *winner[] = { "We tied.", "Meself winned.", "You win." };

while (1) { my_action = (weighed_rand(user_rec, 3) + 1) % 3;

printf("\nYour choice [1-3]:\n" " 1. Rock\n 2. Paper\n 3. Scissors\n> ");

/* scanf is a terrible way to do input. should use stty and keystrokes */ if (!scanf("%d", &user_action)) { scanf("%1s", str); if (*str == 'q') return 0; continue; } user_action --; if (user_action > 2 || user_action < 0) { printf("invalid choice; again\n"); continue; } printf("You chose %s; I chose %s. %s\n", names[user_action], names[my_action], winner[(my_action - user_action + 3) % 3]);

user_rec[user_action]++; } }</lang>

This example is incorrect. Please fix the code and remove this message.

Details: This example does not seem to use the weighted average AI from the task description.

Here's another code: (Does it using a while loop and is much shorter then the above) <lang C>

  1. include <stdio.h> // Standard IO
  2. include <stdlib.h> // other stuff
  3. include <time.h>
  4. include <string.h>

int main(int argc, const char *argv[]){ printf("Hello, Welcome to rock-paper-scissors\nBy The Elite Noob\n"); while(1){ // infinite loop :) printf("\n\nPlease type in 1 for Rock, 2 For Paper, 3 for Scissors, 4 to quit\n"); srand(time(NULL)); int user, comp = (rand()%3)+1; char line[255]; fgets(line, sizeof(line), stdin); while(sscanf(line, "%d", &user) != 1) { //1 match of defined specifier on input line

 			printf("You have not entered an integer.\n");

fgets(line, sizeof(line), stdin); } if(user != 1 && user != 2 && user != 3 && user != 4){printf("Please enter a valid number!\n");continue;} char umove[10], cmove[10]; if(comp == 1){strcpy(cmove, "Rock");}else if(comp == 2){strcpy(cmove, "Paper");}else{strcpy(cmove, "Scissors");} if(user == 1){strcpy(umove, "Rock");}else if(user == 2){strcpy(umove, "Paper");}else{strcpy(umove, "Scissors");} if(user == 4){printf("Goodbye! Thanks for playing!\n");break;} if((comp == 1 && user == 3)||(comp == 2 && user == 1)||(comp == 3 && user == 2)){ printf("Comp Played: %s\nYou Played: %s\nSorry, You Lost!\n", cmove, umove); }else if(comp == user){ printf("Comp Played: %s\nYou Played: %s\nYou Tied :p\n", cmove, umove);} else{ printf("Comp Played: %s\nYou Played: %s\nYay, You Won!\n", cmove, umove); }}return 1;} </lang>

C++

Version using Additional Weapons

<lang cpp>

  1. include <windows.h>
  2. include <iostream>
  3. include <string>

//------------------------------------------------------------------------------- using namespace std;

//------------------------------------------------------------------------------- enum choices { ROCK, SPOCK, PAPER, LIZARD, SCISSORS, MX_C }; enum indexes { PLAYER, COMPUTER, DRAW };

//------------------------------------------------------------------------------- class stats { public:

   stats() : _draw( 0 )
   {
       ZeroMemory( _moves, sizeof( _moves ) );

ZeroMemory( _win, sizeof( _win ) );

   }
   void draw()		        { _draw++; }
   void win( int p )	        { _win[p]++; }
   void move( int p, int m )   { _moves[p][m]++; }
   int getMove( int p, int m ) { return _moves[p][m]; }
   string format( int a )
   {

char t[32]; wsprintf( t, "%.3d", a ); string d( t ); return d;

   }
   void print()
   {
       string  d = format( _draw ),

pw = format( _win[PLAYER] ), cw = format( _win[COMPUTER] ), pr = format( _moves[PLAYER][ROCK] ), cr = format( _moves[COMPUTER][ROCK] ),

              pp = format( _moves[PLAYER][PAPER] ),	cp = format( _moves[COMPUTER][PAPER] ),

ps = format( _moves[PLAYER][SCISSORS] ), cs = format( _moves[COMPUTER][SCISSORS] ), pl = format( _moves[PLAYER][LIZARD] ), cl = format( _moves[COMPUTER][LIZARD] ), pk = format( _moves[PLAYER][SPOCK] ), ck = format( _moves[COMPUTER][SPOCK] );

system( "cls" ); cout << endl; cout << "+----------+-------+--------+--------+---------+----------+--------+---------+" << endl; cout << "| | WON | DRAW | ROCK | PAPER | SCISSORS | LIZARD | SPOCK |" << endl; cout << "+----------+-------+--------+--------+---------+----------+--------+---------+" << endl; cout << "| PLAYER | " << pw << " | | " << pr << " | " << pp << " | " << ps << " | " << pl << " | " << pk << " |" << endl; cout << "+----------+-------+ " << d << " +--------+---------+----------+--------+---------+" << endl; cout << "| COMPUTER | " << cw << " | | " << cr << " | " << cp << " | " << cs << " | " << cl << " | " << ck << " |" << endl; cout << "+----------+-------+--------+--------+---------+----------+--------+---------+" << endl; cout << endl << endl;

system( "pause" );

   }

private:

   int _moves[2][MX_C], _win[2], _draw;

}; //------------------------------------------------------------------------------- class rps { private:

   int makeMove()
   {

int total = 0, r, s; for( int i = 0; i < MX_C; total += statistics.getMove( PLAYER, i++ ) ); r = rand() % total;

s = statistics.getMove( PLAYER, ROCK ); if( r < s ) return SPOCK; r -= s;

s = statistics.getMove( PLAYER, SPOCK ); if( r < s ) return PAPER; r -= s;

s = statistics.getMove( PLAYER, PAPER ); if( r < s ) return LIZARD; r -= s;

s = statistics.getMove( PLAYER, LIZARD ); if( r < s ) return SCISSORS; r -= s;

return ROCK;

   }
   void printMove( int p, int m )
   {

if( p == COMPUTER ) cout << "My move: "; else cout << "Your move: ";

switch( m ) { case ROCK: cout << "ROCK\n"; break; case PAPER: cout << "PAPER\n"; break; case SCISSORS: cout << "SCISSORS\n"; break; case LIZARD: cout << "LIZARD\n"; break; case SPOCK: cout << "SPOCK\n"; }

   }

public:

   rps()
   {

checker[ROCK][ROCK] = 2; checker[ROCK][PAPER] = 1; checker[ROCK][SCISSORS] = 0; checker[ROCK][LIZARD] = 0; checker[ROCK][SPOCK] = 1; checker[PAPER][ROCK] = 0; checker[PAPER][PAPER] = 2; checker[PAPER][SCISSORS] = 1; checker[PAPER][LIZARD] = 1; checker[PAPER][SPOCK] = 0; checker[SCISSORS][ROCK] = 1; checker[SCISSORS][PAPER] = 0; checker[SCISSORS][SCISSORS] = 2; checker[SCISSORS][LIZARD] = 0; checker[SCISSORS][SPOCK] = 1; checker[LIZARD][ROCK] = 1; checker[LIZARD][PAPER] = 0; checker[LIZARD][SCISSORS] = 1; checker[LIZARD][LIZARD] = 2; checker[LIZARD][SPOCK] = 0; checker[SPOCK][ROCK] = 0; checker[SPOCK][PAPER] = 1; checker[SPOCK][SCISSORS] = 0; checker[SPOCK][LIZARD] = 1; checker[SPOCK][SPOCK] = 2;

   }
   void play()
   {

int p, r, m; while( true ) { cout << "What is your move (1)ROCK (2)SPOCK (3)PAPER (4)LIZARD (5)SCISSORS (0)Quit ? "; cin >> p; if( !p || p < 0 ) break; if( p > 0 && p < 6 ) { p--; cout << endl; printMove( PLAYER, p ); statistics.move( PLAYER, p );

m = makeMove(); statistics.move( COMPUTER, m ); printMove( COMPUTER, m );

r = checker[p][m]; switch( r ) { case DRAW: cout << endl << "DRAW!" << endl << endl; statistics.draw(); break; case COMPUTER: cout << endl << "I WIN!" << endl << endl; statistics.win( COMPUTER ); break; case PLAYER: cout << endl << "YOU WIN!" << endl << endl; statistics.win( PLAYER );

} system( "pause" ); } system( "cls" ); } statistics.print();

   }

private:

   stats statistics;
   int checker[MX_C][MX_C];

}; //------------------------------------------------------------------------------- int main( int argc, char* argv[] ) {

   srand( GetTickCount() );
   rps game;
   game.play();
   return 0;

} //------------------------------------------------------------------------------- </lang>

Sample output:

What is your move (1)ROCK (2)SPOCK (3)PAPER (4)LIZARD (5)SCISSORS (0)Quit ? 1

Your move: ROCK
My move: PAPER

I WIN!

What is your move (1)ROCK (2)SPOCK (3)PAPER (4)LIZARD (5)SCISSORS (0)Quit ? 3

Your move: PAPER
My move: SPOCK

YOU WIN!

What is your move (1)ROCK (2)SPOCK (3)PAPER (4)LIZARD (5)SCISSORS (0)Quit ? 1

Your move: SPOCK
My move: LIZARD

I WIN!

[...]

+----------+-------+--------+--------+---------+----------+--------+---------+
|          |  WON  |  DRAW  |  ROCK  |  PAPER  | SCISSORS | LIZARD |  SPOCK  |
+----------+-------+--------+--------+---------+----------+--------+---------+
|  PLAYER  |  001  |        |   003  |   002   |   000    |  000   |   009   |
+----------+-------+   005  +--------+---------+----------+--------+---------+
| COMPUTER |  008  |        |   000  |   005   |   000    |  001   |   008   |
+----------+-------+--------+--------+---------+----------+--------+---------+

D

Translation of: Python

<lang d>import std.stdio, std.random, std.string, std.array,

      std.typecons, std.traits, std.conv, std.algorithm;

enum Choice { rock, paper, scissors } immutable order = [EnumMembers!Choice];

uint[order.length] choiceFrequency;

Choice whatBeats(in Choice ch) pure /*nothrow*/ {

   return order[(order.countUntil(ch) + 1) % $];

}

Nullable!Choice checkWinner(in Choice a, in Choice b) pure /*nothrow*/ {

   alias TResult = typeof(return);
   if (b == whatBeats(a))
       return TResult(b);
   else if (a == whatBeats(b))
       return TResult(a);
   return TResult();

}

Choice getRandomChoice() /*nothrow*/ {

   if (choiceFrequency[].reduce!q{a + b} == 0)
       return uniform!Choice;
   return order[choiceFrequency.dice].whatBeats;

}

void main() {

   writeln("Rock-Paper-Scissors Game");
   while (true) {
       write("Your choice (empty to end game): ");
       immutable humanChoiceStr = readln.strip.toLower;
       if (humanChoiceStr.empty)
           break;
       Choice humanChoice;
       try {
           humanChoice = humanChoiceStr.to!Choice;
       } catch (ConvException e) {
           writeln("Wrong input: ", humanChoiceStr);
           continue;
       }
       immutable compChoice = getRandomChoice;
       write("Computer picked ", compChoice, ", ");
       // Don't register the player choice until after
       // the computer has made its choice.
       choiceFrequency[humanChoice]++;
       immutable winner = checkWinner(humanChoice, compChoice);
       if (winner.isNull)
           writeln("Nobody wins!");
       else
           writeln(winner.get, " wins!");
   }

}</lang>

Output example:
Rock-Paper-Scissors Game
Your choice (empty to end game): rock
Computer picked scissors, rock wins!
Your choice (empty to end game): scissors
Computer picked paper, scissors wins!
Your choice (empty to end game):

Alternative Version

This version is more similar to the functional solutions. <lang d>import std.stdio, std.random, std.string, std.conv, std.array,

      std.typecons;

enum Choice { rock, paper, scissors }

bool beats(in Choice c1, in Choice c2) pure nothrow {

   return (c1 == Choice.paper    && c2 == Choice.rock) ||
          (c1 == Choice.scissors && c2 == Choice.paper) ||
          (c1 == Choice.rock     && c2 == Choice.scissors);

}

Choice genMove(in int r, in int p, in int s) {

   immutable x = uniform!"[]"(1, r + p + s);
   if (x < s)      return Choice.rock;
   if (x <= s + r) return Choice.paper;
   else            return Choice.scissors;

}

Nullable!To maybeTo(To, From)(From x) {

   try {
       return typeof(return)(x.to!To);
   } catch (ConvException e) {
       return typeof(return)();
   }

}

void main() {

   int r = 1, p = 1, s = 1;
   while (true) {
       write("rock, paper or scissors? ");
       immutable hs = readln.strip.toLower;
       if (hs.empty)
           break;
       immutable h = hs.maybeTo!Choice;
       if (h.isNull) {
           writeln("Wrong input: ", hs);
           continue;
       }
       immutable c = genMove(r, p, s);
       writeln("Player: ", h, " Computer: ", c);
            if (beats(h, c)) writeln("Player wins\n");
       else if (beats(c, h)) writeln("Player loses\n");
       else                  writeln("Draw\n");
       final switch (h.get) {
           case Choice.rock:     r++; break;
           case Choice.paper:    p++; break;
           case Choice.scissors: s++; break;
       }
   }

}</lang>

Output:
rock, paper or scissors? paper
Player: paper Computer: paper
Draw

rock, paper or scissors? scissors
Player: scissors Computer: scissors
Draw

rock, paper or scissors? rock
Player: rock Computer: paper
Player loses

rock, paper or scissors? rock
Player: rock Computer: paper
Player loses

rock, paper or scissors?

Erlang

<lang erlang> -module(rps). -compile(export_all).

play() ->

   loop([1,1,1]).

loop([R,P,S]=Odds) ->

   case io:fread("What is your move? (R,P,S,Q) ","~c") of
       {ok,["Q"]} -> io:fwrite("Good bye!~n");
       {ok,Human} when Human == $R; Human == $P; Human == $S ->
           io:fwrite("Your move is ~s.~n",
                     [play_to_string(Human)]),
           Computer = select_play(Odds),
           io:fwrite("My move is ~s~n",
                     [play_to_string(Computer)]),
           case {beats(Human,Computer),beats(Computer,Human)} of
               {true,_} -> io:fwrite("You win!~n");
               {_,true} -> io:fwrite("I win!~n");
               _ -> io:fwrite("Draw~n")
           end,
           case Human of
               $R -> loop([R+1,P,S]);
               $P -> loop([R,P+1,S]);
               $S -> loop([R,P,S+1])
           end;
       _ ->
           io:fwrite("Invalid play~n"),
           loop(Odds)
   end.

beats($R,$S) -> true; beats($P,$R) -> true; beats($S,$P) -> true; beats(_,_) -> false.

play_to_string($R) -> "Rock"; play_to_string($P) -> "Paper"; play_to_string($S) -> "Scissors".

select_play([R,P,S]) ->

   N = random:uniform(R+P+S),
   if
       N =< R -> $P;
       N =< R+P -> $S;
       true -> $R
   end.

</lang>

Euphoria

Translation of: C

<lang euphoria>function weighted_rand(sequence table)

   integer sum,r
   sum = 0
   for i = 1 to length(table) do
       sum += table[i]
   end for
   
   r = rand(sum)
   for i = 1 to length(table)-1 do
       r -= table[i]
       if r <= 0 then
           return i
       end if
   end for
   return length(table)

end function

constant names = { "Rock", "Paper", "Scissors" } constant winner = { "We tied.", "Meself winned.", "You win." } integer user_action, my_action, key, win sequence user_rec, score user_rec = {1,1,1} score = {0,0}

while 1 do

   my_action = remainder(weighted_rand(user_rec)+1,3)+1
   puts(1,"Your choice [1-3]:\n")
   puts(1,"  1. Rock\n  2. Paper\n  3. Scissors\n> ")
   key = -1
   while (key < '1' or key > '3') and key != 'q' do
       key = get_key()
   end while
   puts(1,key)
   puts(1,'\n')
   if key = 'q' then
       exit
   end if
   user_action = key-'0'
   win = remainder(my_action-user_action+3,3)
   printf(1,"You chose %s; I chose %s. %s\n",
       { names[user_action],
         names[my_action],
         winner[win+1] })
   
   if win then
       score[win] += 1
   end if
   printf(1,"\nScore %d:%d\n",score)
   user_rec[user_action] += 1

end while</lang>

F#

<lang FSharp>open System

let random = Random () let rand = random.NextDouble () //Gets a random number in the range (0.0, 1.0)

/// Union of possible choices for a round of rock-paper-scissors type Choice = | Rock | Paper | Scissors

/// Gets the string representation of a Choice let getString = function

   | Rock -> "Rock"
   | Paper -> "Paper"
   | Scissors -> "Scissors"

/// Defines rules for winning and losing let beats (a : Choice, b : Choice) =

   match a, b with
   | Rock, Scissors -> true    // Rock beats Scissors
   | Paper, Rock -> true       // Paper beats Rock
   | Scissors, Paper -> true   // Scissors beat Paper
   | _, _ -> false

/// Generates the next move for the computer based on probability derived from previous player moves. let genMove r p s =

   let tot = r + p + s
   let n = rand
   if n <= s / tot then Rock
   elif n <= (s + r) / tot then Paper
   else Scissors

/// Gets the move chosen by the player let rec getMove () =

   printf "[R]ock, [P]aper, or [S]cissors?: "
   let choice = Console.ReadLine ()
   match choice with
   | "r" | "R" -> Rock
   | "p" | "P" -> Paper
   | "s" | "S" -> Scissors
   | _ ->
       printf "Invalid choice.\n\n"
       getMove ()

/// Place where all the game logic takes place. let rec game (r : float, p : float, s : float) =

   let comp = genMove r p s
   let player = getMove ()
   Console.WriteLine ("Player: {0} vs Computer: {1}", getString player, getString comp)
   Console.WriteLine (
       if beats(player, comp) then "Player Wins!\n"
       elif beats(comp, player) then "Computer Wins!\n"
       else "Draw!\n"
   )
   let nextR = if player = Rock then r + 1.0 else r
   let nextP = if player = Paper then p + 1.0 else p
   let nextS = if player = Scissors then s + 1.0 else s
   game (nextR, nextP, nextS)

game(1.0, 1.0, 1.0) </lang>

Go

<lang go>package main

import (

   "fmt"
   "math/rand"
   "strings"
   "time"

)

const rps = "rps"

var msg = []string{

   "Rock breaks scissors",
   "Paper covers rock",
   "Scissors cut paper",

}

func main() {

   rand.Seed(time.Now().UnixNano())
   fmt.Println("Rock Paper Scissors")
   fmt.Println("Enter r, p, or s as your play.  Anything else ends the game.")
   fmt.Println("Running score shown as <your wins>:<my wins>")
   var pi string // player input
   var aScore, pScore int
   sl := 3               // for output alignment
   pcf := make([]int, 3) // pcf = player choice frequency
   var plays int
   aChoice := rand.Intn(3) // ai choice for first play is completely random
   for {
       // get player choice
       fmt.Print("Play: ")
       _, err := fmt.Scanln(&pi)  // lazy
       if err != nil || len(pi) != 1 {
           break
       }
       pChoice := strings.Index(rps, pi)
       if pChoice < 0 {
           break
       }
       pcf[pChoice]++
       plays++
       // show result of play
       fmt.Printf("My play:%s%c.  ", strings.Repeat(" ", sl-2), rps[aChoice])
       switch (aChoice - pChoice + 3) % 3 {
       case 0:
           fmt.Println("Tie.")
       case 1:
           fmt.Printf("%s.  My point.\n", msg[aChoice])
           aScore++
       case 2:
           fmt.Printf("%s.  Your point.\n", msg[pChoice])
           pScore++
       }
       // show score
       sl, _ = fmt.Printf("%d:%d  ", pScore, aScore)
       // compute ai choice for next play
       switch rn := rand.Intn(plays); {
       case rn < pcf[0]:
           aChoice = 1
       case rn < pcf[0]+pcf[1]:
           aChoice = 2
       default:
           aChoice = 0
       }
   }

}</lang> Sample output:

Rock Paper Scissors
Enter r, p, or s as your play.  Anything else ends the game.
Running score shown as <your wins>:<my wins>
Play: r
My play: r.  Tie.
0:0  Play: p
My play:   p.  Tie.
0:0  Play: s
My play:   p.  Scissors cut paper.  Your point.
1:0  Play: r
My play:   p.  Paper covers rock.  My point.
1:1  Play: r
My play:   r.  Tie.
1:1  Play: r
My play:   p.  Paper covers rock.  My point.
1:2  Play: 

Haskell

<lang haskell>import System.Random

data Choice = Rock | Paper | Scissors

deriving (Show, Eq) 


beats Paper Rock = True beats Scissors Paper = True beats Rock Scissors = True beats _ _ = False

genrps (r,p,s) = fmap rps rand

 where rps x | x <= s    = Rock 
             | x <= s+r  = Paper
             | otherwise = Scissors 
       rand = randomRIO (1,r+p+s) :: IO Int

getrps = fmap rps getLine

 where rps "scissors" = Scissors
       rps "rock" = Rock
       rps "paper" = Paper
       rps _ = error "invalid input"

game (r,p,s) = do putStrLn "rock, paper or scissors?"

                 h <- getrps
                 c <- genrps (r,p,s)
                 putStrLn ("Player: " ++ show h ++ " Computer: " ++ show c)
                 putStrLn (if beats h c then "player wins\n" 
                          else if beats c h then "player loses\n"
                          else "draw\n")
                 let rr = if h == Rock then r+1 else r
                     pp = if h == Paper then p+1 else p
                     ss = if h == Scissors then s+1 else s
                 game (rr,pp,ss)

main = game (1,1,1)</lang>

Icon and Unicon

The key to this comes down to two structures and two lines of code. The player history historyP is just an ordered list of every player turn and provides the weight for the random selection. The beats list is used to rank moves and to choose the move that would beat the randomly selected move. <lang Icon>link printf

procedure main()

printf("Welcome to Rock, Paper, Scissors.\n_

       Rock beats scissors, Scissors beat paper, and Paper beats rock.\n\n")

historyP := ["rock","paper","scissors"] # seed player history winP := winC := draws := 0 # totals

beats := ["rock","scissors","paper","rock"] # what beats what 1 apart

repeat {

  printf("Enter your choice or rock(r), paper(p), scissors(s) or quit(q):")
  turnP := case map(read()) of {
     "q"|"quit": break
     "r"|"rock": "rock"
     "p"|"paper": "paper"
     "s"|"scissors": "scissors"
     default:  printf(" - invalid choice.\n") & next
     }
  turnC := beats[(?historyP == beats[i := 2 to *beats],i-1)]  # choose move
     
  put(historyP,turnP)                       # record history
  printf("You chose %s, computer chose %s",turnP,turnC)   
  (beats[p := 1 to *beats] == turnP) & 
     (beats[c := 1 to *beats] == turnC) & (abs(p-c) <= 1)  # rank play
    
  if p = c then
     printf(" - draw (#%d)\n",draws +:= 1 )
  else if p > c then   
     printf(" - player win(#%d)\n",winP +:= 1)        
  else 
     printf(" - computer win(#%d)\n",winC +:= 1)    
  }

printf("\nResults:\n %d rounds\n %d Draws\n %d Computer wins\n %d Player wins\n",

  winP+winC+draws,draws,winC,winP)   

end</lang>

printf.icn provides printf

Sample output:

Welcome to Rock, Paper, Scissors.
Rock beats scissors, Scissors beat paper, and Paper beats rock.

Enter your choice or rock(r), paper(p), scissors(s) or quit(q):s
You chose scissors, computer chose scissors - draw (#1)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):p
You chose paper, computer chose paper - draw (#2)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):r
You chose rock, computer chose scissors - computer win(#1)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):r
You chose rock, computer chose rock - draw (#3)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):p
You chose paper, computer chose paper - draw (#4)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):s
You chose scissors, computer chose scissors - draw (#5)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):r
You chose rock, computer chose rock - draw (#6)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):r
You chose rock, computer chose paper - player win(#1)
Enter your choice or rock(r), paper(p), scissors(s) or quit(q):q

Results:
 8 rounds
 6 Draws
 1 Computer wins
 1 Player wins

J

<lang j>require'misc strings' game=:3 :0

 outcomes=. rps=. 0 0 0
 choice=. 1+?3
 while.#response=. prompt'  Choose Rock, Paper or Scissors: ' do.
   playerchoice=. 1+'rps' i. tolower {.deb response
   if.4 = playerchoice do.
     smoutput 'Unknown response.'
     smoutput 'Enter an empty line to quit'
     continue.
   end.
   smoutput '    I choose ',choice {::;:'. Rock Paper Scissors'
   smoutput (wintype=. 3 | choice-playerchoice) {:: 'Draw';'I win';'You win'
   outcomes=. outcomes+0 1 2 = wintype
   rps=. rps+1 2 3=playerchoice
   choice=. 1+3|(?0) I.~ (}:%{:)+/\ 0, rps
 end.
 ('Draws:','My wins:',:'Your wins: '),.":,.outcomes

)</lang>

Example use (playing to give the computer implementation the advantage):

<lang j> game

 Choose Rock, Paper or Scissors: rock
   I choose Scissors

You win

 Choose Rock, Paper or Scissors: rock
   I choose Paper

I win

 Choose Rock, Paper or Scissors: rock
   I choose Paper

I win

 Choose Rock, Paper or Scissors: rock
   I choose Paper

I win

 Choose Rock, Paper or Scissors: rock
   I choose Paper

I win

 Choose Rock, Paper or Scissors: 

Draws: 0 My wins: 4 Your wins: 1</lang>

Java

Works with: Java version 1.5+

This could probably be made simpler, but some more complexity is necessary so that other items besides rock, paper, and scissors can be added (as school children and nerds like to do [setup for rock-paper-scissors-lizard-spock is in multi-line comments]). The method getAIChoice() borrows from the Ada example in spirit, but is more generic to additional items. <lang java5>import java.util.Arrays; import java.util.EnumMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.Random;

public class RPS { public enum Item{ ROCK, PAPER, SCISSORS, /*LIZARD, SPOCK*/; public List<Item> losesToList; public boolean losesTo(Item other) { return losesToList.contains(other); } static { SCISSORS.losesToList = Arrays.asList(ROCK/*, SPOCK*/); ROCK.losesToList = Arrays.asList(PAPER/*, SPOCK*/); PAPER.losesToList = Arrays.asList(SCISSORS/*, LIZARD*/); /* SPOCK.losesToList = Arrays.asList(PAPER, LIZARD); LIZARD.losesToList = Arrays.asList(SCISSORS, ROCK); */

               }

} //EnumMap uses a simple array under the hood public final Map<Item, Integer> counts = new EnumMap<Item, Integer>(Item.class){{ for(Item item:Item.values()) put(item, 1); }};

private int totalThrows = Item.values().length;

public static void main(String[] args){ RPS rps = new RPS(); rps.run(); }

public void run() { Scanner in = new Scanner(System.in); System.out.print("Make your choice: "); while(in.hasNextLine()){ Item aiChoice = getAIChoice(); String input = in.nextLine(); Item choice; try{ choice = Item.valueOf(input.toUpperCase()); }catch (IllegalArgumentException ex){ System.out.println("Invalid choice"); continue; } counts.put(choice, counts.get(choice) + 1); totalThrows++; System.out.println("Computer chose: " + aiChoice); if(aiChoice == choice){ System.out.println("Tie!"); }else if(aiChoice.losesTo(choice)){ System.out.println("You chose...wisely. You win!"); }else{ System.out.println("You chose...poorly. You lose!"); } System.out.print("Make your choice: "); } }

private static final Random rng = new Random(); private Item getAIChoice() { int rand = rng.nextInt(totalThrows); for(Map.Entry<Item, Integer> entry:counts.entrySet()){ Item item = entry.getKey(); int count = entry.getValue(); if(rand < count){ List<Item> losesTo = item.losesToList; return losesTo.get(rng.nextInt(losesTo.size())); } rand -= count; } return null; } }</lang> Sample output:

Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: rock
Computer chose: SCISSORS
You chose...wisely. You win!
Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: rock
Computer chose: SCISSORS
You chose...wisely. You win!
Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: rock
Computer chose: ROCK
Tie!
Make your choice: rock
Computer chose: ROCK
Tie!
Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: rock
Computer chose: PAPER
You chose...poorly. You lose!
Make your choice: scissors
Computer chose: PAPER
You chose...wisely. You win!
Make your choice: scissors
Computer chose: PAPER
You chose...wisely. You win!
...

Julia

<lang julia>function rps() print("Welcome to Rock, paper, scissors! Go ahead and type your pick.\n r(ock), p(aper), or s(cissors)\n Enter 'q' to quit.\n>") comp_score = 0 user_score = 0 options = ["r","p","s"] new_pick() = options[rand(1:3)] i_win(m,y) = ((m == "r" && y == "s")|(m == "s" && y == "p")|(m == "p" && y == "r")) while true input = string(readline(STDIN)[1]) input == "q" && break !ismatch(r"^[rps]",input) && begin print("Invalid guess: Please enter 'r', 'p', or 's'\n"); continue end answer = new_pick() if input == answer print("\nTie!\nScore still: \nyou $user_score\nme $comp_score\n>") continue else i_win(answer,input) ? (comp_score += 1) : (user_score += 1) print(i_win(answer,input) ? "\nSorry you lose!\n" : "\nYou win!","Score: \nyou $user_score\nme $comp_score\n>") end end end</lang>

julia> rps()
Welcome to Rock, paper, scissors! Go ahead and type your pick.

r(ock), p(aper), or s(cissors)

Enter 'q' to quit.
>r

You win!Score: 
you 1
me  0
>p

Sorry you lose!
Score: 
you 1
me  1
>s

You win!Score: 
you 2
me  1

Liberty BASIC

<lang lb> dim rps( 2), g$( 3)

g$( 0) ="rock": g$( 1) ="paper": g$( 2) ="scissors" global total

total =0: draw =0: pwin =0: cwin =0

rps( 0) =1: rps( 1) =1: rps( 2) =1 ' at first computer will play all three with equal probability

c =int( 3 *rnd( 1)) ' first time, computer response is random

' In the following code we set three integer %ages for the <human>'s biassed throws.

                                           '   set up the <human> player's key frequencies as %ages.
                                           '   Done like this it's easy to mimic the <human> input of q$
                                           '   It allows only integer %age frequency- not an important thing.

rockP =45 ' <<<<<<<<< Set here the <human>'s %age of 'rock' choices. for i =1 to rockP: qF$ =qF$ +"R": next i

paprP =24 ' <<<<<<<<< Set here the %age of 'paper' choices. for i =1 to paprP: qF$ =qF$ +"P": next i

scisP =100 -rockP -paprP ' <<<<<<<<< %age 'scissors' calculated to make 100% for i =1 to scisP: qF$ =qF$ +"S": next i 'print qF$

do

 'do: input q$:loop until instr( "RPSrpsQq", q$)   '   for actual human input... possibly biassed.         <<<<<<<<<<<<< REM one or the other line...
 q$ =mid$( qF$, int( 100 *rnd( 1)), 1)              '   simulated <human> input with controlled bias.      <<<<<<<<<<<<<
 if total >10000 then q$ ="Q"
 g =int( ( instr( "RrPpSsQq", q$) -1) / 2)
 if g >2 then [endGame]
 total    =total   +1
 rps( g)  =rps( g) +1  '   accumulate plays the <human> has chosen. ( & hence their (biassed?) frequencies.)
 'print "  You chose "; g$( g); " and I chose "; g$( c); ". "
 select case g -c
   case 0
     draw =draw +1  ':print "It's a draw"
   case 1, -2
     pwin =pwin +1  ':print "You win!"
   case -1, 2
     cwin =cwin +1  ':print "I win!"
  end select
  r =int( total *rnd( 1))      '   Now select computer's choice for next confrontation.
  select case                  '   Using the accumulating data about <human>'s frequencies so far.
       case r <=rps( 0)
           c =1
       case r <=( rps( 0) +rps( 1))
           c =2
       case else
           c =0
  end select
  scan

loop until 0

[endGame]

   print
   print "  You won "; pwin; ", and I won "; cwin; ". There were "; draw; " draws."
   if cwin >pwin then print "      I AM THE CHAMPION!!" else print "        You won this time."
   print
   print "  At first I assumed you'd throw each equally often."
   print "  This means I'd win 1 time in 3; draw 1 in 3; lose 1 in 3."
   print "  However if I detect a bias in your throws,...."
   print "  ....this allows me to anticipate your most likely throw & on average beat it."
   print
   print "  In fact, keyboard layout & human frailty mean even if you TRY to be even & random..."
   print "  ... you may be typing replies with large bias. In 100 tries I gave 48 'P's, 29 'R' & 23 'S'!"
   print
   print "    This time I played.."
   print "      Rock "; using( "##.##", rps( 2)* 100 /total); "%    Paper "; using( "##.##", rps( 0) *100 /total); "%    Scissors "; using( "##.##", rps( 1) *100 /total); "%."
   print
   print "  ( PS. I have since learned your actual bias had been.."
   print "      Rock "; using( "##.##", rockP); "%    Paper "; using( "##.##", paprP ); "%    Scissors "; using( "##.##", ( 100 -rockP -paprP)); "%.)"
   print
   print "  The advantage I can gain gets bigger the further the 'human' entries are biassed."
   print "  The results statistically smooth out better with large runs."
   print "  Try 10,000,000, & have a cuppa while you wait."
   print
   print "  Can you see what will happen if, say, the 'human' is set to give 'Rock' EVERY time?"
   print "  Try different %ages by altering the marked code lines."
   print
   print "  Thanks for playing!"
   end

</lang>

 You won 3204, and I won 3669. There were 3128 draws.
     I AM THE CHAMPION!!

 At first I assumed you'd throw each equally often.
 This means I'd win 1 time in 3; draw 1 in 3; lose 1 in 3.
 However if I detect a bias in your throws,....
 ....this allows me to anticipate your most likely throw & on average beat it.

 In fact, keyboard layout & human frailty mean even if you TRY to be even & random...
 ... you may be typing replies with large bias. In 100 tries I gave 48 'P's, 29 'R' & 23 'S'!
 
   This time I played..
     Rock 30.17%    Paper 45.93%    Scissors 23.94%.

 ( PS. I have since learned your actual bias had been..
     Rock 45.00%    Paper 24.00%    Scissors 31.00%.)

 The advantage I can gain gets bigger the further the 'human' entries are biassed.
 The results statistically smooth out better with large runs.
 Try 10,000,000, & have a cuppa while you wait.

 Can you see what will happen if, say, the 'human' is set to give 'Rock' EVERY time?
 Try different %ages by altering the marked code lines.


Locomotive Basic

Translation of: Go

<lang locobasic>10 mode 1:defint a-z:randomize time 20 rps$="rps" 30 msg$(1)="Rock breaks scissors" 40 msg$(2)="Paper covers rock" 50 msg$(3)="Scissors cut paper" 60 print "Rock Paper Scissors":print 70 print "Enter r, p, or s as your play." 80 print "Running score shown as <your wins>:<my wins>" 90 achoice=rnd*2.99+.5 ' get integer between 1 and 3 from real between .5 and <3.5 100 ' get key 110 pin$=inkey$ 120 if pin$="" then 110 130 pchoice=instr(rps$,pin$) 140 if pchoice=0 then print "Sorry?":goto 110 150 pcf(pchoice)=pcf(pchoice)+1 160 plays=plays+1 170 print "My play: "mid$(rps$,achoice,1) 180 sw=(achoice-pchoice+3) mod 3 190 if sw=0 then print "Tie." else if sw=1 then print msg$(achoice);". My point.":ascore=ascore+1 else print msg$(pchoice);". Your point.":pscore=pscore+1 200 print pscore":"ascore 210 rn=rnd*plays 220 if rn<pcf(1) then achoice=2 else if rn<pcf(1)+pcf(2) then achoice=3 else achoice=1 230 goto 110</lang>

Mathematica

<lang mathematica>DynamicModule[{record, play, text = "\nRock-paper-scissors\n",

 choices = {"Rock", "Paper", "Scissors"}}, 
Evaluate[record /@ choices] = {1, 1, 1}; 
play[x_] := 
 Module[{y = RandomChoice[record /@ choices -> RotateLeft@choices]}, 
  record[x]++; 
  text = "Your Choice:" <> x <> "\nComputer's Choice:" <> y <> "\n" <>
     Switch[{x, y}, Alternatives @@ Partition[choices, 2, 1, 1], 
     "You lost.", 
     Alternatives @@ Reverse /@ Partition[choices, 2, 1, 1], 
     "You win.", _, "Draw."]]; 
Column@{Dynamic[text], ButtonBar[# :> play[#] & /@ choices]}]</lang>

OCaml

<lang OCaml> let pf = Printf.printf ;;

let looses a b = match a, b with

    `R, `P -> true
  | `P, `S -> true
  | `S, `R -> true
  |  _,  _ -> false ;;

let rec get_move () =

  pf "[R]ock, [P]aper, [S]cisors [Q]uit? " ;
  match String.uppercase (read_line ()) with
       "P" -> `P
     | "S" -> `S
     | "R" -> `R
     | "Q" -> exit 0
     | _   -> get_move () ;;

let str_of_move = function

       `P -> "paper"
     | `R -> "rock"
     | `S -> "scisors" ;;

let comp_move r p s =

  let tot = r +. p +. s in
  let n = Random.float 1.0 in
  if n < r /. tot then
     `R
  else
     if n < (r +. p) /. tot then
        `P
     else
        `S ;;

let rec make_moves r p s =

  let cm = comp_move r p s in   (* Computer move is based on game history. *)
  let hm = get_move () in       (* Human move is requested. *)
  pf "Me: %s. You: %s. " (str_of_move cm) (str_of_move hm);
  let outcome = 
     if looses hm cm then
        "I win. You loose.\n"
     else if cm = hm then
        "We draw.\n"
     else 
        "You win. I loose.\n"
  in pf "%s" outcome;
  match hm with (* Play on with adapted strategy. *)
       `S -> make_moves (r +. 1.) p s
     | `R -> make_moves r (p +. 1.) s
     | `P -> make_moves r p (s +. 1.) ;;

(* Main loop. *) make_moves 1. 1. 1. ;;

</lang>

PARI/GP

<lang parigp>contest(rounds)={

 my(v=[1,1,1],wins,losses); \\ Laplace rule
 for(i=1,rounds,
   my(computer,player,t);
   t=random(v[1]+v[2]+v[3]);
   if(t<v[1], computer = "R",
     if(t<v[1]+v[2], computer = "P", computer = "S")
   );
   print("Rock, paper, or scissors?");
   t = Str(input());
   if(#t,
     player=Vec(t)[1];
     if(player <> "R" && player <> "P", player = "S")
   ,
     player = "S"
   );
   if (player == "R", v[2]++);
   if (player == "P", v[3]++);
   if (player == "S", v[1]++);
   print1(player" vs. "computer": ");
   if (computer <> player,
     if((computer == "R" && player = "P") || (computer == "P" && player = "S") || (computer == "S" && player == "R"),
       print("You win");
       losses++
     ,
       print("I win");
       wins++
     )
   ,
     print("Tie");
   )
 );
 [wins,losses]

}; contest(10)</lang>

Perl 6

This is slightly more complicated than it could be; it is a general case framework with input filtering. It weights the computers choices based on your previous choices. Type in at least the first two characters of your choice, or just hit enter to quit. Customize it by supplying your own %vs options/outcomes.

Here is standard Rock-Paper-Scissors.

<lang perl6>my %vs = (

   options => [<Rock Paper Scissors>],
   ro => {
       ro => [ 2,                         ],
       pa => [ 1, 'Paper covers Rock: '     ],
       sc => [ 0, 'Rock smashes Scissors: ' ]
   },
   pa => {
       ro => [ 0, 'Paper covers Rock: '    ],
       pa => [ 2,                        ],
       sc => [ 1, 'Scissors cut Paper: '   ]
   },
   sc => {
       ro => [ 1, 'Rock smashes Scissors: '],
       pa => [ 0, 'Scissors cut Paper: '   ],
       sc => [ 2,                        ]
   }

);

my %choices = %vs<options>.map({; $_.substr(0,2).lc => $_ }); my $keys = %choices.keys.join('|'); my $prompt = %vs<options>.map({$_.subst(/(\w\w)/,->$/{"[$0]"})}).join(' ')~"? "; my %weight = %choices.keys »=>» 1;

my @stats = 0,0,0; my $round;

while my $player = (prompt "Round {++$round}: " ~ $prompt).lc {

   $player.=substr(0,2);
   say 'Invalid choice, try again.' and $round-- and next
     unless $player.chars == 2 and $player ~~ /<$keys>/;
   my $computer = %weight.keys.map( { $_ xx %weight{$_} } ).pick;
   %weight{$_.key}++ for %vs{$player}.grep( { $_.value[0] == 1 } );
   my $result = %vs{$player}{$computer}[0];
   @stats[$result]++;
   say "You chose %choices{$player},  Computer chose %choices{$computer}.";
   print %vs{$player}{$computer}[1];
   print ( 'You win!', 'You Lose!','Tie.' )[$result];
   say " - (W:{@stats[0]} L:{@stats[1]} T:{@stats[2]})\n",

};</lang>Example output:

Round 1: [Ro]ck [Pa]per [Sc]issors? ro
You chose Rock,  Computer chose Paper.
Paper covers Rock: You Lose! - (W:0 L:1 T:0)

Round 2: [Ro]ck [Pa]per [Sc]issors? pa
You chose Paper,  Computer chose Scissors.
Scissors cut Paper: You Lose! - (W:0 L:2 T:0)

Round 3: [Ro]ck [Pa]per [Sc]issors? pa
You chose Paper,  Computer chose Scissors.
Scissors cut Paper: You Lose! - (W:0 L:3 T:0)

Round 4: [Ro]ck [Pa]per [Sc]issors? ro
You chose Rock,  Computer chose Rock.
Tie. - (W:0 L:3 T:1)

Round 5: [Ro]ck [Pa]per [Sc]issors? sc
You chose Scissors,  Computer chose Scissors.
Tie. - (W:0 L:3 T:2)
...

Here is example output from the same code only with a different %vs data structure implementing Rock-Paper-Scissors-Lizard-Spock.

<lang perl6>my %vs = (

   options => [<Rock Paper Scissors Lizard Spock>],
   ro => {
       ro => [ 2,                             ],
       pa => [ 1, 'Paper covers Rock: '         ],
       sc => [ 0, 'Rock smashes Scissors: '     ],
       li => [ 0, 'Rock crushes Lizard: '       ],
       sp => [ 1, 'Spock vaporizes Rock: '      ]
   },
   pa => {
       ro => [ 0, 'Paper covers Rock: '         ],
       pa => [ 2,                             ],
       sc => [ 1, 'Scissors cut Paper: '        ],
       li => [ 1, 'Lizard eats Paper: '         ],
       sp => [ 0, 'Paper disproves Spock: '     ]
   },
   sc => {
       ro => [ 1, 'Rock smashes Scissors: '     ],
       pa => [ 0, 'Scissors cut Paper: '        ],
       sc => [ 2,                             ],
       li => [ 0, 'Scissors decapitate Lizard: '],
       sp => [ 1, 'Spock smashes Scissors: '    ]
   },
   li => {
       ro => [ 1, 'Rock crushes Lizard: '       ],
       pa => [ 0, 'Lizard eats Paper: '         ],
       sc => [ 1, 'Scissors decapitate Lizard: '],
       li => [ 2,                             ],
       sp => [ 0, 'Lizard poisons Spock: '      ]
   },
   sp => {
       ro => [ 0, 'Spock vaporizes Rock: '      ],
       pa => [ 1, 'Paper disproves Spock: '     ],
       sc => [ 0, 'Spock smashes Scissors: '    ],
       li => [ 1, 'Lizard poisons Spock: '      ],
       sp => [ 2,                             ]
   }

);</lang>

Round 1: [Ro]ck [Pa]per [Sc]issors [Li]zard [Sp]ock? li
You chose Lizard,  Computer chose Scissors.
Scissors decapitate Lizard: You Lose! - (W:0 L:1 T:0)

Round 2: [Ro]ck [Pa]per [Sc]issors [Li]zard [Sp]ock? sp
You chose Spock,  Computer chose Paper.
Paper disproves Spock: You Lose! - (W:0 L:2 T:0)

Round 3: [Ro]ck [Pa]per [Sc]issors [Li]zard [Sp]ock? ro
You chose Rock,  Computer chose Lizard.
Rock crushes Lizard: You Win! - (W:1 L:2 T:0)

Round 4: [Ro]ck [Pa]per [Sc]issors [Li]zard [Sp]ock? ro
You chose Rock,  Computer chose Scissors.
Rock smashes Scissors: You win! - (W:2 L:2 T:0)

Round 5: [Ro]ck [Pa]per [Sc]issors [Li]zard [Sp]ock? li
You chose Lizard,  Computer chose Paper.
Lizard eats Paper: You win! - (W:3 L:2 T:0)
...

PicoLisp

<lang PicoLisp>(use (C Mine Your)

  (let (Rock 0  Paper 0  Scissors 0)
     (loop
        (setq Mine
           (let N (if (gt0 (+ Rock Paper Scissors)) (rand 1 @) 0)
              (seek
                 '((L) (le0 (dec 'N (caar L))))
                 '(Rock Paper Scissors .) ) ) )
        (prin "Enter R, P or S to play, or Q to quit: ")
        (loop
           (and (= "Q" (prinl (setq C (uppc (key))))) (bye))
           (T (setq Your (find '((S) (pre? C S)) '(Rock Paper Scissors))))
           (prinl "Bad input - try again") )
        (prinl
           "I say " (cadr Mine) ", You say " Your ": "
           (cond
              ((== Your (cadr Mine)) "Draw")
              ((== Your (car Mine)) "I win")
              (T "You win") ) )
        (inc Your) ) ) )</lang>

PureBasic

<lang purebasic>Enumeration

 ;choices are in listed according to their cycle, weaker followed by stronger
 #rock
 #paper
 #scissors
 #numChoices ;this comes after all possible choices

EndEnumeration

give names to each of the choices

Dim choices.s(#numChoices - 1) choices(#rock) = "rock" choices(#paper) = "paper" choices(#scissors) = "scissors"

Define gameCount Dim playerChoiceHistory(#numChoices - 1)

Procedure weightedRandomChoice()

 Shared gameCount, playerChoiceHistory()
 Protected x = Random(gameCount - 1), t, c
 
 For i = 0 To #numChoices - 1
   t + playerChoiceHistory(i)
   If t >= x
     c = i
     Break
   EndIf
 Next
  
 ProcedureReturn (c + 1) % #numChoices

EndProcedure

If OpenConsole()

 PrintN("Welcome to the game of rock-paper-scissors")
 PrintN("Each player guesses one of these three, and reveals it at the same time.")
 PrintN("Rock blunts scissors, which cut paper, which wraps stone.")
 PrintN("If both players choose the same, it is a draw!")
 PrintN("When you've had enough, choose Q.")
 
 Define computerChoice, playerChoice, response.s
 Define playerWins, computerWins, draw, quit
  
 computerChoice = Random(#numChoices - 1)
 Repeat
   Print(#CRLF$ + "What is your move (press R, P, or S)?")
   Repeat
     response = LCase(Input())
   Until FindString("rpsq", response) > 0
   
   If response = "q":
     quit = 1
   Else
     gameCount + 1
     playerChoice = FindString("rps", response) - 1
     
     result = (playerChoice - computerChoice + #numChoices) % #numChoices
     Print("You chose " + choices(playerChoice) + " and I chose " + choices(computerChoice))
     Select result
       Case 0
         PrintN(". It's a draw.")
         draw + 1
       Case 1
         PrintN(". You win!")
         playerWins + 1
       Case 2
         PrintN(". I win!")
         computerWins + 1
     EndSelect
     playerChoiceHistory(playerChoice) + 1
     computerChoice = weightedRandomChoice()
   EndIf 
 Until quit
 
 Print(#CRLF$ + "You chose: ")
 For i = 0 To #numChoices - 1
   Print(choices(i) + " " + StrF(playerChoiceHistory(i) * 100 / gameCount, 1) + "%; ")
 Next
 PrintN("")
 PrintN("You won " + Str(playerWins) + ", and I won " + Str(computerWins) + ". There were " + Str(draw) + " draws.")
 PrintN("Thanks for playing!")
 
 Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
 CloseConsole()

EndIf</lang> Sample output:

Welcome to the game of rock-paper-scissors
Each player guesses one of these three, and reveals it at the same time.
Rock blunts scissors, which cut paper, which wraps stone.
If both players choose the same, it is a draw!
When you've had enough, choose Q.

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?s
You chose scissors and I chose paper. You win!

What is your move (press R, P, or S)?r
You chose rock and I chose paper. I win!

What is your move (press R, P, or S)?s
You chose scissors and I chose paper. You win!

What is your move (press R, P, or S)?s
You chose scissors and I chose paper. You win!

What is your move (press R, P, or S)?s
You chose scissors and I chose paper. You win!

What is your move (press R, P, or S)?s
You chose scissors and I chose rock. I win!

What is your move (press R, P, or S)?q

You chose: rock 54.5%; paper 0.0%; scissors 45.5%;
You won 4, and I won 7. There were 0 draws.
Thanks for playing!

Python

<lang python>#!/usr/bin/python from random import choice, randrange from bisect import bisect from collections import defaultdict

WHATBEATS = { 'paper' : 'scissors',

               'scissors' : 'rock',
               'rock' : 'paper'        }

ORDER = ('rock', 'paper', 'scissors')

CHOICEFREQUENCY = defaultdict(int)

def probChoice(choices, probabilities):

   total = sum(probabilities)
   prob_accumulator = 0
   accumulator = []
   for p in probabilities:
       prob_accumulator += p
       accumulator.append(prob_accumulator)
   r = randrange(total)
   bsct = bisect(accumulator, r)
   chc = choices[bsct]
   return chc

def checkWinner(a, b):

   if b == WHATBEATS[a]:
       return b
   elif a == WHATBEATS[b]:
       return a
   return None

def sanitizeChoice(a):

   # Drop it to lower-case
   return a.lower()

def registerPlayerChoice(choice):

   CHOICEFREQUENCY[choice] += 1

def getRandomChoice():

   if len(CHOICEFREQUENCY) == 0:
       return choice(ORDER)
   choices = CHOICEFREQUENCY.keys()
   probabilities = CHOICEFREQUENCY.values()
   return WHATBEATS[probChoice(choices, probabilities)]

while True:

   humanChoice = raw_input()
   humanChoice = sanitizeChoice(humanChoice)
   if humanChoice not in ORDER:
       continue
   compChoice = getRandomChoice()
   print "Computer picked", compChoice+",",
   # Don't register the player choice until after the computer has made
   # its choice.
   registerPlayerChoice(humanChoice)
   winner = checkWinner(humanChoice, compChoice)
   if winner == None:
       winner = "nobody"
   print winner, "wins!"</lang>

Output, where player always chooses Rock:

!504 #5 j0 ?0 $ ./rps.py 
rock
Computer picked scissors, rock wins!
rock
Computer picked paper, paper wins!
rock
Computer picked paper, paper wins!
rock
Computer picked paper, paper wins!
rock
Computer picked paper, paper wins!

Rascal

<lang rascal>import Prelude;

rel[str, str] whatbeats = {<"Rock", "Scissors">, <"Scissors", "Paper">, <"Paper", "Rock">};

list[str] ComputerChoices = ["Rock", "Paper", "Scissors"];

str CheckWinner(a, b){ if(b == getOneFrom(whatbeats[a])) return a; elseif(a == getOneFrom(whatbeats[b])) return b; else return "Nobody"; }

public str RPS(human){ computer = getOneFrom(ComputerChoices); x = if(human == "Rock") "Paper"; elseif(human == "Paper") "Scissors"; else "Rock"; ComputerChoices += x; return "Computer played <computer>. <CheckWinner(human, computer)> wins!"; }</lang> Sample output: <lang rascal>rascal>RPS("Rock") str: "Computer played Rock. Nobody wins!"

rascal>RPS("Rock") str: "Computer played Rock. Nobody wins!"

rascal>RPS("Rock") str: "Computer played Scissors. Rock wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"

rascal>RPS("Rock") str: "Computer played Rock. Nobody wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"

rascal>RPS("Rock") str: "Computer played Paper. Paper wins!"</lang>

REXX

This version of the REXX program:

  • allows the human player to abbreviate their choice
  • allows the human player to   QUIT   at any time
  • keeps track of the human player's responses   (to make a hopefully winning choice)
  • uses proper "English"   rock breaks scissors

<lang rexx>/*REXX pgm plays rock-paper-scissors with a CBLF (carbon-based life form*/ !='────────'; er='***error!***'; @.=0 /*some constants for pgm*/ z=! 'Please enter one of: Rock Paper Scissors (or Quit)' $.p='paper'; $.s='scissors'; $.r='rock' /*computer's choices. */ b.p=' covers '; b.s=' cuts '; b.r=' breaks ' /*how the choice wins.*/

 do forever;   say;    say z;    say  /*prompt the CBLF & get response.*/
 c=word('rock paper scissors',random(1,3))    /*the computer's 1st pick*/
 m=max(@.r,@.p,@.s);   f='paper'      /*prepare to examine the history.*/
 if @.p==m  then f='scissors'         /*emulate JC's The Amazing Karnac*/
 if @.s==m  then f='rock'             /*   "     "    "     "       "  */
 if m\==0   then c=f                  /*choose based on CBLF's history.*/
 c1=left(c,1);   upper c1             /*C1  is used for fast comparing.*/
 parse pull u;   a=strip(u);          /*get the CBLF's choice (answer).*/
 upper a;        a1=left(a,1)         /*uppercase answer, get 1st char.*/
 ok=0                                 /*indicate answer isn't OK so far*/
      select                          /*process the CBLF's choice.     */
      when words(u)==0           then say  er  'nothing entered'
      when words(u)>1            then say  er  'too many choices: '  u
      when abbrev('QUIT',a)      then do;  say ! 'quitting.';  exit;  end
      when abbrev('ROCK',a)  |,
           abbrev('PAPER',a) |,
           abbrev('SCISSORS',a)  then ok=1    /*a valid answer by CBLF.*/
      otherwise                  say er  'you entered a bad choice:'  u
      end   /*select*/
 if \ok          then iterate         /*answer ¬ OK?  Then get another.*/
 @.a1 = @.a1+1                        /*keep track of CBLF's answers.  */
 say ! 'computer chose: '  c
 if a1==c1              then do; say ! 'draw.';  iterate;  end
 if a1=='R' & c1=='S' |,
    a1=='S' & c1=='P' |,
    a1=='P' & c1=='R'  then say ! 'you win! '            ! $.a1 b.a1 $.c1
                       else say ! 'the computer wins. '  ! $.c1 b.c1 $.a1
 end   /*forever*/
                                      /*stick a fork in it, we're done.*/</lang>

output with various responses from the user   (output shown is a screen scraping):

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

s
──────── computer chose:  rock
──────── the computer wins.  ──────── rock  breaks  scissors

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

s
──────── computer chose:  rock
──────── the computer wins.  ──────── rock  breaks  scissors

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

s
──────── computer chose:  rock
──────── the computer wins.  ──────── rock  breaks  scissors

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

s
──────── computer chose:  rock
──────── the computer wins.  ──────── rock  breaks  scissors

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

s
──────── computer chose:  rock
──────── the computer wins.  ──────── rock  breaks  scissors

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

p
──────── computer chose:  rock
──────── you win!  ──────── paper  covers  rock

──────── Please enter one of:     Rock  Paper  Scissors      (or Quit)

q
──────── quitting.

Ruby

<lang ruby>class RockPaperScissorsGame

 def initialize()
   @pieces = %w[rock paper scissors]
   @beats = {
     'rock' => 'paper',
     'paper' => 'scissors',
     'scissors' => 'rock',
   }
   @plays = {
     'rock' => 1,
     'paper' => 1,
     'scissors' => 1,
   }
   @score = [0, 0]
   play
 end
 def humanPlay()
   answer = nil
   loop do
     print "\nYour choice: #@pieces? "
     answer = STDIN.gets.strip.downcase
     next if answer.empty?
     if idx = @pieces.find_index {|piece| piece.match(/^#{answer}/)}
       answer = @pieces[idx]
       break
     else
       puts "invalid answer, try again"
     end
   end
   answer
 end
 def computerPlay()
   total = @plays.values.reduce(:+)
   r = rand(total) + 1
   sum = 0
   humans_choice = nil
   @pieces.each do |piece|
     sum += @plays[piece]
     if r <= sum
       humans_choice = piece
       break
     end
   end
   @beats[humans_choice]
 end
 def play
   loop do
     h = humanPlay
     c = computerPlay
     print "H: #{h}, C: #{c} => "
     # only update the human player's history after the computer has chosen
     @plays[h] += 1
     if h == c
       puts "draw"
     elsif h == @beats[c]
       puts "Human wins"
       @score[0] += 1
     else
       puts "Computer wins"
       @score[1] += 1
     end
     puts "score: human=#{@score[0]}, computer=#{@score[1]}"
   end
 end

end

game = RockPaperScissorsGame.new</lang> sample game where human always chooses rock:

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: rock => draw
score: human=0, computer=0

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=1

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: rock => draw
score: human=0, computer=1

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=2

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=3

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=4

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=5

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=6

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=7

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=8

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=9

Your choice: ["rock", "paper", "scissors"]? r
H: rock, C: paper => Computer wins
score: human=0, computer=10

Run BASIC

<lang runbasic>pri$ = "RSPR" rps$ = "Rock,Paper,Sissors" [loop] button #r, "Rock", [r] button #p, "Paper", [p] button #s, "Scissors",[s] button #q, "Quit", [q] wait [r] y = 1 :goto [me] [p] y = 2 :goto [me] [s] y = 3 [me] cls y$ = word$(rps$,y,",") m = int((rnd(0) * 2) + 1) m$ = word$(rps$,m,",") print chr$(10);"You Chose:";y$;" I chose:";m$ yp = instr(pri$,left$(y$,1)) mp = instr(pri$,left$(m$,1)) if yp = 1 and mp = 3 then mp = 0 if mp = 1 and yp = 3 then yp = 0 if yp < mp then print "You win" if yp = mp then print "Tie" if yp > mp then print "I win" goto [loop] wait

[q] cls print "Good Bye! I enjoyed the game" end </lang>

Tcl

<lang tcl>package require Tcl 8.5

      1. Choices are represented by integers, which are indices into this list:
      2. Rock, Paper, Scissors
      3. Normally, idiomatic Tcl code uses names for these sorts of things, but it
      4. turns out that using integers simplifies the move-comparison logic.
  1. How to ask for a move from the human player

proc getHumanMove {} {

   while 1 {

puts -nonewline "Your move? \[R\]ock, \[P\]aper, \[S\]cissors: " flush stdout gets stdin line if {[eof stdin]} { puts "\nBye!" exit } set len [string length $line] foreach play {0 1 2} name {"rock" "paper" "scissors"} { # Do a prefix comparison if {$len && [string equal -nocase -length $len $line $name]} { return $play } } puts "Sorry, I don't understand that. Try again please."

   }

}

  1. How to ask for a move from the machine player

proc getMachineMove {} {

   global states
   set choice [expr {int(rand() * [::tcl::mathop::+ {*}$states 3])}]
   foreach play {1 2 0} count $states {

if {[incr sum [expr {$count+1}]] > $choice} { puts "I play \"[lindex {Rock Paper Scissors} $play]\"" return $play }

   }

}

  1. Initialize some state variables

set states {0 0 0} set humanWins 0 set machineWins 0

  1. The main game loop

while 1 {

   # Get the moves for this round
   set machineMove [getMachineMove]
   set humanMove [getHumanMove]
   # Report on what happened
   if {$humanMove == $machineMove} {

puts "A draw!"

   } elseif {($humanMove+1)%3 == $machineMove} {

puts "I win!" incr machineWins

   } else {

puts "You win!" incr humanWins

   }
   puts "Cumulative scores: $humanWins to you, $machineWins to me"
   # Update the state of how the human has played in the past
   lset states $humanMove [expr {[lindex $states $humanMove] + 1}]

}</lang> Sample run:

Your move? [R]ock, [P]aper, [S]cissors: rock
I play "Scissors"
You win!
Cumulative scores: 1 to you, 0 to me
Your move? [R]ock, [P]aper, [S]cissors: r
I play "Paper"
I win!
Cumulative scores: 1 to you, 1 to me
Your move? [R]ock, [P]aper, [S]cissors: s
I play "Paper"
You win!
Cumulative scores: 2 to you, 1 to me
Your move? [R]ock, [P]aper, [S]cissors: sciss
I play "Paper"
You win!
Cumulative scores: 3 to you, 1 to me
Your move? [R]ock, [P]aper, [S]cissors: p
I play "Paper"
A draw!
Cumulative scores: 3 to you, 1 to me
Your move? [R]ock, [P]aper, [S]cissors: zaphod beeblebrox
Sorry, I don't understand that. Try again please.
Your move? [R]ock, [P]aper, [S]cissors: r
I play "Scissors"
You win!
Cumulative scores: 4 to you, 1 to me
Your move? [R]ock, [P]aper, [S]cissors: ^D
Bye!

TorqueScript

Rock Paper Scissors in TorqueScript:

<lang TorqueScript> while(isobject(RockPaperScissors)) RockPaperScissors.delete();

new scriptObject(RockPaperScissors);

function RockPaperScissors::startGame(%this) { %this.idle = true; echo("Starting rock paper scissors, please type choose(\"choice\"); to proceed!"); }

function RockPaperScissors::endGame(%this) { %this.idle = true; }

function RockPaperScissors::main(%this) { %this.idle = 0;

if(getRandom(1,2) == 1) { %result = %this.getChoiceByUserFrequency(); } else { %c[0] = "rock"; %c[1] = "paper"; %c[2] = "scissors";

%result = %c[getRandom(0,2)]; }

%userChoice = %this.current;

%winner = thisVSthat(%userChoice,%result);

if(%winner == 0) { echo("You both chose "@%userChoice@", tie!"); } else if(%winner == 1) { echo("You chose "@%userChoice@" computer chose "@%result@", you win!"); } else if(%winner == 2) { echo("You chose "@%userChoice@" computer chose "@%result@", you lose!"); }

%this.idle = true; }

function RockPaperScissors::getChoiceByUserFrequency(%this) { %weakness["rock"] = "paper"; %weakness["paper"] = "Scissors"; %weakness["scissors"] = "rock";

%a[0] = %this.choice["rock"]; %a[1] = %this.choice["paper"]; %a[2] = %this.choice["Scissors"];

%b[0] = "rock"; %b[1] = "paper"; %b[2] = "scissors";

for(%i=0;%i<3;%i++) { %curr = %a[%i];

if(%temp $= "") { %temp = %curr; %tempi = %i; } else if(%curr > %temp) { %temp = %curr; %tempi = %i; } }

return %weakness[%b[%tempi]]; }

function choose(%this) { %rps = rockPaperScissors;

if(!%rps.idle) { return 0; } else if(%this !$= "rock" && %this !$= "paper" && %this !$= "scissors") { return 0; }

%rps.choice[%this]++; %rps.current = %this; %rps.main();

return %this; }

function thisVSthat(%this,%that) { if(%this !$= "rock" && %this !$= "paper" && %this !$= "scissors") { return 0; } else if(%that !$= "rock" && %that !$= "paper" && %that !$= "scissors") { return 0; }

%weakness["rock"] = "paper"; %weakness["paper"] = "Scissors"; %weakness["scissors"] = "rock";

if(%weakness[%this] $= %that) { %result = 2; } else if(%weakness[%that] $= %this) { %result = 1; } else %result = 0;

return %result; } </lang>

To begin do:

<lang TorqueScript> RockPaperScissors.startGame(); </lang>

Choose and play!

<lang TorqueScript> choose("Rock"); </lang>

=> You chose rock computer chose paper, you lose!

TI-83 BASIC

<lang ti83b>PROGRAM:RPS

{0,0,0}→L1
{0,0,0}→L2
Lbl ST
Disp "R/P/S"
Disp "1/2/3"
Lbl EC
Input A
If A>3 or A<1
Then
Goto NO
End
randInt(1,3+L1(1)+L1(2)+L1(3)→C
If C≤1+L1(1)
Then
2→B
Goto NS
End
If C>2+L1(2)
Then
1→B
Else
3→B
End
Lbl NS
L1(A)+1→L1(A)
If A=B
Then
Disp "TIE GAME"
L2(3)+1→L2(3)
Goto TG
End
If (A=1 and B=2) or (A=2 and B=3) or (A=3 and B=1)
Then
Disp "I WIN"
L2(1)+1→L2(1)
Else
Disp "YOU WIN"
L2(2)+1→L2(2)
End
Lbl TG
Disp "PLAY AGAIN?"
Input Str1
If Str1="YES"
Then
ClrHome
Goto ST
Else
Goto EN
End
Lbl NO
ClrHome
Pause "PICK 1,2, or 3"
ClrHome
Goto EC
Lbl EN
ClrHome
Disp "I WON:"
Disp L2(1)
Disp "YOU WON:"
Disp L2(2)
Disp "WE TIED:"
Disp L2(3)
Disp "BYE"

</lang>