New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dice-js

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dice-js - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

546

lib/dice.js
(function (exports) {
var derive = Object.create,
noOp = function () {},
isArray = Array.isArray,
plainSpec = {

@@ -41,13 +43,7 @@ enumerable: true,

function numericSort (a, b) {
return a - b;
}
function numericSort (a, b) { return a - b; }
function rollDie (sides) {
return Math.floor(Math.random() * sides) + 1;
}
function rollDie (sides) { return Math.floor(Math.random() * sides) + 1; }
function reduceSum (t, d) {
return (t + d);
}
function reduceSum (t, d) { return (t + d); }
//-----------------------------------------------------------------------

@@ -114,3 +110,3 @@ // Dice

this.rolled = true;
this._applyBehaviors();
this._applyBehaviors("roll");
return this.total;

@@ -138,3 +134,3 @@ }),

delete this.rolled;
this._applyBehaviors();
this._applyBehaviors("reset");
return this;

@@ -161,8 +157,24 @@ }),

toString: method(function () {
var count = this.count,
total = this.total
var spec = {
count: this.count,
sides: this.sides,
total: this.total,
modifiers: [],
results: this.results || [],
suffix: "",
addenda: ""
},
mod
;
return (count > 1 ? count : "") + "d" + this.sides +
(this.rolled ? " [" + this.results.join(", ") + "] = " + total : "");
this._applyBehaviors("toString", [spec]);
mod = spec.modifiers.reduce(reduceSum, 0);
return (spec.count > 1 ? spec.count : "") + "d" + spec.sides +
(mod !== 0 ? (mod > 0 ? "+" + mod : mod) : "") +
(this.rolled ? " [" + this.results.join(", ") + "] = " + spec.total +
(spec.suffix ? spec.suffix : "") +
(spec.addenda ? " (" + spec.addenda + ")" : "") :
"");
}),

@@ -198,221 +210,299 @@ /**

*/
_applyBehaviors: privateMethod(function () {
this._behaviors.forEach(this._applyBehavior, this);
_applyBehaviors: privateMethod(function (aspect, args) {
args = args || [];
args.unshift(this);
this._behaviors.forEach(function (behavior) {
behavior[aspect].apply(behavior, args);
}, this);
return this;
}),
/**
* Apply the passed behavior to this object
*
* @method _applyBehavior
* @private
* @param {function}
*/
_applyBehavior: privateMethod(function (fn) {
fn.call(this);
})
});
//-----------------------------------------------------------------------
// Behaviors
// Dice Behaviors
//-----------------------------------------------------------------------
behaviors = {
/**
* Apply a modifier to the total
*
* @param amt {number}
* @mutates Dice#total
*/
resultModifier: function (amt) {
return function () {
if (!this.rolled) {
return;
}
this.total += amt;
};
Dice.behaviors = behaviors = {};
function DiceBehavior () {
var init = this.init;
if (init && typeof init === "function") {
init.apply(this, arguments);
}
}
DiceBehavior.prototype = derive(Object.prototype, {
roll: method(noOp),
reset: method(noOp),
toString: method(noOp)
});
Dice.DiceBehavior = DiceBehavior;
function createBehavior (name, props) {
var ctor = function () { DiceBehavior.apply(this, arguments); };
merge((ctor.prototype = derive(DiceBehavior.prototype)), props);
return (behaviors[name] = ctor);
}
Dice.createBehavior = createBehavior;
function getBehavior (name) {
var behavior = behaviors[name],
proto, init, inst
;
if (!behavior) {
// throw an error
throw new Error("Unknown behavior '" + name + "'");
}
else {
proto = behavior.prototype;
if (typeof proto.init === "function") {
inst = derive(proto);
behavior.apply(inst, slice(arguments, 1));
return inst;
}
else {
return proto;
}
}
}
Dice.getBehavior = getBehavior;
function makeDiceFactory (sides, behaviors) {
return function (num) {
var dice = new Dice(num, sides);
if (behaviors) {
behaviors.forEach(function (args) {
dice.addBehavior(
isArray(args) ?
getBehavior.apply(null, args) :
getBehavior(args)
);
});
}
return dice;
};
}
Dice.makeDiceFactory = makeDiceFactory;
//-----------------------------------------------------------------------
// Bits and Pieces
//-----------------------------------------------------------------------
/**
* Apply a modifier to the total
*
* @param amt {number}
* @mutates Dice#total
*/
createBehavior("ResultModifier", {
init: function (amt) {
this.amount = amt;
},
/**
* Apply a modifier to every die
*
* @param amt {number}
* @mutates Dice#total
* @mutates Dice#results
*/
dieModifier: function (amt) {
return function () {
if (!this.rolled) {
return;
}
roll: function (dice) {
dice.total += this.amount;
},
toString: function (dice, spec) {
spec.modifiers.push(this.amount);
}
});
/**
* Apply a modifier to every die
*
* @param amt {number}
* @mutates Dice#total
* @mutates Dice#results
*/
createBehavior("DieModifier", {
init: function (amt) {
this.amount = amt;
},
roll: function (dice) {
dice.total += (this.amount * dice.count);
},
toString: function (dice, spec) {
spec.modifiers.push(this.amount * dice.count);
}
});
/**
* Remove *amt* lowest dice from the results.
*
* @param amt {number} number of low dice to discard
* @mutates Dice#total
* @property Dice#lowResults {array[number]}
*/
createBehavior("RemoveLowest", {
init: function (amt) {
this.amount = amt;
},
roll: function (dice) {
var results = dice.results.sort(numericSort).reverse();
dice.lowResults = results.splice(dice.count - this.amount);
dice.total = results.reduce(reduceSum, 0);
},
reset: function (dice) {
delete dice.lowResults;
},
toString: function (dice, spec) {
spec.addenda += "low: [" + dice.lowResults.join(", ") + "]";
}
});
this.total += amt * this.results.length;
};
/**
* Count the number of dice above a certain threshold
*
* @param amt {number} number or greater to count as a success
* @mutates Dice#total
* @mutates Dice#toString
* @property Dice#successes {number}
* @property Dice#failures {number}
* @property Dice#fumbled {boolean}
*/
createBehavior("SuccessDice", {
init: function (min) {
this.minimum = min;
},
/**
* Remove *amt* lowest dice from the results.
*
* @param amt {number} number of low dice to discard
* @mutates Dice#toal
* @mutates Dice#toString
* @property Dice#lowResults {array[number]}
*/
removeLowest: function (amt) {
return function () {
var dice;
if (!this.rolled) {
delete this.lowResults;
delete this.toString;
roll: function (dice) {
var total = 0,
failures = 0,
results = dice.results,
len = results.length,
count = dice.count,
min = this.minimum,
i, d
;
for (i = 0; i < len; i++) {
d = results[i];
if (d >= min) {
total++;
}
else {
this.lowResults = this.results.sort(numericSort).reverse().
splice(this.count - amt);
this.total = this.results.reduce(reduceSum, 0);
this.toString = function () {
return Dice.prototype.toString.call(this) +
" (low: [" + this.lowResults.join(", ") + "])";
};
// We only count ones as failures if in the original
// result set
else if (i < count && d === 1) {
failures++;
}
};
},
/**
* Count the number of dice above a certain threshold
*
* @param amt {number} number or greater to count as a success
* @mutates Dice#total
* @mutates Dice#toString
* @property Dice#successes {number}
* @property Dice#failures {number}
* @property Dice#fumbled {boolean}
*/
successDice: function (min) {
return function () {
var total, failures, count, results, i, len, d;
if (!this.rolled) {
delete this.successes;
delete this.failures;
delete this.toString;
}
else {
total = 0;
failures = 0;
results = this.results;
len = results.length;
count = this.count;
for (i = 0; i < len; i++) {
d = results[i];
if (d >= min) {
total++;
}
// We only count ones as failures if in the original
// result set
else if (i < count && d === 1) {
failures++;
}
}
}
this.successes = total;
this.failures = failures;
this.total = Math.max(total - failures, 0);
this.fumbled = failures > total;
this.toString = function () {
return (this.count ? this.count : "") + "d" + this.sides +
" [" + this.results.join(", ") + "] = " +
this.total + " successes" +
(this.fumbled ? "!" : "");
};
}
};
dice.successes = total;
dice.failures = failures;
dice.total = Math.max(total - failures, 0);
dice.fumbled = failures > total;
},
/**
* Determine the amount of Stun and Body
*
* @mutates Dice#toString
* @property Dice#body {number} number of body (die result: 1 = 0, 2-5 = 1, 6 = 2)
* @property Dice#stun {number} total of dice
*/
heroDice: function () {
return function () {
if (!this.rolled) {
delete this.body;
delete this.stun;
delete this.toString;
reset: function (dice) {
delete dice.successes;
delete dice.failures;
delete dice.fumbled;
},
toString: function (dice, spec) {
spec.suffix += " successes" + (dice.fumbled ? "!" : "");
}
});
/**
* Determine the amount of Stun and Body
*
* @mutates Dice#toString
* @property Dice#body {number} number of body (die result: 1 = 0, 2-5 = 1, 6 = 2)
* @property Dice#stun {number} total of dice
*/
createBehavior("HeroNormalDice", {
roll: function (dice) {
dice.body = dice.results.reduce(function (total, d) {
switch (d) {
case 1:
break;
case 6:
total += 2;
break;
default:
total += 1;
}
else {
this.body = this.results.reduce(function (total, d) {
switch (d) {
case 1:
break;
case 6:
total += 2;
break;
default:
total += 1;
}
return total;
}, 0);
this.stun = this.total;
this.toString = function () {
return Dice.prototype.toString.call(this) +
" stun, " + this.body + " body";
};
}
};
return total;
}, 0);
dice.stun = dice.total;
},
/**
* Specify a number of dice that are *wild*. If these dice roll the
* maximum amount, roll another die and add that to the total. The
* wild di(c)e continue to add as long as they roll the maximum.
*
* @param amt {number}
* @property Dice#wildDice {array[number]} results of the wild dice
* @property Dice#complications {boolean} if the wild die comes up a 1
* @mutates Dice#total
*/
wildDice: function (amt) {
return function () {
var dicesWild;
reset: function (dice) {
delete dice.body;
delete dice.stun;
},
toString: function (dice, spec) {
spec.suffix += " stun, " + dice.body + " body";
}
});
/**
* Specify a number of dice that are *wild*. If these dice roll the
* maximum amount, roll another die and add that to the total. The
* wild di(c)e continue to add as long as they roll the maximum.
*
* @param amt {number}
* @property Dice#wildDice {array[number]} results of the wild dice
* @property Dice#complications {boolean} if the wild die comes up a 1
* @mutates Dice#total
*/
createBehavior("WildDice", {
init: function (amt) {
this.amount = amt || 0;
},
roll: function (dice) {
var results = dice.results.slice().reverse(),
dicesWild = results.slice(0, this.amount || dice.results.length),
complications = 0
;
if (!this.rolled) {
delete this.wildDice;
delete this.complication;
delete this.toString;
dicesWild.forEach(function (die) {
var sides = dice.sides,
result
;
if (die === sides) {
do {
result = rollDie(sides);
dice.results.push(result);
} while (result === sides);
}
else {
dicesWild = this.results.slice().reverse().
slice(0, amt || this.results.length);
dicesWild.forEach(function (die) {
var sides = this.sides,
result
;
if (die === sides) {
do {
result = rollDie(sides);
this.results.push(result);
} while (result === sides);
}
else if (die === 1) {
if (!this.complications) {
this.complications = 0;
}
this.complications++;
}
}, this);
this.total = this.results.reduce(reduceSum, 0);
this.toString = function () {
var fails = this.complications;
return Dice.prototype.toString.call(this) +
(fails ? Array(fails + 1).join("!") : "");
};
else if (die === 1) {
complications++;
}
};
});
dice.total = dice.results.reduce(reduceSum, 0);
dice.complications = complications;
dice.complication = complications > 0;
},
reset: function (dice) {
delete dice.wildDice;
delete dice.complication;
delete dice.complications;
},
toString: function (dice, spec) {
var fails = dice.complication,
failures = dice.complications
;
spec.suffix += (fails ? Array(failures+1).join("!") : "");
}
};
});

@@ -424,28 +514,18 @@ //-----------------------------------------------------------------------

Dice: Dice,
diceBehaviors: behaviors,
/**
* Utility function/Class for creating Hero System Normal Dice
*
* @class HeroDice
* @function heroDice
* @param num {number}
* @returns {Dice}
*/
HeroDice: function (num) {
return new Dice(num, 6, [behaviors.heroDice()]);
},
heroDice: makeDiceFactory(6, ["HeroNormalDice"]),
/**
* Utility function/Class for creating a batch of Shadowrun Dice
*
* @class ShadowrunDice
* @function shadowrunDice
* @param num {number}
* @returns {Dice}
*/
ShadowrunDice: function (num) {
return new Dice(num, 6, [
behaviors.wildDice(),
behaviors.successDice(5)
]);
},
shadowrunDice: makeDiceFactory(6, ["WildDice", ["SuccessDice", 5]]),
/**

@@ -455,3 +535,3 @@ * Utility function/Class for creating West End Game's Star Wars

*
* @class WEGStarWarsDice
* @function d6StarWarsDice
* @param num {number}

@@ -461,7 +541,7 @@ * @param pips {number}

*/
WEGStarWarsDice: function (num, pips) {
var dice = new Dice(num, 6, [behaviors.wildDice(1)]);
d6StarWarsDice: function (num, pips) {
var dice = new Dice(num, 6, [getBehavior("WildDice", 1)]);
if (typeof pips === "number") {
dice.addBehavior(behaviors.resultModifier(pips));
dice.addBehavior(getBehavior("ResultModifier", pips));
}

@@ -468,0 +548,0 @@

{
"name": "dice-js",
"description": "Roll some dice.",
"version": "0.1.0",
"version": "0.2.0",
"keywords": [

@@ -6,0 +6,0 @@ "dice",

var lib = require("../"),
Dice = lib.Dice,
behaviors = lib.diceBehaviors
behaviors = Dice.behaviors
;

@@ -53,3 +53,3 @@

test("Roll 3d6+2", function () {
var dice = new Dice(3, 6, [behaviors.resultModifier(2)]),
var dice = new Dice(3, 6, [new behaviors.ResultModifier(2)]),
result, dietotal

@@ -71,3 +71,3 @@ ;

test("Roll 3d6 and add 1 to every die", function () {
var dice = new Dice(3, 6, [behaviors.dieModifier(1)]),
var dice = new Dice(3, 6, [new behaviors.DieModifier(1)]),
result, dietotal

@@ -93,3 +93,3 @@ ;

dice.addBehavior(behaviors.removeLowest(2));
dice.addBehavior(new behaviors.RemoveLowest(2));

@@ -106,3 +106,3 @@ results = dice.roll();

test("10d6 Hero Dice", function () {
var dice = new lib.HeroDice(10);
var dice = lib.heroDice(10);

@@ -119,3 +119,3 @@ dice.roll();

dice.addBehavior(behaviors.successDice(5));
dice.addBehavior(new behaviors.SuccessDice(5));

@@ -129,3 +129,3 @@ dice.roll();

test("6d6 Shadowrun dice", function () {
var dice = new lib.ShadowrunDice(6);
var dice = lib.shadowrunDice(6);
dice.roll();

@@ -136,3 +136,3 @@ console.log("" + dice);

test("6d6 WEG Star Wars", function () {
var dice = new lib.WEGStarWarsDice(6);
var dice = lib.d6StarWarsDice(6);
dice.roll();

@@ -143,3 +143,3 @@ console.log("" + dice);

test("4d6+2 WEG Star Wars", function () {
var dice = new lib.WEGStarWarsDice(4, 2);
var dice = lib.d6StarWarsDice(4, 2);
dice.roll();

@@ -150,5 +150,5 @@ dice.total.should.be.above(6);

("" + dice).should.match(/4d6 \[(\d+(?:, )?)+\] = \d+!?/);
("" + dice).should.match(/4d6\+2 \[(\d+(?:, )?)+\] = \d+!?/);
console.log("" + dice);
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc