Rock Paper Scissors

December 10, 2013

This isn’t hard. But it is tedious. The call-with-current-continuation sets up for the early loop exit when the player quits.

(define (rps)
  (display "Welcome to Rock Paper Scissors. ") (newline)
  (call-with-current-continuation (lambda (return)
    (let ((cscore 0) (hscore 0))
      (let play ((cthrow (list-ref '(rock paper scissors) (randint 3)))
                 (hthrow 'none))
        (do () ((member hthrow '(rock paper scissors quit)))
          (display "Enter R, P or S to make your throw, or Q to quit: ")
          (let ((h (read)))
            (case (string-ref (symbol->string h) 0)
            ((#\r #\R) (set! hthrow 'rock))
            ((#\p #\P) (set! hthrow 'paper))
            ((#\s #\S) (set! hthrow 'scissors))
            ((#\q #\Q) (display "Thanks for playing.")
                       (newline)(return)))))
        (display " I throw ") (display cthrow)
        (cond ((and (eq? cthrow 'rock) (eq? hthrow 'paper))
                (set! hscore (+ hscore 1))
                (display ". Your paper wraps my rock. You win."))
              ((and (eq? cthrow 'paper) (eq? hthrow 'rock))
                (set! cscore (+ cscore 1))
                (display ". My paper wraps your rock. I win."))
              ((and (eq? cthrow 'paper) (eq? hthrow 'scissors))
                (set! hscore (+ hscore 1))
                (display ". Your scissors cuts my paper. You win."))
              ((and (eq? cthrow 'scissors) (eq? hthrow 'paper))
                (set! cscore (+ cscore 1))
                (display ". My scissors cuts your paper. I win."))
              ((and (eq? cthrow 'scissors) (eq? hthrow 'rock))
                (set! hscore (+ hscore 1))
                (display ". Your rock blunts my scissors. You win."))
              ((and (eq? cthrow 'rock) (eq? hthrow 'scissors))
                (set! cscore (+ cscore 1))
                (display ". My rock blunts your scissors. I win."))
              ((eq? cthrow hthrow)
                (display ". Our throws are the same. It's a tie.")))
        (newline) (display " ")
        (cond ((< cscore hscore)
                (display "You are winning: ") (display hscore)
                (display " to ") (display cscore) (display "."))
              ((< hscore cscore)
                (display "I am winning: ") (display cscore)
                (display " to ") (display hscore) (display "."))
              (else (display "The score is tied at ")
                    (display cscore) (display ".")))
        (newline)
        (play (list-ref '(rock paper scissors) (randint 3)) 'none))))))

We used randint from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/LZRKWkz9.

Advertisement

Pages: 1 2

9 Responses to “Rock Paper Scissors”

  1. Bonus points if the program uses a webcam to receive input?

  2. Haskell version (requires GHC, doesn’t run in codepad :( ). Not the most beautiful program in Haskell, but nevertheless

    http://codepad.org/3oEk8lKq

  3. Paul said

    In Python.

    from random import choice
    import sys
    
    opt = dict(zip("RPS", ("rock", "paper", "scissors")))
    verbs = {}
    verbs["RP"] = verbs["PR"] = "wraps"
    verbs["RS"] = verbs["SR"] = "blunts"
    verbs["SP"] = verbs["PS"] = "cut"
    
    def message(c, h):
        if c == h: return "Our throws are the same."
        if c + h in ("RS", "PR", "SP"):
            return " ".join(["My", opt[c], verbs[c + h], "your", opt[h] + ".", "I win."])
        else:
            return " ".join(["Your", opt[h], verbs[c + h], "my", opt[c] + ".", "You win."])
    
    print "Welcome to Rock Paper Scissors. "
    while 1:
        computer = choice("RPS")
        human = "None"
        while human not in "RPS":
            human = raw_input("Enter R, P or S to make your throw, or Q to quit: ").upper()
            if human.startswith("Q"):
                print "Game ended."
                sys.exit(0)
        mess = message(computer, human)
        print mess
        if mess.endswith("win."):
            print "New game."
    
  4. wilton said

    Badly written Clojure… /

    (def precedence '(:rock :scissors :paper precedence))
     
     (def human 0)
    
     (def machine 0)
     
     (def human-score (ref human))
     (def machine-score (ref machine))
      
     (defn machine-option []
       (nth precedence (rand-int 4)))
     
     (defn weight [option]
       (.indexOf precedence option))
     
     (defn show-score []
       (str "machine: " (deref machine-score)
            " human: " (deref human-score)))
     
     (defn winner [human-option]
       (if (> (weight human-option) 
              (weight (machine-option)))
         (dosync (alter human-score + 1))
         (dosync (alter machine-score + 1)))
       (show-score))
      
     (defn go [player-option]
       (winner player-option))
    
  5. Jussi Piitulainen said

    Not keeping score, so I lose, but anyway:

    #! /usr/bin/env gsi-script
    (display "Content-Type: text/plain") (newline)
    (newline)
    (random-source-randomize! default-random-source)
    (define parser '(("move=rock" . 0) ("move=paper" . 1) ("move=scissors" . 2)))
    (define writer
      '((0 . ((0 . "rock ties with rock") (1 . "paper wraps rock") (2 . "rock blunts scissors")))
        (1 . ((1 . "paper ties with paper") (2 . "scissors cut paper")))
        (2 . ((2 . "scissors tie with scissors")))))
    (define (judge client server)
      (cond
       ((= client server) " - it's a tie")
       ((= (modulo (+ client 1) 3) server) " - server wins")
       ((= client (modulo (+ server 1) 3)) " - client wins")))
    (define client-move (cdr (assoc (getenv "QUERY_STRING") parser)))
    (define server-move (random-integer 3))
    (define lesser (cdr (assoc (min client-move server-move) writer)))
    (display (list-ref '("rock! " "paper! " "scissors! ") server-move))
    (display (cdr (assoc (max client-move server-move) lesser)))
    (display (judge client-move server-move))
    (newline)

    It’s a Gambit CGI script. With a web server running locally in port 8080 and accepting CGI programs in cwd, play like this:

    $ curl http://localhost:8080/rock.cgi'?'move=paper
    rock! paper wraps rock - client wins

  6. happyout!! said

    any java code for rock paper scissors.. it would be two clients and a server?

  7. JP said

    Here’s a Racket version with a bunch of different AIs to play against (or against each other): Rock-paper-scissors on jverkamp.com.

    Granted, none of them are that smart (I’m considering writing one based on a Hidden Markov Model), but it’s still pretty neat.

  8. lmonaco99 said

    Here is a PHP version.
    Not too happy with a couple of sections, but overall not bad. https://github.com/lmon/samples/blob/master/RockPaperScissors.php

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: