Commit 0f391e31 authored by nanahira's avatar nanahira

rename calculate to eval and redo random generator

parent 15034991
...@@ -11,23 +11,6 @@ import { OneDice } from 'onedice'; ...@@ -11,23 +11,6 @@ import { OneDice } from 'onedice';
const onedice = new OneDice() const onedice = new OneDice()
onedice.calculate('1d6') onedice.eval('1d6')
onedice.calculate('2d3+3d4') onedice.eval('2d3+3d4')
``` ```
### Change Random Generator
```ts
class MyOneDice extends OneDice {
random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
```
### Extend operator
```ts
const onedice = new OneDice()
onedice.addOperator(new Operator('+', 1, (a, [o, b]) => a + b))
```
\ No newline at end of file
...@@ -59,11 +59,17 @@ export interface OneDiceConfig { ...@@ -59,11 +59,17 @@ export interface OneDiceConfig {
maxDiceFaces?: number; maxDiceFaces?: number;
valueDict?: { [key: string]: number }; valueDict?: { [key: string]: number };
defaultDiceFaces?: number; defaultDiceFaces?: number;
random?: () => number;
} }
export class OneDice { export class OneDice {
random(min: number, max: number): number { random() {
return Math.floor(Math.random() * (max - min + 1)) + min; // can be extended
return this.config.random ? this.config.random() : Math.random();
}
randomInt(min: number, max: number): number {
return Math.floor(this.random() * (max - min + 1)) + min;
} }
private splitThrow( private splitThrow(
...@@ -73,8 +79,8 @@ export class OneDice { ...@@ -73,8 +79,8 @@ export class OneDice {
if (count == null) { if (count == null) {
throw new Error('Count is required in pb.'); throw new Error('Count is required in pb.');
} }
const first = this.random(0, 9); const first = this.randomInt(0, 9);
const tens = range(count + 1).map(() => this.random(0, 9)); const tens = range(count + 1).map(() => this.randomInt(0, 9));
const tenFun = (ten: number) => (first === 0 && ten === 0 ? 10 : ten); const tenFun = (ten: number) => (first === 0 && ten === 0 ? 10 : ten);
const pickTen = picker(tens, tenFun); const pickTen = picker(tens, tenFun);
const combined = first + 10 * pickTen; const combined = first + 10 * pickTen;
...@@ -250,7 +256,7 @@ export class OneDice { ...@@ -250,7 +256,7 @@ export class OneDice {
this.pbThrow(pbCount, pb === '\x01' ? 'p' : 'b'), this.pbThrow(pbCount, pb === '\x01' ? 'p' : 'b'),
); );
} else { } else {
results = range(count).map(() => this.random(1, faces)); results = range(count).map(() => this.randomInt(1, faces));
} }
if (pool && min) { if (pool && min) {
return results.filter((r) => r >= min).length; return results.filter((r) => r >= min).length;
...@@ -283,7 +289,7 @@ export class OneDice { ...@@ -283,7 +289,7 @@ export class OneDice {
let totalResults: number[] = []; let totalResults: number[] = [];
let nextCount = count; let nextCount = count;
while (nextCount) { while (nextCount) {
const results = range(nextCount).map(() => this.random(1, faces)); const results = range(nextCount).map(() => this.randomInt(1, faces));
totalResults = totalResults.concat(results); totalResults = totalResults.concat(results);
nextCount = results.filter((r) => r >= addLine).length; nextCount = results.filter((r) => r >= addLine).length;
} }
...@@ -301,7 +307,7 @@ export class OneDice { ...@@ -301,7 +307,7 @@ export class OneDice {
const totalResults: number[][] = []; const totalResults: number[][] = [];
let nextCount = count; let nextCount = count;
while (nextCount) { while (nextCount) {
const results = range(nextCount).map(() => this.random(1, faces)); const results = range(nextCount).map(() => this.randomInt(1, faces));
totalResults.push(results); totalResults.push(results);
nextCount = results.filter((r) => r >= addLine).length; nextCount = results.filter((r) => r >= addLine).length;
} }
...@@ -312,7 +318,7 @@ export class OneDice { ...@@ -312,7 +318,7 @@ export class OneDice {
if (count < 1) { if (count < 1) {
throw new Error(`Invalid count: ${count}`); throw new Error(`Invalid count: ${count}`);
} }
return sum(range(count).map(() => this.random(-1, 1))); return sum(range(count).map(() => this.randomInt(-1, 1)));
}), }),
]; ];
...@@ -444,7 +450,7 @@ export class OneDice { ...@@ -444,7 +450,7 @@ export class OneDice {
const firstValue = numberStack.pop(); const firstValue = numberStack.pop();
operatorMiniStack.reverse(); operatorMiniStack.reverse();
numberMiniStack.reverse(); numberMiniStack.reverse();
// console.log('calculate', firstValue, numberMiniStack, operatorMiniStack); // console.log('eval', firstValue, numberMiniStack, operatorMiniStack);
const operator = this.operatorMap.get(operatorMiniStack[0]); const operator = this.operatorMap.get(operatorMiniStack[0]);
const calculated = operator.doCalculation( const calculated = operator.doCalculation(
firstValue, firstValue,
...@@ -455,7 +461,7 @@ export class OneDice { ...@@ -455,7 +461,7 @@ export class OneDice {
numberStack.push(calculated); numberStack.push(calculated);
} }
calculate(expr: string) { eval(expr: string) {
const chain = this.parseChain(expr); const chain = this.parseChain(expr);
const numberStack: number[] = []; const numberStack: number[] = [];
const operatorStack: string[] = []; const operatorStack: string[] = [];
...@@ -490,4 +496,9 @@ export class OneDice { ...@@ -490,4 +496,9 @@ export class OneDice {
} }
return numberStack[0]; return numberStack[0];
} }
// @deprecated
calculate(expr: string) {
return this.eval(expr);
}
} }
import { OneDice } from '../src/onedice'; import { OneDice } from '../src/onedice';
class TestOneDice extends OneDice {
random(min: number, max: number): number {
return max;
}
}
describe('Sample test.', () => { describe('Sample test.', () => {
const onedice = new TestOneDice({ const onedice = new OneDice({
valueDict: { valueDict: {
foo: 50, foo: 50,
bar: 60, bar: 60,
}, },
random: () => 0.99999,
}); });
it('should calculate', () => { it('should eval', () => {
expect(onedice.calculate('1+1')).toBe(2); expect(onedice.eval('1+1')).toBe(2);
expect(onedice.calculate('1+2*2')).toBe(5); expect(onedice.eval('1+2*2')).toBe(5);
expect(onedice.calculate('1+2*(2+3)')).toBe(11); expect(onedice.eval('1+2*(2+3)')).toBe(11);
}); });
it('should roll dice', () => { it('should roll dice', () => {
expect(onedice.calculate('1d1')).toBe(1); expect(onedice.eval('1d1')).toBe(1);
expect(onedice.calculate('1d2')).toBe(2); expect(onedice.eval('1d2')).toBe(2);
expect(onedice.calculate('2d3')).toBe(6); expect(onedice.eval('2d3')).toBe(6);
expect(onedice.calculate('2d3+1')).toBe(7); expect(onedice.eval('2d3+1')).toBe(7);
expect(onedice.calculate('2d3+4d(5*2)')).toBe(46); expect(onedice.eval('2d3+4d(5*2)')).toBe(46);
expect(onedice.calculate('d6')).toBe(6); expect(onedice.eval('d6')).toBe(6);
expect(onedice.calculate('d6+d6')).toBe(12); expect(onedice.eval('d6+d6')).toBe(12);
expect(onedice.calculate('1d+d6+d6')).toBe(18); expect(onedice.eval('1d+d6+d6')).toBe(18);
}); });
it('should pass onedice tests', () => { it('should pass onedice tests', () => {
expect(onedice.calculate('((1-1>2)|(1-1<2))?(1+1):(1-2)')).toBe(2); expect(onedice.eval('((1-1>2)|(1-1<2))?(1+1):(1-2)')).toBe(2);
expect(onedice.calculate('7d5f')).toBe(35); expect(onedice.eval('7d5f')).toBe(35);
}); });
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment