A tweet-sized, fork-to-play, implementation of the game Paper/Scissors/Rock/Lizard/Spock
-
-
Save padawin/11213132 to your computer and use it in GitHub Desktop.
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> |
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}
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}
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?
%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.
fair enough, it makes sense.
changed :-)
or you just replace .indexOf with .search
Thanks, updated
How about golfing this down to 85 chars?