Skip to content

Instantly share code, notes, and snippets.

@padawin
Forked from 140bytes/LICENSE.txt
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save padawin/11213132 to your computer and use it in GitHub Desktop.
Save padawin/11213132 to your computer and use it in GitHub Desktop.

Paper Scissors Rock Lizard Spock

A tweet-sized, fork-to-play, implementation of the game Paper/Scissors/Rock/Lizard/Spock

function(
p // p is the player choice, a char in
// ['P','R','L','V','S']. If p is any other
// char, the result will be the same as with
// 'S'
// P is for Paper
// R is for Rock
// L is for Lizard
// V is for Spock
// S is for Scissors
// Each choice is associated to its index in
// the string. For each index I, here is the
// list of the indexes I can beat:
// 0 => 1, 3 (Paper beats Rock and Spock)
// 1 => 2, 4 (Rock beats Lizard and Scissors)
// 2 => 3, 0 (Lizard beats Spock and Paper)
// 3 => 4, 1 (Spock beats Scissors and Rock)
// 4 => 0, 2 (Scissors beats Paper and Lizard)
){
p='PRLVS'.search(p) // Convert the player choice into an integer
+5-( // To that add 5 and subtract the computer
// choice (randomly generated)
0| // This is to floor the computer choice
Math.random()*5 // Computer choice, which is a float between
// 0 and 5
);
return // Return 1 if the game is a draw, true if
// the player wins or false if the computer
// wins
(p%=5) // Redifine p as p%5. For the player to win,
// (the difference between the player and the
// computer choice) modulo 5 must be equal to
// 2 or 4. If the modulo is 0, the game is a
// draw, otherwise (1 or 3), the computer wins.
?
!(p&1) // different than zero, return true if even
// result, false if odd result
:
1 // draw
}
<html>
<head></head>
<body>
<span id="result"></span>
<script type="text/javascript">
var prlvs = function(p,c){p='PRLVS'.search(p)+5-c;return(p%=5)?!(p&1):1}
var list = {
'win': [
['P', 1],
['P', 3],
['R', 2],
['R', 4],
['L', 3],
['L', 0],
['V', 4],
['V', 1],
['S', 0],
['S', 2]
],
'lose': [
['P', 2],
['P', 4],
['R', 0],
['R', 3],
['L', 1],
['L', 4],
['V', 0],
['V', 2],
['S', 1],
['S', 3]
],
'draw': [
['P', 0],
['R', 1],
['L', 2],
['V', 3],
['S', 4],
]
};
for (var result in list) {
document.getElementById('result').innerHTML += 'Expected result: ' + result + '<br />';
for (var m in list[result]) {
var move = prlvs(list[result][m][0], list[result][m][1]);
if(move === true)
document.getElementById('result').innerHTML += 'You won<br />';
else if (move === false)
document.getElementById('result').innerHTML += 'You lost<br />';
else
document.getElementById('result').innerHTML += 'draw<br />';
}
}
</script>
</body>
</html>
function(p){p='PRLVS'.search(p)+5-(0|Math.random()*5);return(p%=5)?!(p&1):1}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "PaperScissorsRockLizardSpock",
"description": "Implementation of the Famous game
Paper/Scissors/Rock/Lizard/Spock in less than 140 bytes",
"keywords": [
"Paper",
"Scissors",
"Rock",
"Lizard",
"Spock",
"Game"
]
}
<html>
<head></head>
<body>
<select id="player">
<option value="P">Paper</option>
<option value="R">Rock</option>
<option value="L">Lizard</option>
<option value="V">Spock</option>
<option value="S">Scissor</option>
</select>
<input type="button" id="playbtn" value="Play"/>
<span id="result"></span>
<script type="text/javascript">
var prlvs = function(p){p='PRLVS'.search(p)+5-(0|Math.random()*5);return(p%=5)?!(p&1):1}
document.getElementById('playbtn').onclick=function(){
var result = prlvs(document.getElementById('player').value);
if(result === true)
document.getElementById('result').innerHTML = 'You won';
else if (result === false)
document.getElementById('result').innerHTML = 'You lost';
else
document.getElementById('result').innerHTML = 'draw';
}
</script>
</body>
</html>
@atk
Copy link

atk commented Apr 24, 2014

How about golfing this down to 85 chars?

function(p,c){p='PRLVS'.indexOf(p);c=0|Math.random()*5;return(p=(p+5-c)%5)?!!(p&1):1}

@atk
Copy link

atk commented Apr 24, 2014

Wait, c is only used once, so we can remove it safely, golfing it down to 81 chars:

function(p){p='PRLVS'.indexOf(p);return(p=(p+5-(0|Math.random()*5))%5)?!!(p&1):1}

@atk
Copy link

atk commented Apr 24, 2014

And by pulling most of the calculation into the first expression, we can remove 3 more bytes (down to 78):

function(p){p='PRLVS'.indexOf(p)+5-(0|Math.random()*5);return(p%=5)?!!(p&1):1}

@padawin
Copy link
Author

padawin commented Apr 28, 2014

Awesome, thanks!

I learnt quite a few thinks in your optimisations:

  • Doing a floor like that, quite handy: 0|Math.random()*5
  • convert 1 or 0 to boolean with !!(...), that's so obvious, but I never thought about it....

However, your version returns false if the player wins and true if the computer wins. Easily fixed by removing a !
in the last test (which downs it to 77 ;-) ).
When I rewrote it to understand your changes, I ended with the version p%2 instead of p&1, do you think one's better than the other?

@atk
Copy link

atk commented Apr 29, 2014

%2 and &1 are basically doing the same, but the latter is faster, since it uses long int instead of float.
I like to remind people that there are binary operations around in JS which are quite powerful and really, really fast.

@padawin
Copy link
Author

padawin commented Apr 29, 2014

fair enough, it makes sense.

changed :-)

@tsaniel
Copy link

tsaniel commented Apr 30, 2014

or you just replace .indexOf with .search

@padawin
Copy link
Author

padawin commented May 8, 2014

Thanks, updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment