libram 0.4.0 → 0.4.1
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/dist/combat.d.ts +2 -1
- package/dist/combat.js +3 -2
- package/dist/diet/index.d.ts +16 -0
- package/dist/diet/index.js +439 -0
- package/dist/diet/knapsack.d.ts +7 -0
- package/dist/diet/knapsack.js +116 -0
- package/dist/lib.d.ts +20 -0
- package/dist/lib.js +49 -2
- package/dist/maximize.js +36 -30
- package/dist/modifier.d.ts +4 -0
- package/dist/propertyTypes.d.ts +2 -2
- package/dist/resources/2010/CrownOfThrones.d.ts +9 -0
- package/dist/resources/2010/CrownOfThrones.js +374 -0
- package/dist/resources/index.d.ts +16 -14
- package/dist/resources/index.js +39 -34
- package/dist/ring-buffer.d.ts +24 -0
- package/dist/ring-buffer.js +135 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.js +18 -0
- package/package.json +2 -1
- package/dist/libram-example-briefcase.js +0 -16073
- package/dist/libram-example-clan.js +0 -7050
- package/dist/libram-example-consult.js +0 -5032
- package/dist/libram-example-item.js +0 -2870
- package/dist/libram-example-kmail.js +0 -2065
- package/dist/libram-example-lib.js +0 -6369
- package/dist/libram-example-modifier.js +0 -4495
- package/dist/libram-example-props.js +0 -3996
- package/dist/libram-example-resources.js +0 -10461
package/dist/combat.d.ts
CHANGED
|
@@ -100,9 +100,10 @@ export declare class Macro {
|
|
|
100
100
|
* Conditionally add a step to a macro based on a condition evaluated at the time of building the macro.
|
|
101
101
|
* @param condition The JS condition.
|
|
102
102
|
* @param ifTrue Continuation to add if the condition is true.
|
|
103
|
+
* @param ifFalse Optional input to turn this into an if...else statement.
|
|
103
104
|
* @returns {Macro} This object itself.
|
|
104
105
|
*/
|
|
105
|
-
externalIf(condition: boolean, ifTrue: string | Macro): this;
|
|
106
|
+
externalIf(condition: boolean, ifTrue: string | Macro, ifFalse?: string | Macro): this;
|
|
106
107
|
/**
|
|
107
108
|
* Create a new macro with a condition evaluated at the time of building the macro.
|
|
108
109
|
* @param condition The JS condition.
|
package/dist/combat.js
CHANGED
|
@@ -273,10 +273,11 @@ var Macro = /*#__PURE__*/function () {
|
|
|
273
273
|
* Conditionally add a step to a macro based on a condition evaluated at the time of building the macro.
|
|
274
274
|
* @param condition The JS condition.
|
|
275
275
|
* @param ifTrue Continuation to add if the condition is true.
|
|
276
|
+
* @param ifFalse Optional input to turn this into an if...else statement.
|
|
276
277
|
* @returns {Macro} This object itself.
|
|
277
278
|
*/
|
|
278
|
-
function externalIf(condition, ifTrue) {
|
|
279
|
-
|
|
279
|
+
function externalIf(condition, ifTrue, ifFalse) {
|
|
280
|
+
if (condition) return this.step(ifTrue);else if (ifFalse) return this.step(ifFalse);else return this;
|
|
280
281
|
}
|
|
281
282
|
/**
|
|
282
283
|
* Create a new macro with a condition evaluated at the time of building the macro.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class MenuItem {
|
|
2
|
+
item: Item;
|
|
3
|
+
maximum?: number;
|
|
4
|
+
additionalValue?: number;
|
|
5
|
+
size: number;
|
|
6
|
+
static seasoning: MenuItem;
|
|
7
|
+
static mayoflex: MenuItem;
|
|
8
|
+
static fork: MenuItem;
|
|
9
|
+
static mug: MenuItem;
|
|
10
|
+
constructor(item: Item, maximum?: number, additionalValue?: number, size?: number);
|
|
11
|
+
toString(): string;
|
|
12
|
+
price(): number;
|
|
13
|
+
}
|
|
14
|
+
declare type Organ = "food" | "booze" | "spleen item";
|
|
15
|
+
export declare function planDiet(mpa: number, menu: MenuItem[], organCapacities?: [Organ, number | null][]): [Item[], number][];
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/es.symbol.js");
|
|
4
|
+
|
|
5
|
+
require("core-js/modules/es.symbol.description.js");
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "__esModule", {
|
|
8
|
+
value: true
|
|
9
|
+
});
|
|
10
|
+
exports.planDiet = planDiet;
|
|
11
|
+
exports.MenuItem = void 0;
|
|
12
|
+
|
|
13
|
+
require("core-js/modules/es.array.map.js");
|
|
14
|
+
|
|
15
|
+
require("core-js/modules/es.regexp.exec.js");
|
|
16
|
+
|
|
17
|
+
require("core-js/modules/es.string.split.js");
|
|
18
|
+
|
|
19
|
+
require("core-js/modules/es.array.iterator.js");
|
|
20
|
+
|
|
21
|
+
require("core-js/modules/es.object.to-string.js");
|
|
22
|
+
|
|
23
|
+
require("core-js/modules/es.regexp.to-string.js");
|
|
24
|
+
|
|
25
|
+
require("core-js/modules/es.array.filter.js");
|
|
26
|
+
|
|
27
|
+
require("core-js/modules/es.array.includes.js");
|
|
28
|
+
|
|
29
|
+
require("core-js/modules/es.array.sort.js");
|
|
30
|
+
|
|
31
|
+
require("core-js/modules/es.string.includes.js");
|
|
32
|
+
|
|
33
|
+
require("core-js/modules/es.array.concat.js");
|
|
34
|
+
|
|
35
|
+
require("core-js/modules/es.array.slice.js");
|
|
36
|
+
|
|
37
|
+
require("core-js/modules/es.array.find.js");
|
|
38
|
+
|
|
39
|
+
var _kolmafia = require("kolmafia");
|
|
40
|
+
|
|
41
|
+
var _knapsack3 = require("./knapsack");
|
|
42
|
+
|
|
43
|
+
var _lib = require("../lib");
|
|
44
|
+
|
|
45
|
+
var _templateString = require("../template-string");
|
|
46
|
+
|
|
47
|
+
var _utils = require("../utils");
|
|
48
|
+
|
|
49
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19, _templateObject20;
|
|
50
|
+
|
|
51
|
+
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
52
|
+
|
|
53
|
+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
54
|
+
|
|
55
|
+
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
56
|
+
|
|
57
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
58
|
+
|
|
59
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
60
|
+
|
|
61
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
62
|
+
|
|
63
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
64
|
+
|
|
65
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
66
|
+
|
|
67
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
68
|
+
|
|
69
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
70
|
+
|
|
71
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
72
|
+
|
|
73
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
74
|
+
|
|
75
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
76
|
+
|
|
77
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
78
|
+
|
|
79
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
80
|
+
|
|
81
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
82
|
+
|
|
83
|
+
// TODO: Include other consumption modifiers.
|
|
84
|
+
function expectedAdventures(item) {
|
|
85
|
+
var forkMug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
86
|
+
if (item.adventures === "") return 0;
|
|
87
|
+
|
|
88
|
+
var _item$adventures$spli = item.adventures.split(/[-–—]/).map(s => parseInt(s)),
|
|
89
|
+
_item$adventures$spli2 = _slicedToArray(_item$adventures$spli, 2),
|
|
90
|
+
min = _item$adventures$spli2[0],
|
|
91
|
+
recordedMax = _item$adventures$spli2[1];
|
|
92
|
+
|
|
93
|
+
var max = recordedMax !== null && recordedMax !== void 0 ? recordedMax : min;
|
|
94
|
+
|
|
95
|
+
var interpolated = _toConsumableArray(new Array(max - min + 1).keys()).map(n => n + min);
|
|
96
|
+
|
|
97
|
+
return (0, _utils.sum)(interpolated, n => Math.floor(n * (forkMug ? 1.3 : 1))) / interpolated.length;
|
|
98
|
+
} // Assuming list is already sorted, count adjacent items.
|
|
99
|
+
// Effectively run-length encoding.
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
function aggregate(list, isEqual) {
|
|
103
|
+
var aggregatedList = [];
|
|
104
|
+
|
|
105
|
+
var _iterator = _createForOfIteratorHelper(list),
|
|
106
|
+
_step;
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
110
|
+
var item = _step.value;
|
|
111
|
+
|
|
112
|
+
if (aggregatedList.length === 0) {
|
|
113
|
+
aggregatedList.push([item, 1]);
|
|
114
|
+
} else {
|
|
115
|
+
var last = aggregatedList[aggregatedList.length - 1];
|
|
116
|
+
|
|
117
|
+
var _last = _slicedToArray(last, 1),
|
|
118
|
+
lastItem = _last[0];
|
|
119
|
+
|
|
120
|
+
if (isEqual(item, lastItem)) {
|
|
121
|
+
last[1]++;
|
|
122
|
+
} else {
|
|
123
|
+
aggregatedList.push([item, 1]);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} catch (err) {
|
|
128
|
+
_iterator.e(err);
|
|
129
|
+
} finally {
|
|
130
|
+
_iterator.f();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return aggregatedList;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var MenuItem = /*#__PURE__*/function () {
|
|
137
|
+
function MenuItem(item, maximum, additionalValue, size) {
|
|
138
|
+
_classCallCheck(this, MenuItem);
|
|
139
|
+
|
|
140
|
+
_defineProperty(this, "item", void 0);
|
|
141
|
+
|
|
142
|
+
_defineProperty(this, "maximum", void 0);
|
|
143
|
+
|
|
144
|
+
_defineProperty(this, "additionalValue", void 0);
|
|
145
|
+
|
|
146
|
+
_defineProperty(this, "size", void 0);
|
|
147
|
+
|
|
148
|
+
this.item = item;
|
|
149
|
+
this.maximum = maximum;
|
|
150
|
+
this.additionalValue = additionalValue;
|
|
151
|
+
var typ = (0, _kolmafia.itemType)(this.item);
|
|
152
|
+
this.size = (size !== null && size !== void 0 ? size : typ === "food") ? this.item.fullness : typ === "booze" ? this.item.inebriety : typ === "spleen item" ? this.item.spleen : 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
_createClass(MenuItem, [{
|
|
156
|
+
key: "toString",
|
|
157
|
+
value: function toString() {
|
|
158
|
+
return this.item.toString();
|
|
159
|
+
}
|
|
160
|
+
}, {
|
|
161
|
+
key: "price",
|
|
162
|
+
value: function price() {
|
|
163
|
+
return (0, _kolmafia.npcPrice)(this.item) > 0 ? (0, _kolmafia.npcPrice)(this.item) : (0, _kolmafia.mallPrice)(this.item);
|
|
164
|
+
}
|
|
165
|
+
}]);
|
|
166
|
+
|
|
167
|
+
return MenuItem;
|
|
168
|
+
}();
|
|
169
|
+
|
|
170
|
+
exports.MenuItem = MenuItem;
|
|
171
|
+
|
|
172
|
+
_defineProperty(MenuItem, "seasoning", new MenuItem((0, _templateString.$item)(_templateObject17 || (_templateObject17 = _taggedTemplateLiteral(["Special Seasoning"])))));
|
|
173
|
+
|
|
174
|
+
_defineProperty(MenuItem, "mayoflex", new MenuItem((0, _templateString.$item)(_templateObject18 || (_templateObject18 = _taggedTemplateLiteral(["Mayoflex"])))));
|
|
175
|
+
|
|
176
|
+
_defineProperty(MenuItem, "fork", new MenuItem((0, _templateString.$item)(_templateObject19 || (_templateObject19 = _taggedTemplateLiteral(["Ol' Scratch's salad fork"])))));
|
|
177
|
+
|
|
178
|
+
_defineProperty(MenuItem, "mug", new MenuItem((0, _templateString.$item)(_templateObject20 || (_templateObject20 = _taggedTemplateLiteral(["Frosty's frosty mug"])))));
|
|
179
|
+
|
|
180
|
+
var DietPlanner = /*#__PURE__*/function () {
|
|
181
|
+
function DietPlanner(mpa, menu) {
|
|
182
|
+
_classCallCheck(this, DietPlanner);
|
|
183
|
+
|
|
184
|
+
_defineProperty(this, "mpa", void 0);
|
|
185
|
+
|
|
186
|
+
_defineProperty(this, "menu", void 0);
|
|
187
|
+
|
|
188
|
+
_defineProperty(this, "checkFork", void 0);
|
|
189
|
+
|
|
190
|
+
_defineProperty(this, "checkMug", void 0);
|
|
191
|
+
|
|
192
|
+
_defineProperty(this, "useSeasoning", void 0);
|
|
193
|
+
|
|
194
|
+
_defineProperty(this, "useMayoflex", void 0);
|
|
195
|
+
|
|
196
|
+
_defineProperty(this, "spleenValue", 0);
|
|
197
|
+
|
|
198
|
+
this.mpa = mpa;
|
|
199
|
+
this.checkFork = menu.some(item => item.item === MenuItem.fork.item);
|
|
200
|
+
this.checkMug = menu.some(item => item.item === MenuItem.mug.item);
|
|
201
|
+
this.useSeasoning = menu.some(item => item.item === (0, _templateString.$item)(_templateObject || (_templateObject = _taggedTemplateLiteral(["Special Seasoning"]))));
|
|
202
|
+
this.useMayoflex = (0, _kolmafia.getWorkshed)() === (0, _templateString.$item)(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["portable Mayo Clinic"]))) && menu.some(item => item.item === (0, _templateString.$item)(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["Mayoflex"]))));
|
|
203
|
+
this.menu = menu.filter(item => ["food", "booze", "spleen item"].includes((0, _kolmafia.itemType)(item.item)));
|
|
204
|
+
|
|
205
|
+
if (menu.length > 100) {
|
|
206
|
+
(0, _kolmafia.mallPrices)("food");
|
|
207
|
+
(0, _kolmafia.mallPrices)("booze");
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
var spleenItems = menu.filter(item => (0, _kolmafia.itemType)(item.item) === "spleen item");
|
|
211
|
+
spleenItems.sort((x, y) => -(this.consumptionValue(x) / x.item.spleen - this.consumptionValue(y) / y.item.spleen));
|
|
212
|
+
|
|
213
|
+
if (spleenItems.length > 0) {
|
|
214
|
+
this.spleenValue = this.consumptionValue(spleenItems[0]) / spleenItems[0].item.spleen;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
_createClass(DietPlanner, [{
|
|
219
|
+
key: "consumptionValue",
|
|
220
|
+
value: function consumptionValue(menuItem) {
|
|
221
|
+
return this.consumptionHelpersAndValue(menuItem)[1];
|
|
222
|
+
}
|
|
223
|
+
}, {
|
|
224
|
+
key: "consumptionHelpersAndValue",
|
|
225
|
+
value: function consumptionHelpersAndValue(menuItem) {
|
|
226
|
+
var _menuItem$additionalV, _menuItem$additionalV2;
|
|
227
|
+
|
|
228
|
+
var additionalAdventures = 0;
|
|
229
|
+
var helpers = [];
|
|
230
|
+
|
|
231
|
+
if (this.useMayoflex && (0, _kolmafia.itemType)(menuItem.item) === "food" && this.mpa > (0, _kolmafia.npcPrice)((0, _templateString.$item)(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["Mayoflex"]))))) {
|
|
232
|
+
helpers.push(MenuItem.mayoflex);
|
|
233
|
+
additionalAdventures++;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (this.useSeasoning && (0, _kolmafia.itemType)(menuItem.item) === "food" && this.mpa > (0, _kolmafia.mallPrice)((0, _templateString.$item)(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["Special Seasoning"]))))) {
|
|
237
|
+
helpers.push(MenuItem.seasoning);
|
|
238
|
+
additionalAdventures++;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
var forkMug = (0, _kolmafia.itemType)(menuItem.item) === "food" ? MenuItem.fork : (0, _kolmafia.itemType)(menuItem.item) === "booze" ? MenuItem.mug : null;
|
|
242
|
+
var forkMugPrice = forkMug ? forkMug.price() : Infinity;
|
|
243
|
+
var valueRaw = (expectedAdventures(menuItem.item, false) + additionalAdventures) * this.mpa - (0, _kolmafia.mallPrice)(menuItem.item) + ((_menuItem$additionalV = menuItem.additionalValue) !== null && _menuItem$additionalV !== void 0 ? _menuItem$additionalV : 0);
|
|
244
|
+
var valueForkMug = (expectedAdventures(menuItem.item, true) + additionalAdventures) * this.mpa - (0, _kolmafia.mallPrice)(menuItem.item) - forkMugPrice + ((_menuItem$additionalV2 = menuItem.additionalValue) !== null && _menuItem$additionalV2 !== void 0 ? _menuItem$additionalV2 : 0);
|
|
245
|
+
var valueSpleen = (0, _templateString.$items)(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["jar of fermented pickle juice, extra-greasy slider"]))).includes(menuItem.item) ? 5 * this.spleenValue : 0;
|
|
246
|
+
return forkMug && valueForkMug > valueRaw ? [[].concat(helpers, [forkMug, menuItem]), valueForkMug + valueSpleen] : [[].concat(helpers, [menuItem]), valueRaw + valueSpleen];
|
|
247
|
+
}
|
|
248
|
+
}, {
|
|
249
|
+
key: "planOrgan",
|
|
250
|
+
value: function planOrgan(organ, capacity) {
|
|
251
|
+
// print(`Plan ${organ} < ${capacity}`);
|
|
252
|
+
var submenu = this.menu.filter(item => (0, _kolmafia.itemType)(item.item) === organ);
|
|
253
|
+
var knapsackValues = submenu.map(menuItem => [].concat(_toConsumableArray(this.consumptionHelpersAndValue(menuItem)), [menuItem.size, menuItem.maximum]));
|
|
254
|
+
|
|
255
|
+
var _knapsack = (0, _knapsack3.knapsack)(knapsackValues, capacity),
|
|
256
|
+
_knapsack2 = _slicedToArray(_knapsack, 2),
|
|
257
|
+
value = _knapsack2[0],
|
|
258
|
+
menuItemList = _knapsack2[1];
|
|
259
|
+
|
|
260
|
+
var itemList = menuItemList.map(menuItems => menuItems.map(menuItem => menuItem.item)); // print(
|
|
261
|
+
// `Items: ${itemList.length} ${([] as Item[])
|
|
262
|
+
// .concat(...itemList)
|
|
263
|
+
// .map((item) => item.name)
|
|
264
|
+
// .join(", ")}`
|
|
265
|
+
// );
|
|
266
|
+
|
|
267
|
+
return [value, aggregate(itemList, (x, y) => x.every((elem, index) => elem === y[index]))];
|
|
268
|
+
}
|
|
269
|
+
}, {
|
|
270
|
+
key: "planOrgans",
|
|
271
|
+
value: function planOrgans(organCapacities) {
|
|
272
|
+
var _ref5;
|
|
273
|
+
|
|
274
|
+
var valuePlans = organCapacities.map(_ref => {
|
|
275
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
276
|
+
organ = _ref2[0],
|
|
277
|
+
capacity = _ref2[1];
|
|
278
|
+
|
|
279
|
+
return this.planOrgan(organ, capacity);
|
|
280
|
+
});
|
|
281
|
+
return [(0, _utils.sum)(valuePlans, _ref3 => {
|
|
282
|
+
var _ref4 = _slicedToArray(_ref3, 1),
|
|
283
|
+
value = _ref4[0];
|
|
284
|
+
|
|
285
|
+
return value;
|
|
286
|
+
}), (_ref5 = []).concat.apply(_ref5, _toConsumableArray(valuePlans.map(_ref6 => {
|
|
287
|
+
var _ref7 = _slicedToArray(_ref6, 2),
|
|
288
|
+
plan = _ref7[1];
|
|
289
|
+
|
|
290
|
+
return plan;
|
|
291
|
+
})))];
|
|
292
|
+
}
|
|
293
|
+
}, {
|
|
294
|
+
key: "planOrgansWithTrials",
|
|
295
|
+
value: function planOrgansWithTrials(organCapacities, trialItems) {
|
|
296
|
+
if (trialItems.length === 0) {
|
|
297
|
+
return this.planOrgans(organCapacities);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
var organCapacitiesWithMap = new Map(organCapacities);
|
|
301
|
+
|
|
302
|
+
var _trialItems$ = _slicedToArray(trialItems[0], 2),
|
|
303
|
+
trialItem = _trialItems$[0],
|
|
304
|
+
organSizes = _trialItems$[1]; // print(`TRYING ${trialItem.item.name}`);
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
var _iterator2 = _createForOfIteratorHelper(organSizes),
|
|
308
|
+
_step2;
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
312
|
+
var _step2$value = _slicedToArray(_step2.value, 2),
|
|
313
|
+
organ = _step2$value[0],
|
|
314
|
+
size = _step2$value[1];
|
|
315
|
+
|
|
316
|
+
var current = organCapacitiesWithMap.get(organ);
|
|
317
|
+
|
|
318
|
+
if (current !== undefined) {
|
|
319
|
+
organCapacitiesWithMap.set(organ, current - size);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
} catch (err) {
|
|
323
|
+
_iterator2.e(err);
|
|
324
|
+
} finally {
|
|
325
|
+
_iterator2.f();
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
var organCapacitiesWith = _toConsumableArray(organCapacitiesWithMap);
|
|
329
|
+
|
|
330
|
+
var _this$planOrgansWithT = this.planOrgansWithTrials(organCapacities, trialItems.slice(1)),
|
|
331
|
+
_this$planOrgansWithT2 = _slicedToArray(_this$planOrgansWithT, 2),
|
|
332
|
+
valueWithout = _this$planOrgansWithT2[0],
|
|
333
|
+
planWithout = _this$planOrgansWithT2[1];
|
|
334
|
+
|
|
335
|
+
var _this$planOrgansWithT3 = this.planOrgansWithTrials(organCapacitiesWith, trialItems.slice(1)),
|
|
336
|
+
_this$planOrgansWithT4 = _slicedToArray(_this$planOrgansWithT3, 2),
|
|
337
|
+
valueWith = _this$planOrgansWithT4[0],
|
|
338
|
+
planWith = _this$planOrgansWithT4[1];
|
|
339
|
+
|
|
340
|
+
var _this$consumptionHelp = this.consumptionHelpersAndValue(trialItem),
|
|
341
|
+
_this$consumptionHelp2 = _slicedToArray(_this$consumptionHelp, 2),
|
|
342
|
+
helpers = _this$consumptionHelp2[0],
|
|
343
|
+
value = _this$consumptionHelp2[1];
|
|
344
|
+
|
|
345
|
+
(0, _kolmafia.print)("".concat(new Array(5 - trialItems.length).join(">"), " ").concat(valueWithout > valueWith + value ? "WITHOUT" : "WITH", " ").concat(trialItem.item, " ").concat(value.toFixed(0), ": ").concat(valueWithout.toFixed(0), " vs. ").concat((valueWith + value).toFixed(0)));
|
|
346
|
+
return valueWithout > valueWith + value ? [valueWithout, planWithout] : [valueWith, [].concat(_toConsumableArray(planWith), [[helpers.map(menuItem => menuItem.item), 1]])];
|
|
347
|
+
}
|
|
348
|
+
}]);
|
|
349
|
+
|
|
350
|
+
return DietPlanner;
|
|
351
|
+
}(); // [item, fullness, inebriety]
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
var interactingItems = [[(0, _templateString.$item)(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["spice melange"]))), [["food", -3], ["booze", -3]]], [(0, _templateString.$item)(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["Ultra Mega Sour Ball"]))), [["food", -3], ["booze", -3]]], [(0, _templateString.$item)(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["The Plumber's mushroom stew"]))), [["food", 3], ["booze", -1]]], [(0, _templateString.$item)(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["The Mad Liquor"]))), [["food", -1], ["booze", 3]]], [(0, _templateString.$item)(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["Doc Clock's thyme cocktail"]))), [["food", -2], ["booze", 4]]], [(0, _templateString.$item)(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["Mr. Burnsger"]))), [["food", 4], ["booze", -2]]]];
|
|
355
|
+
|
|
356
|
+
function planDiet(mpa, menu) {
|
|
357
|
+
var _resolvedOrganCapacit;
|
|
358
|
+
|
|
359
|
+
var organCapacities = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [["food", null], ["booze", null], ["spleen item", null]];
|
|
360
|
+
var dietPlanner = new DietPlanner(mpa, menu);
|
|
361
|
+
(0, _kolmafia.print)("MENU:");
|
|
362
|
+
|
|
363
|
+
var _iterator3 = _createForOfIteratorHelper(menu),
|
|
364
|
+
_step3;
|
|
365
|
+
|
|
366
|
+
try {
|
|
367
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
368
|
+
var menuItem = _step3.value;
|
|
369
|
+
|
|
370
|
+
var _dietPlanner$consumpt = dietPlanner.consumptionHelpersAndValue(menuItem),
|
|
371
|
+
_dietPlanner$consumpt2 = _slicedToArray(_dietPlanner$consumpt, 2),
|
|
372
|
+
helpers = _dietPlanner$consumpt2[0],
|
|
373
|
+
value = _dietPlanner$consumpt2[1];
|
|
374
|
+
|
|
375
|
+
(0, _kolmafia.print)("".concat(menuItem.item.name, ": ").concat(helpers.join(", "), " ").concat(value));
|
|
376
|
+
}
|
|
377
|
+
} catch (err) {
|
|
378
|
+
_iterator3.e(err);
|
|
379
|
+
} finally {
|
|
380
|
+
_iterator3.f();
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
var resolvedOrganCapacities = organCapacities.map(_ref8 => {
|
|
384
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
385
|
+
organ = _ref9[0],
|
|
386
|
+
size = _ref9[1];
|
|
387
|
+
|
|
388
|
+
return [organ, size !== null && size !== void 0 ? size : organ === "food" ? (0, _kolmafia.fullnessLimit)() - (0, _kolmafia.myFullness)() + ((0, _lib.have)((0, _templateString.$item)(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["distention pill"])))) ? 1 : 0) : organ === "booze" ? (0, _kolmafia.inebrietyLimit)() + ((0, _lib.have)((0, _templateString.$item)(_templateObject14 || (_templateObject14 = _taggedTemplateLiteral(["synthetic dog hair pill"])))) ? 1 : 0) : organ === "spleen item" ? (0, _kolmafia.spleenLimit)() - (0, _kolmafia.mySpleenUse)() : 0];
|
|
389
|
+
});
|
|
390
|
+
var allItems = new Map(menu.map(menuItem => [menuItem.item, menuItem]));
|
|
391
|
+
var includedInteractingItems = interactingItems.map(_ref10 => {
|
|
392
|
+
var _ref11 = _slicedToArray(_ref10, 2),
|
|
393
|
+
item = _ref11[0],
|
|
394
|
+
sizes = _ref11[1];
|
|
395
|
+
|
|
396
|
+
return [allItems.get(item), sizes];
|
|
397
|
+
}).filter(_ref12 => {
|
|
398
|
+
var _ref13 = _slicedToArray(_ref12, 1),
|
|
399
|
+
menuItem = _ref13[0];
|
|
400
|
+
|
|
401
|
+
return menuItem;
|
|
402
|
+
}); // print(
|
|
403
|
+
// `included interacting: ${includedInteractingItems
|
|
404
|
+
// .map(([menuItem]) => menuItem.item.name)
|
|
405
|
+
// .join(", ")}`
|
|
406
|
+
// );
|
|
407
|
+
|
|
408
|
+
var _dietPlanner$planOrga = dietPlanner.planOrgansWithTrials(resolvedOrganCapacities.filter(_ref14 => {
|
|
409
|
+
var _ref15 = _slicedToArray(_ref14, 1),
|
|
410
|
+
organ = _ref15[0];
|
|
411
|
+
|
|
412
|
+
return ["food", "booze"].includes(organ);
|
|
413
|
+
}), includedInteractingItems),
|
|
414
|
+
_dietPlanner$planOrga2 = _slicedToArray(_dietPlanner$planOrga, 2),
|
|
415
|
+
planFoodBooze = _dietPlanner$planOrga2[1];
|
|
416
|
+
|
|
417
|
+
var additionalSpleen = (0, _utils.sum)(planFoodBooze, _ref16 => {
|
|
418
|
+
var _ref17 = _slicedToArray(_ref16, 2),
|
|
419
|
+
items = _ref17[0],
|
|
420
|
+
number = _ref17[1];
|
|
421
|
+
|
|
422
|
+
return items.includes((0, _templateString.$item)(_templateObject15 || (_templateObject15 = _taggedTemplateLiteral(["jar of fermented pickle juice"])))) || items.includes((0, _templateString.$item)(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["extra-greasy slider"])))) ? 5 * number : 0;
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
var _ref18 = (_resolvedOrganCapacit = resolvedOrganCapacities.find(_ref20 => {
|
|
426
|
+
var _ref21 = _slicedToArray(_ref20, 1),
|
|
427
|
+
organ = _ref21[0];
|
|
428
|
+
|
|
429
|
+
return organ === "spleen item";
|
|
430
|
+
})) !== null && _resolvedOrganCapacit !== void 0 ? _resolvedOrganCapacit : ["spleen item", 0],
|
|
431
|
+
_ref19 = _slicedToArray(_ref18, 2),
|
|
432
|
+
availableSpleen = _ref19[1];
|
|
433
|
+
|
|
434
|
+
var _dietPlanner$planOrga3 = dietPlanner.planOrgan("spleen item", availableSpleen + additionalSpleen),
|
|
435
|
+
_dietPlanner$planOrga4 = _slicedToArray(_dietPlanner$planOrga3, 2),
|
|
436
|
+
planSpleen = _dietPlanner$planOrga4[1];
|
|
437
|
+
|
|
438
|
+
return [].concat(_toConsumableArray(planFoodBooze), _toConsumableArray(planSpleen));
|
|
439
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Solve the knapsack problem.
|
|
3
|
+
* @param values Array of {[item, value, weight, maximum]} tuples for knapsack parameter.
|
|
4
|
+
* @param capacity Capacity of knapsack.
|
|
5
|
+
* @returns Tuple {[totalValue, items]} of selected items and total value of those items.
|
|
6
|
+
*/
|
|
7
|
+
export declare function knapsack<T>(values: [T, number, number, number?][], capacity: number): [number, T[]];
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/es.symbol.js");
|
|
4
|
+
|
|
5
|
+
require("core-js/modules/es.symbol.description.js");
|
|
6
|
+
|
|
7
|
+
require("core-js/modules/es.object.to-string.js");
|
|
8
|
+
|
|
9
|
+
require("core-js/modules/es.array.iterator.js");
|
|
10
|
+
|
|
11
|
+
require("core-js/modules/es.array.slice.js");
|
|
12
|
+
|
|
13
|
+
Object.defineProperty(exports, "__esModule", {
|
|
14
|
+
value: true
|
|
15
|
+
});
|
|
16
|
+
exports.knapsack = knapsack;
|
|
17
|
+
|
|
18
|
+
require("core-js/modules/es.array.sort.js");
|
|
19
|
+
|
|
20
|
+
require("core-js/modules/es.array.concat.js");
|
|
21
|
+
|
|
22
|
+
require("core-js/modules/es.array.map.js");
|
|
23
|
+
|
|
24
|
+
require("core-js/modules/es.array.fill.js");
|
|
25
|
+
|
|
26
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
27
|
+
|
|
28
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
29
|
+
|
|
30
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
31
|
+
|
|
32
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
33
|
+
|
|
34
|
+
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
35
|
+
|
|
36
|
+
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
37
|
+
|
|
38
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
39
|
+
|
|
40
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
41
|
+
|
|
42
|
+
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
43
|
+
|
|
44
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Solve the knapsack problem.
|
|
48
|
+
* @param values Array of {[item, value, weight, maximum]} tuples for knapsack parameter.
|
|
49
|
+
* @param capacity Capacity of knapsack.
|
|
50
|
+
* @returns Tuple {[totalValue, items]} of selected items and total value of those items.
|
|
51
|
+
*/
|
|
52
|
+
function knapsack(values, capacity) {
|
|
53
|
+
var _ref;
|
|
54
|
+
|
|
55
|
+
// Sort values by weight.
|
|
56
|
+
var valuesSorted = _toConsumableArray(values).sort((x, y) => x[2] - y[2]); // Convert the problem into 0/1 knapsack - just include as many copies as possible of each item.
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
var values01 = (_ref = []).concat.apply(_ref, _toConsumableArray(valuesSorted.map(_ref2 => {
|
|
60
|
+
var _ref3 = _slicedToArray(_ref2, 4),
|
|
61
|
+
thing = _ref3[0],
|
|
62
|
+
value = _ref3[1],
|
|
63
|
+
weight = _ref3[2],
|
|
64
|
+
maximum = _ref3[3];
|
|
65
|
+
|
|
66
|
+
var maxQuantity = maximum !== null && maximum !== void 0 ? maximum : Math.floor(capacity / weight);
|
|
67
|
+
return new Array(maxQuantity).fill([thing, value, weight]);
|
|
68
|
+
})));
|
|
69
|
+
|
|
70
|
+
var memoizationTable = new Array(values01.length);
|
|
71
|
+
|
|
72
|
+
for (var i = 0; i < values01.length; i++) {
|
|
73
|
+
memoizationTable[i] = new Array(capacity).fill(null);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return bestSolution(memoizationTable, values01, values01.length - 1, capacity);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Find the best solution to a knapsack subproblem.
|
|
80
|
+
* @param memoizationTable Memoization table for dynamic programming approach.
|
|
81
|
+
* @param values Array of {[item, value, weight, maximum]} tuples for knapsack parameter.
|
|
82
|
+
* @param currentIndex Current index into values array - only add items before this index.
|
|
83
|
+
* @param remainingCapacity Remaining capacity of knapsack.
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
function bestSolution(memoizationTable, values, currentIndex, remainingCapacity) {
|
|
89
|
+
// If we've used all our capacity, this solution is no good.
|
|
90
|
+
if (remainingCapacity < 0) return [-Infinity, []];
|
|
91
|
+
if (remainingCapacity === 0 || currentIndex < 0) return [0, []];
|
|
92
|
+
var memoized = memoizationTable[currentIndex][remainingCapacity - 1];
|
|
93
|
+
if (memoized !== null) return memoized;
|
|
94
|
+
|
|
95
|
+
var _values$currentIndex = _slicedToArray(values[currentIndex], 3),
|
|
96
|
+
item = _values$currentIndex[0],
|
|
97
|
+
value = _values$currentIndex[1],
|
|
98
|
+
weight = _values$currentIndex[2];
|
|
99
|
+
|
|
100
|
+
var _bestSolution = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity - weight),
|
|
101
|
+
_bestSolution2 = _slicedToArray(_bestSolution, 2),
|
|
102
|
+
valueIncludeRest = _bestSolution2[0],
|
|
103
|
+
itemsInclude = _bestSolution2[1];
|
|
104
|
+
|
|
105
|
+
var valueInclude = valueIncludeRest + value;
|
|
106
|
+
|
|
107
|
+
var _bestSolution3 = bestSolution(memoizationTable, values, currentIndex - 1, remainingCapacity),
|
|
108
|
+
_bestSolution4 = _slicedToArray(_bestSolution3, 2),
|
|
109
|
+
valueExclude = _bestSolution4[0],
|
|
110
|
+
itemsExclude = _bestSolution4[1]; // Pick the better of the two options between including/excluding.
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
var result = valueInclude > valueExclude ? [valueInclude, [].concat(_toConsumableArray(itemsInclude), [item])] : [valueExclude, itemsExclude];
|
|
114
|
+
memoizationTable[currentIndex][remainingCapacity - 1] = result;
|
|
115
|
+
return result;
|
|
116
|
+
}
|
package/dist/lib.d.ts
CHANGED
|
@@ -222,6 +222,12 @@ export declare type Player = {
|
|
|
222
222
|
* @returns Object containing id and name of player
|
|
223
223
|
*/
|
|
224
224
|
export declare function getPlayerFromIdOrName(idOrName: number | string): Player;
|
|
225
|
+
/**
|
|
226
|
+
* Return the step as a number for a given quest property.
|
|
227
|
+
*
|
|
228
|
+
* @param questName Name of quest property to check.
|
|
229
|
+
*/
|
|
230
|
+
export declare function questStep(questName: string): number;
|
|
225
231
|
export declare class EnsureError extends Error {
|
|
226
232
|
constructor(cause: Item | Familiar | Effect);
|
|
227
233
|
}
|
|
@@ -243,3 +249,17 @@ export declare const Environment: {
|
|
|
243
249
|
readonly Underwater: "underwater";
|
|
244
250
|
};
|
|
245
251
|
export declare type EnvironmentType = typeof Environment[keyof typeof Environment];
|
|
252
|
+
/**
|
|
253
|
+
* Returns the weight-coefficient of any leprechaunning that this familiar may find itself doing
|
|
254
|
+
* Assumes the familiar is nude and thus fails for hatrack & pantsrack
|
|
255
|
+
* For the Mutant Cactus Bud, returns the efficacy-multiplier instead
|
|
256
|
+
* @param familiar The familiar whose leprechaun multiplier you're interested in
|
|
257
|
+
*/
|
|
258
|
+
export declare function findLeprechaunMultiplier(familiar: Familiar): number;
|
|
259
|
+
/**
|
|
260
|
+
* Returns the weight-coefficient of any baby gravy fairying that this familiar may find itself doing
|
|
261
|
+
* Assumes the familiar is nude and thus fails for hatrack & pantsrack
|
|
262
|
+
* For the Mutant Fire Ant, returns the efficacy-multiplier instead
|
|
263
|
+
* @param familiar The familiar whose fairy multiplier you're interested in
|
|
264
|
+
*/
|
|
265
|
+
export declare function findFairyMultiplier(familiar: Familiar): number;
|