mana-scribe 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/package.json +1 -2
- package/src/arrayComparison.js +50 -0
- package/src/costs/ManaCost.js +13 -0
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ Supports both brace `{3}{R/U}` and shortform `3R/U` notation.
|
|
|
14
14
|
- Converted mana cost
|
|
15
15
|
- Color identity
|
|
16
16
|
- Devotion
|
|
17
|
+
- Compare mana costs to evaluate if they are equal, greater than, or less than each other.
|
|
17
18
|
- Extensible design — add new symbol types by subclassing
|
|
18
19
|
|
|
19
20
|
Note: When the parser encounters an unrecognized symbol it stops parsing and returns the symbols it parsed so far. You can access the unparsed string component through the property `remainingStr`.
|
|
@@ -44,8 +45,24 @@ console.log(cost.cmc); // 3
|
|
|
44
45
|
console.log(cost.colors); // ['W','U','B']
|
|
45
46
|
```
|
|
46
47
|
|
|
48
|
+
### Comparison example
|
|
49
|
+
The `ManaCost` class supports equality and comparison operators under superset semantics:
|
|
50
|
+
|
|
51
|
+
- `equals(other)` → true if the costs are exactly the same
|
|
52
|
+
- `greaterThan(other)` → true if this cost includes all symbols of other plus additional ones, or generic mana cost is higher.
|
|
53
|
+
- `lessThan(other)` → true if this cost is a strict subset of other, or generic mana cost is lower.
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const a = ManaCost.parse('{3}{B}{B}{B}');
|
|
57
|
+
const b = ManaCost.parse('{1}{B}{B}{B}');
|
|
58
|
+
|
|
59
|
+
console.log(a.equals(b)); // false
|
|
60
|
+
console.log(a.greaterThan(b)); // true
|
|
61
|
+
console.log(b.lessThan(a)); // true
|
|
62
|
+
```
|
|
63
|
+
|
|
47
64
|
## Activation costs
|
|
48
|
-
`ActivationCost` offers the same functionality as the `ManaCost` class, but supports additional symbols such as Tap, Untap, and Energy.
|
|
65
|
+
`ActivationCost` offers the same functionality as the `ManaCost` class, but supports additional symbols such as Tap, Untap, and Energy. It does not have comparison functions.
|
|
49
66
|
|
|
50
67
|
```js
|
|
51
68
|
import { ActivationCost } from 'mana-scribe';
|
|
@@ -72,6 +89,7 @@ This is an early but complete implementation.
|
|
|
72
89
|
Current priorities:
|
|
73
90
|
- [x] Support core MTG symbols
|
|
74
91
|
- [x] Add test coverage
|
|
92
|
+
- [x] Add cost comparison
|
|
75
93
|
- [ ] Other improvements? TBD
|
|
76
94
|
|
|
77
95
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mana-scribe",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Library for parsing and querying Magic: The Gathering mana costs — with support for CMC, devotion, and color identity.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mtg",
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"cost",
|
|
10
10
|
"parser"
|
|
11
11
|
],
|
|
12
|
-
"homepage": "https://github.com/matortheeternal/mana-scribe#readme",
|
|
13
12
|
"bugs": {
|
|
14
13
|
"url": "https://github.com/matortheeternal/mana-scribe/issues"
|
|
15
14
|
},
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
function toFrequencyMap(arr) {
|
|
2
|
+
const map = new Map();
|
|
3
|
+
for (const el of arr) {
|
|
4
|
+
if (el.type === 'genericMana' || el.type === 'infiniteMana') {
|
|
5
|
+
map.set('generic', (map.get('generic') || 0) + el.cmcValue());
|
|
6
|
+
} else {
|
|
7
|
+
const key = el.toString();
|
|
8
|
+
map.set(key, (map.get(key) || 0) + 1);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return map;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function arrayEquals(arr1, arr2) {
|
|
15
|
+
const m1 = toFrequencyMap(arr1);
|
|
16
|
+
const m2 = toFrequencyMap(arr2);
|
|
17
|
+
|
|
18
|
+
if (m1.size !== m2.size) return false;
|
|
19
|
+
for (const [key, count] of m1.entries()) {
|
|
20
|
+
if ((m2.get(key) || 0) !== count) return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function arrayGreaterThan(arr1, arr2) {
|
|
26
|
+
const m1 = toFrequencyMap(arr1);
|
|
27
|
+
const m2 = toFrequencyMap(arr2);
|
|
28
|
+
|
|
29
|
+
let larger = false;
|
|
30
|
+
for (const [key, count] of m2.entries()) {
|
|
31
|
+
if ((m1.get(key) || 0) < count) return false;
|
|
32
|
+
larger = larger || m1.get(key) > count;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return larger || m1.size > m2.size;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function arrayLessThan(arr1, arr2) {
|
|
39
|
+
const m1 = toFrequencyMap(arr1);
|
|
40
|
+
const m2 = toFrequencyMap(arr2);
|
|
41
|
+
|
|
42
|
+
let smaller = false;
|
|
43
|
+
for (const [key, count] of m1.entries()) {
|
|
44
|
+
if ((m2.get(key) || 0) < count) return false;
|
|
45
|
+
smaller = smaller || (count < (m2.get(key) || 0));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return smaller || m1.size < m2.size;
|
|
49
|
+
}
|
|
50
|
+
|
package/src/costs/ManaCost.js
CHANGED
|
@@ -13,6 +13,7 @@ import SnowManaSymbol from '../symbols/SnowManaSymbol.js';
|
|
|
13
13
|
import ThreeColorHybridManaSymbol from '../symbols/ThreeColorHybridManaSymbol.js';
|
|
14
14
|
import TwoColorHybridManaSymbol from '../symbols/TwoColorHybridManaSymbol.js';
|
|
15
15
|
import VariableManaSymbol from '../symbols/VariableManaSymbol.js';
|
|
16
|
+
import {arrayEquals, arrayGreaterThan, arrayLessThan} from '../arrayComparison.js';
|
|
16
17
|
|
|
17
18
|
export default class ManaCost extends Cost {
|
|
18
19
|
static get allowedSymbols() {
|
|
@@ -35,4 +36,16 @@ export default class ManaCost extends Cost {
|
|
|
35
36
|
return devotion + (sym.colors.includes(color) ? 1 : 0);
|
|
36
37
|
}, 0);
|
|
37
38
|
}
|
|
39
|
+
|
|
40
|
+
equals(other) {
|
|
41
|
+
return arrayEquals(this.symbols, other.symbols);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
greaterThan(other) {
|
|
45
|
+
return arrayGreaterThan(this.symbols, other.symbols);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
lessThan(other) {
|
|
49
|
+
return arrayLessThan(this.symbols, other.symbols);
|
|
50
|
+
}
|
|
38
51
|
}
|