-
-
Save FireyFly/5426471 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function RPS(count) { | |
this.players = count | |
this.score = range(count).map(Const(0)) | |
this.moves = range(count).map(limit(Array,0)) | |
} | |
RPS.prototype.beats = { "rock": "scissors", | |
"paper": "rock", | |
"scissors": "paper" } | |
RPS.prototype.wins = function (p1, p2) { | |
return (this.beats[p1] == p2) | |
} | |
RPS.prototype.calcScore = function (winners, move) { | |
return contains(winners, move)? 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 = uniqes(moves) | |
, 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)) | |
}) | |
//-- Helpers --------------- | |
function uniques(arr) { | |
return arr.filter(function (x, i) { | |
// make sure that `x` isn't in the tail of the array | |
return !contains(arr, x, i+1) | |
}) | |
} | |
} | |
RPS.prototype.move = function(moves) { | |
this.moves.forEach(function (x) { | |
x.push(x) | |
}) | |
// for (var i = 0; i < this.players; i++) | |
// this.moves[i].push(moves[i]) | |
var winners = this.winningWeapons(moves) | |
, scores = moves.map(this.calcScore.bind(this, winners)) | |
this.score = this.score.map(function (x, i) { | |
return x + scores[i] | |
}) | |
// return all the winning players | |
var winning_players = moves.reduce(function (p, c, i) { | |
return contains(winners, c)? p.concat([i]) | |
: /*else*/ p | |
}, []) | |
return winning_players | |
} | |
RPS.prototype.AI = function() { | |
return randomElementOf(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 | |
//-- Helpers --------------- | |
// Returns an array [0..n-1]. | |
function range(n) { | |
var res = [] | |
for (var i=0; i<n; i++) { res.push(i) } | |
return res | |
} | |
// Returns a function which always returns `x`. | |
function Const(x) { return function () { return x } } | |
// Predicate that checks whether `elem` occurs in `arr` (starting at `offset`). | |
function contains(arr, elem, offset) { | |
return arr.indexOf(elem, offset) >= 0 | |
} | |
// Limits a function to taking `count` arguments. | |
function limit(f, count) { | |
return function (/*...*/) { | |
var args = Array.prototype.slice.call(arguments, 0, count) | |
return f.apply(this, args) | |
} | |
} | |
// Returns a randomly-chosen element of `arr`. | |
function randomElementOf(arr) { | |
return arr[arr.length * Math.random() | 0] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment