Skip to content

Instantly share code, notes, and snippets.

@yorickvP
Created January 15, 2013 01:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yorickvP/4535121 to your computer and use it in GitHub Desktop.
Save yorickvP/4535121 to your computer and use it in GitHub Desktop.
rock paper scissors for more than 2 players and extensible
function RPS(noPlayers, proto) {
var obj = Object.create(proto || RPS.prototype)
obj.players = noPlayers
obj.score = {}
obj.moves = {}
for (var i = 0; i < noPlayers; i++) {
obj.score[i] = 0
obj.moves[i] = [] }
return obj }
RPS.prototype.beats =
{ "rock": "scissors"
, "paper": "rock"
, "scissors": "paper" }
RPS.prototype.wins = function(p1, p2) {
return (this.beats[p1] == p2) }
// found on stackoverflow
Array.prototype.unique = function(a){
return function(){return this.filter(a)}}
(function(a,b,c){return c.indexOf(a,b+1)<0
});
RPS.prototype.calcscore = function(winners, move) {
return (winners.indexOf(move) != -1) ? 1 : 0 }
// if the weapons don't form a cycle, the upper one wins
// otherwise, it's a draw
RPS.prototype.winningweapons = function(moves) {
var uniquemoves = moves.unique()
var wins = this.wins.bind(this)
return uniquemoves.filter(function(weapon) {
// every move is beaten by this one, or it is this one
// but it needs to beat at least one move
var others = uniquemoves.filter(function(move) {
return move != weapon })
return others.length > 0 &&
others.every(wins.bind(0, weapon)) })}
RPS.prototype.move = function(moves) {
for (var i = 0; i < this.players; i++)
this.moves[i].push(moves[i])
var winners = this.winningweapons(moves)
var scores = moves.map(this.calcscore.bind(this, winners))
for (var i = 0; i < this.players; i++)
this.score[i] += scores[i]
// return all the winning players
var winning_players = moves.reduce(function(p, c, i) {
return winners.indexOf(c) != -1 ? p.concat([i]) : p
}, [])
return winning_players }
function randfromArr(a) {
return a[(a.length * Math.random()) | 0] }
RPS.prototype.AI = function() {
return randfromArr(Object.keys(this.beats)) }
if (module && module.exports) {
module.exports = RPS }
// example usage:
// game = RPS(2) // 2 is the number of players
// game.move(["scissors", game.AI()])
// the return object is an array of the winning players
// score is inside game.score
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment