@pkmn/engine 0.1.0-dev.0cabf16e → 0.1.0-dev.0f9e9648
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/LICENSE +1 -1
- package/README.md +47 -4
- package/build/pkg/addon/browser.d.ts +1 -1
- package/build/pkg/addon/browser.js +6 -2
- package/build/pkg/addon/browser.js.map +1 -1
- package/build/pkg/addon/node.js +22 -8
- package/build/pkg/addon/node.js.map +1 -1
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +53 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +24 -4
- package/build/pkg/addon.js +8 -17
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data/layout.json +15 -2
- package/build/pkg/data/protocol.json +23 -9
- package/build/pkg/gen1.d.ts +15 -18
- package/build/pkg/gen1.js +28 -19
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +37 -100
- package/build/pkg/index.js +23 -75
- package/build/pkg/index.js.map +1 -1
- package/build/tools/debug.js +18 -9
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +18 -7
- package/build/tools/display/debug.jsx.map +1 -1
- package/build/tools/display/index.js +35 -15
- package/build/tools/display/index.js.map +1 -1
- package/build/tools/display/ui.jsx +17 -7
- package/build/tools/display/ui.jsx.map +1 -1
- package/build/tools/display/util.js +16 -1
- package/build/tools/display/util.js.map +1 -1
- package/build.zig +196 -84
- package/package.json +29 -127
- package/src/bin/install-pkmn-engine +3 -2
- package/src/lib/bindings/c.zig +255 -0
- package/src/lib/bindings/node.zig +121 -0
- package/src/lib/bindings/wasm.zig +59 -0
- package/src/lib/common/array.zig +1 -1
- package/src/lib/common/optional.zig +1 -1
- package/src/lib/common/options.zig +2 -0
- package/src/lib/common/protocol.zig +4 -8
- package/src/lib/common/rational.zig +222 -147
- package/src/lib/common/rng.zig +1 -3
- package/src/lib/common/util.zig +17 -2
- package/src/lib/gen1/calc.zig +87 -97
- package/src/lib/gen1/chance.zig +34 -18
- package/src/lib/gen1/data/moves.zig +2 -4
- package/src/lib/gen1/data/species.zig +1 -3
- package/src/lib/gen1/data/types.zig +1 -2
- package/src/lib/gen1/data.zig +7 -11
- package/src/lib/gen1/helpers.zig +4 -11
- package/src/lib/gen1/mechanics.zig +66 -50
- package/src/lib/gen2/calc.zig +10 -18
- package/src/lib/gen2/data/items.zig +1 -3
- package/src/lib/gen2/data/moves.zig +2 -4
- package/src/lib/gen2/data/species.zig +1 -3
- package/src/lib/gen2/data/types.zig +1 -2
- package/src/lib/gen2/data.zig +11 -15
- package/src/lib/gen2/generated.zig +18 -23
- package/src/lib/gen2/helpers.zig +5 -12
- package/src/lib/gen2/mechanics.zig +41 -38
- package/src/lib/node.zig +3 -116
- package/src/lib/pkmn.zig +7 -2
- package/src/lib/wasm.zig +13 -9
- package/src/tools/display/dom.ts +5 -8
- package/src/tools/display/ui.css +0 -5
package/src/lib/gen1/calc.zig
CHANGED
|
@@ -1,44 +1,35 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const pkmn = @import("../pkmn.zig");
|
|
1
|
+
const DEBUG = @import("../common/debug.zig").print;
|
|
4
2
|
|
|
3
|
+
const chance = @import("chance.zig");
|
|
5
4
|
const common = @import("../common/data.zig");
|
|
6
|
-
const
|
|
5
|
+
const data = @import("data.zig");
|
|
6
|
+
const helpers = @import("helpers.zig");
|
|
7
7
|
const optional = @import("../common/optional.zig");
|
|
8
|
+
const pkmn = @import("../pkmn.zig");
|
|
8
9
|
const protocol = @import("../common/protocol.zig");
|
|
9
10
|
const rational = @import("../common/rational.zig");
|
|
11
|
+
const std = @import("std");
|
|
10
12
|
const util = @import("../common/util.zig");
|
|
11
13
|
|
|
12
|
-
const chance = @import("chance.zig");
|
|
13
|
-
const data = @import("data.zig");
|
|
14
|
-
const helpers = @import("helpers.zig");
|
|
15
|
-
|
|
16
|
-
const assert = std.debug.assert;
|
|
17
|
-
|
|
18
|
-
const expect = std.testing.expect;
|
|
19
|
-
const expectEqual = std.testing.expectEqual;
|
|
20
|
-
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
21
|
-
|
|
22
|
-
const enabled = pkmn.options.calc;
|
|
23
|
-
|
|
24
|
-
const Player = common.Player;
|
|
25
|
-
const Result = common.Result;
|
|
26
|
-
const Choice = common.Choice;
|
|
27
|
-
|
|
28
|
-
const Optional = optional.Optional;
|
|
29
|
-
|
|
30
|
-
const Rational = rational.Rational;
|
|
31
|
-
|
|
32
|
-
const PointerType = util.PointerType;
|
|
33
|
-
const isPointerTo = util.isPointerTo;
|
|
34
|
-
|
|
35
|
-
const Actions = chance.Actions;
|
|
36
14
|
const Action = chance.Action;
|
|
15
|
+
const Actions = chance.Actions;
|
|
16
|
+
const assert = std.debug.assert;
|
|
37
17
|
const Chance = chance.Chance;
|
|
18
|
+
const Choice = common.Choice;
|
|
38
19
|
const Confusion = chance.Confusion;
|
|
39
20
|
const Duration = chance.Duration;
|
|
40
21
|
const Durations = chance.Durations;
|
|
22
|
+
const enabled = pkmn.options.calc;
|
|
23
|
+
const expect = std.testing.expect;
|
|
24
|
+
const expectEqual = std.testing.expectEqual;
|
|
25
|
+
const expectEqualSlices = std.testing.expectEqualSlices;
|
|
26
|
+
const isPointerTo = util.isPointerTo;
|
|
41
27
|
const Observation = chance.Observation;
|
|
28
|
+
const Optional = optional.Optional;
|
|
29
|
+
const Player = common.Player;
|
|
30
|
+
const PointerType = util.PointerType;
|
|
31
|
+
const Rational = rational.Rational;
|
|
32
|
+
const Result = common.Result;
|
|
42
33
|
const Sleeps = chance.Sleeps;
|
|
43
34
|
|
|
44
35
|
const tty = true; // DEBUG
|
|
@@ -108,7 +99,7 @@ pub const Calc = struct {
|
|
|
108
99
|
self: Calc,
|
|
109
100
|
player: Player,
|
|
110
101
|
comptime field: Action.Field,
|
|
111
|
-
) ?
|
|
102
|
+
) ?util.FieldType(Action, field) {
|
|
112
103
|
if (!enabled) return null;
|
|
113
104
|
|
|
114
105
|
const val = @field(self.overrides.get(player), @tagName(field));
|
|
@@ -155,7 +146,7 @@ const Null = struct {
|
|
|
155
146
|
self: Null,
|
|
156
147
|
player: Player,
|
|
157
148
|
comptime field: Action.Field,
|
|
158
|
-
) ?
|
|
149
|
+
) ?util.FieldType(Action, field) {
|
|
159
150
|
_ = .{ self, player };
|
|
160
151
|
return null;
|
|
161
152
|
}
|
|
@@ -191,7 +182,7 @@ pub const Options = struct {
|
|
|
191
182
|
metronome: bool = false,
|
|
192
183
|
};
|
|
193
184
|
|
|
194
|
-
pub const MAX_FRONTIER =
|
|
185
|
+
pub const MAX_FRONTIER = 81;
|
|
195
186
|
|
|
196
187
|
pub fn transitions(
|
|
197
188
|
battle: anytype,
|
|
@@ -210,11 +201,11 @@ pub fn transitions(
|
|
|
210
201
|
var frontier = std.ArrayList(Actions).init(allocator);
|
|
211
202
|
defer frontier.deinit();
|
|
212
203
|
|
|
213
|
-
const
|
|
204
|
+
const d = options.durations;
|
|
214
205
|
|
|
215
206
|
var opts = pkmn.battle.options(
|
|
216
207
|
protocol.NULL,
|
|
217
|
-
Chance(Rational(u128)){ .probability = .{}, .durations =
|
|
208
|
+
Chance(Rational(u128)){ .probability = .{}, .durations = d },
|
|
218
209
|
Calc{},
|
|
219
210
|
);
|
|
220
211
|
|
|
@@ -225,7 +216,7 @@ pub fn transitions(
|
|
|
225
216
|
const p1 = b.side(.P1);
|
|
226
217
|
const p2 = b.side(.P2);
|
|
227
218
|
|
|
228
|
-
var p: Rational(
|
|
219
|
+
var p: Rational(u256) = .{ .p = 0, .q = 1 };
|
|
229
220
|
try frontier.append(opts.chance.actions);
|
|
230
221
|
|
|
231
222
|
// zig fmt: off
|
|
@@ -240,6 +231,8 @@ pub fn transitions(
|
|
|
240
231
|
const f = frontier.items[i];
|
|
241
232
|
const saved = stats.saved;
|
|
242
233
|
|
|
234
|
+
var r: Rational(u256) = .{ .p = 0, .q = 1 };
|
|
235
|
+
|
|
243
236
|
try debug(writer, f, .{
|
|
244
237
|
.shape = true,
|
|
245
238
|
.color = i,
|
|
@@ -254,20 +247,20 @@ pub fn transitions(
|
|
|
254
247
|
};
|
|
255
248
|
|
|
256
249
|
for (Rolls.speedTie(f.p1)) |tie| { a.p1.speed_tie = tie; a.p2.speed_tie = tie;
|
|
257
|
-
for (Rolls.sleep(f.p1,
|
|
258
|
-
for (Rolls.sleep(f.p2,
|
|
259
|
-
for (Rolls.disable(f.p1,
|
|
260
|
-
for (Rolls.disable(f.p2,
|
|
261
|
-
for (Rolls.attacking(f.p1,
|
|
262
|
-
for (Rolls.attacking(f.p2,
|
|
263
|
-
for (Rolls.confusion(f.p1,
|
|
264
|
-
for (Rolls.confusion(f.p2,
|
|
250
|
+
for (Rolls.sleep(f.p1, d.p1)) |p1_slp| { a.p1.sleep = p1_slp;
|
|
251
|
+
for (Rolls.sleep(f.p2, d.p2)) |p2_slp| { a.p2.sleep = p2_slp;
|
|
252
|
+
for (Rolls.disable(f.p1, d.p1, p1_slp)) |p1_dis| { a.p1.disable = p1_dis;
|
|
253
|
+
for (Rolls.disable(f.p2, d.p2, p2_slp)) |p2_dis| { a.p2.disable = p2_dis;
|
|
254
|
+
for (Rolls.attacking(f.p1, d.p1, p1_slp)) |p1_atk| { a.p1.attacking = p1_atk;
|
|
255
|
+
for (Rolls.attacking(f.p2, d.p2, p2_slp)) |p2_atk| { a.p2.attacking = p2_atk;
|
|
256
|
+
for (Rolls.confusion(f.p1, d.p1, tie, p1_atk, p1_slp)) |p1_cfz| { a.p1.confusion = p1_cfz;
|
|
257
|
+
for (Rolls.confusion(f.p2, d.p2, tie, p2_atk, p2_slp)) |p2_cfz| { a.p2.confusion = p2_cfz;
|
|
265
258
|
for (Rolls.confused(f.p1, p1_cfz)) |p1_cfzd| { a.p1.confused = p1_cfzd;
|
|
266
259
|
for (Rolls.confused(f.p2, p2_cfz)) |p2_cfzd| { a.p2.confused = p2_cfzd;
|
|
267
260
|
for (Rolls.paralyzed(f.p1, p1_cfzd)) |p1_par| { a.p1.paralyzed = p1_par;
|
|
268
261
|
for (Rolls.paralyzed(f.p2, p2_cfzd)) |p2_par| { a.p2.paralyzed = p2_par;
|
|
269
|
-
for (Rolls.binding(f.p1,
|
|
270
|
-
for (Rolls.binding(f.p2,
|
|
262
|
+
for (Rolls.binding(f.p1, d.p1, p1_par)) |p1_bind| { a.p1.binding = p1_bind;
|
|
263
|
+
for (Rolls.binding(f.p2, d.p2, p2_par)) |p2_bind| { a.p2.binding = p2_bind;
|
|
271
264
|
for (Rolls.hit(f.p1, p1_par)) |p1_hit| { a.p1.hit = p1_hit;
|
|
272
265
|
for (Rolls.hit(f.p2, p2_par)) |p2_hit| { a.p2.hit = p2_hit;
|
|
273
266
|
for (Rolls.psywave(f.p1, p1, p1_hit)) |p1_psywave| { a.p1.psywave = p1_psywave;
|
|
@@ -295,7 +288,7 @@ pub fn transitions(
|
|
|
295
288
|
|
|
296
289
|
opts.calc.overrides = a;
|
|
297
290
|
opts.calc.summaries = .{};
|
|
298
|
-
opts.chance = .{ .probability = .{}, .durations =
|
|
291
|
+
opts.chance = .{ .probability = .{}, .durations = d };
|
|
299
292
|
const q = &opts.chance.probability;
|
|
300
293
|
|
|
301
294
|
b = battle;
|
|
@@ -307,12 +300,12 @@ pub fn transitions(
|
|
|
307
300
|
const p1_max: u9 = if (p2_dmg.min != p2_min)
|
|
308
301
|
p1_dmg.min
|
|
309
302
|
else
|
|
310
|
-
|
|
303
|
+
Rolls.coalesce(.P1, @as(u8, @intCast(p1_dmg.min)), summaries, cap);
|
|
311
304
|
const p2_max: u9 =
|
|
312
|
-
|
|
305
|
+
Rolls.coalesce(.P2, @as(u8, @intCast(p2_dmg.min)), summaries, cap);
|
|
313
306
|
|
|
314
307
|
if (opts.chance.actions.matches(f)) {
|
|
315
|
-
if (!
|
|
308
|
+
if (!opts.chance.actions.relax().eql(a)) {
|
|
316
309
|
if (!summary) {
|
|
317
310
|
try debug(writer, opts.chance.actions, .{
|
|
318
311
|
.p1_max = p1_max,
|
|
@@ -346,10 +339,15 @@ pub fn transitions(
|
|
|
346
339
|
}
|
|
347
340
|
}
|
|
348
341
|
}
|
|
349
|
-
|
|
350
342
|
if (p1_max != p1_min) try q.update(p1_max - p1_min + 1, 1);
|
|
351
343
|
if (p2_max != p2_dmg.min) try q.update(p2_max - p2_dmg.min + 1, 1);
|
|
344
|
+
|
|
345
|
+
q.reduce();
|
|
352
346
|
try p.add(q);
|
|
347
|
+
p.reduce();
|
|
348
|
+
try r.add(q);
|
|
349
|
+
r.reduce();
|
|
350
|
+
|
|
353
351
|
stats.saved += 1;
|
|
354
352
|
|
|
355
353
|
if (p.q < p.p) {
|
|
@@ -357,7 +355,7 @@ pub fn transitions(
|
|
|
357
355
|
return error.TestUnexpectedResult;
|
|
358
356
|
}
|
|
359
357
|
} else {
|
|
360
|
-
if (!
|
|
358
|
+
if (!opts.chance.actions.matchesAny(frontier.items, i)) {
|
|
361
359
|
try frontier.append(opts.chance.actions);
|
|
362
360
|
|
|
363
361
|
try debug(writer, opts.chance.actions, .{
|
|
@@ -390,14 +388,15 @@ pub fn transitions(
|
|
|
390
388
|
}}}}}}}}}}}}}}}}}}}}}}}}}}}}
|
|
391
389
|
|
|
392
390
|
assert(stats.saved > saved);
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
391
|
+
// TODO: ziglang/zig#22667
|
|
392
|
+
// const old = @hasDecl(std.fmt, "formatFloatDecimal");
|
|
393
|
+
// if (!old and @TypeOf(writer) != @TypeOf(std.io.null_writer)) {
|
|
394
|
+
// try writer.print(
|
|
395
|
+
// " {} ({d:.2}%)\n = ──────────\n {} ({d:.2}%)\n\n",
|
|
396
|
+
// .{r, 100 * @as(f128, @floatFromInt(r.p)) / @as(f128, @floatFromInt(r.q)),
|
|
397
|
+
// p, 100 * @as(f128, @floatFromInt(p.p)) / @as(f128, @floatFromInt(p.q))},
|
|
398
|
+
// );
|
|
399
|
+
// }
|
|
401
400
|
|
|
402
401
|
}
|
|
403
402
|
|
|
@@ -527,23 +526,6 @@ fn unfix(actual: anytype) data.Battle(data.PRNG) {
|
|
|
527
526
|
};
|
|
528
527
|
}
|
|
529
528
|
|
|
530
|
-
fn map(actions: Actions) Actions {
|
|
531
|
-
if (!pkmn.options.overwrite) return actions;
|
|
532
|
-
var a = actions;
|
|
533
|
-
if (a.p1.confusion == .overwritten) a.p1.confusion = .continuing;
|
|
534
|
-
if (a.p2.confusion == .overwritten) a.p2.confusion = .continuing;
|
|
535
|
-
return a;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
fn matches(actions: Actions, i: usize, frontier: []Actions) bool {
|
|
539
|
-
for (frontier, 0..) |f, j| {
|
|
540
|
-
// TODO: is skipping this redundant check worth it?
|
|
541
|
-
if (i == j) continue;
|
|
542
|
-
if (f.matches(actions)) return true;
|
|
543
|
-
}
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
529
|
fn err(comptime fmt: []const u8, v: anytype, seed: ?u64) void {
|
|
548
530
|
const w = std.io.getStdErr().writer();
|
|
549
531
|
w.print(fmt, v) catch return;
|
|
@@ -667,49 +649,57 @@ pub const Rolls = struct {
|
|
|
667
649
|
};
|
|
668
650
|
}
|
|
669
651
|
|
|
652
|
+
/// FIXME
|
|
653
|
+
pub fn attacking(
|
|
654
|
+
action: Action,
|
|
655
|
+
duration: Duration,
|
|
656
|
+
parent: Optional(Observation),
|
|
657
|
+
) []const Optional(Observation) {
|
|
658
|
+
return switch (action.attacking) {
|
|
659
|
+
.None => &OBS_NONE,
|
|
660
|
+
.started => &OBS_STARTED,
|
|
661
|
+
else => if (duration.attacking >= 3)
|
|
662
|
+
&OBS_ENDED
|
|
663
|
+
else if ((parent == .continuing and parent == .ended) or duration.attacking < 2)
|
|
664
|
+
&OBS_CONTINUING
|
|
665
|
+
else
|
|
666
|
+
&OBS,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
|
|
670
670
|
const CFZ_NONE = [_]Optional(Confusion){.None};
|
|
671
671
|
const CFZ_STARTED = [_]Optional(Confusion){.started};
|
|
672
672
|
const CFZ_OVERWRITTEN = [_]Optional(Confusion){ .started, .overwritten };
|
|
673
673
|
const CFZ_CONTINUING = [_]Optional(Confusion){.continuing};
|
|
674
674
|
const CFZ_ENDED = [_]Optional(Confusion){.ended};
|
|
675
675
|
const CFZ = [_]Optional(Confusion){ .continuing, .ended };
|
|
676
|
+
const CFZ_TIE = [_]Optional(Confusion){ .started, .continuing, .ended };
|
|
676
677
|
|
|
677
678
|
/// FIXME
|
|
678
679
|
pub fn confusion(
|
|
679
680
|
action: Action,
|
|
680
681
|
duration: Duration,
|
|
682
|
+
tie: Optional(Player),
|
|
681
683
|
sibling: Optional(Observation),
|
|
682
684
|
parent: Optional(Observation),
|
|
683
685
|
) []const Optional(Confusion) {
|
|
684
686
|
return switch (action.confusion) {
|
|
685
687
|
.None => &CFZ_NONE,
|
|
686
|
-
.started => if (sibling == .ended)
|
|
688
|
+
.started => if (pkmn.options.overwrite and sibling == .ended and duration.confusion < 5)
|
|
687
689
|
&CFZ_OVERWRITTEN
|
|
688
690
|
else
|
|
689
691
|
&CFZ_STARTED,
|
|
690
692
|
else => if (duration.confusion >= 5)
|
|
691
693
|
&CFZ_ENDED
|
|
692
|
-
else if ((parent
|
|
694
|
+
else if ((parent == .continuing and parent == .ended) or duration.confusion < 2)
|
|
693
695
|
&CFZ_CONTINUING
|
|
696
|
+
else if (tie != .None)
|
|
697
|
+
&CFZ_TIE
|
|
694
698
|
else
|
|
695
699
|
&CFZ,
|
|
696
700
|
};
|
|
697
701
|
}
|
|
698
702
|
|
|
699
|
-
/// FIXME
|
|
700
|
-
pub fn attacking(action: Action, duration: Duration) []const Optional(Observation) {
|
|
701
|
-
return switch (action.attacking) {
|
|
702
|
-
.None => &OBS_NONE,
|
|
703
|
-
.started => &OBS_STARTED,
|
|
704
|
-
else => if (duration.attacking >= 3)
|
|
705
|
-
&OBS_ENDED
|
|
706
|
-
else if (duration.attacking < 2)
|
|
707
|
-
&OBS_CONTINUING
|
|
708
|
-
else
|
|
709
|
-
&OBS,
|
|
710
|
-
};
|
|
711
|
-
}
|
|
712
|
-
|
|
713
703
|
/// Returns a slice with a range of values for binding given the `action`, observed `durations`,
|
|
714
704
|
/// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
|
|
715
705
|
pub fn binding(
|
|
@@ -763,7 +753,7 @@ pub const Rolls = struct {
|
|
|
763
753
|
|
|
764
754
|
/// Returns the max damage roll which will produce the same damage as `roll`
|
|
765
755
|
/// given the base damage in `summaries`.
|
|
766
|
-
pub fn coalesce(player: Player, roll: u8, summaries: *Summaries, cap: bool)
|
|
756
|
+
pub fn coalesce(player: Player, roll: u8, summaries: *Summaries, cap: bool) u8 {
|
|
767
757
|
if (roll == 0) return roll;
|
|
768
758
|
|
|
769
759
|
const dmg = summaries.get(player.foe()).damage;
|
|
@@ -873,12 +863,12 @@ test "Rolls.damage" {
|
|
|
873
863
|
|
|
874
864
|
test "Rolls.coalesce" {
|
|
875
865
|
var summaries = Summaries{ .p1 = .{ .damage = .{ .base = 74, .final = 69, .capped = true } } };
|
|
876
|
-
try expectEqual(@as(u8, 0),
|
|
877
|
-
try expectEqual(@as(u8, 241),
|
|
878
|
-
try expectEqual(@as(u8, 255),
|
|
866
|
+
try expectEqual(@as(u8, 0), Rolls.coalesce(.P2, 0, &summaries, false));
|
|
867
|
+
try expectEqual(@as(u8, 241), Rolls.coalesce(.P2, 238, &summaries, false));
|
|
868
|
+
try expectEqual(@as(u8, 255), Rolls.coalesce(.P2, 238, &summaries, true));
|
|
879
869
|
summaries.p1.damage.final = 74;
|
|
880
|
-
try expectEqual(@as(u8, 217),
|
|
881
|
-
try expectEqual(@as(u8, 255),
|
|
870
|
+
try expectEqual(@as(u8, 217), Rolls.coalesce(.P2, 217, &summaries, false));
|
|
871
|
+
try expectEqual(@as(u8, 255), Rolls.coalesce(.P2, 217, &summaries, true));
|
|
882
872
|
}
|
|
883
873
|
|
|
884
874
|
test "Rolls.hit" {
|
package/src/lib/gen1/chance.zig
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
|
-
|
|
3
|
-
const assert = std.debug.assert;
|
|
4
|
-
const print = std.debug.print;
|
|
5
|
-
|
|
6
|
-
const expect = std.testing.expect;
|
|
7
|
-
const expectEqual = std.testing.expectEqual;
|
|
8
|
-
|
|
9
1
|
const DEBUG = @import("../common/debug.zig").print;
|
|
2
|
+
|
|
3
|
+
const array = @import("../common/array.zig");
|
|
4
|
+
const common = @import("../common/data.zig");
|
|
5
|
+
const data = @import("data.zig");
|
|
6
|
+
const optional = @import("../common/optional.zig");
|
|
10
7
|
const options = @import("../common/options.zig");
|
|
11
8
|
const rational = @import("../common/rational.zig");
|
|
9
|
+
const std = @import("std");
|
|
12
10
|
const util = @import("../common/util.zig");
|
|
13
11
|
|
|
14
|
-
const Array =
|
|
15
|
-
const
|
|
16
|
-
const Optional = @import("../common/optional.zig").Optional;
|
|
17
|
-
|
|
18
|
-
const data = @import("data.zig");
|
|
19
|
-
|
|
12
|
+
const Array = array.Array;
|
|
13
|
+
const assert = std.debug.assert;
|
|
20
14
|
const enabled = options.chance;
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const PointerType = util.PointerType;
|
|
15
|
+
const expect = std.testing.expect;
|
|
16
|
+
const expectEqual = std.testing.expectEqual;
|
|
24
17
|
const isPointerTo = util.isPointerTo;
|
|
25
|
-
|
|
26
18
|
const Move = data.Move;
|
|
27
19
|
const MoveSlot = data.MoveSlot;
|
|
20
|
+
const Optional = optional.Optional;
|
|
21
|
+
const Player = common.Player;
|
|
22
|
+
const PointerType = util.PointerType;
|
|
23
|
+
const print = std.debug.print;
|
|
24
|
+
const showdown = options.showdown;
|
|
28
25
|
|
|
29
26
|
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
30
27
|
const Enum = if (@hasField(std.builtin.Type, "enum")) .@"enum" else .Enum;
|
|
@@ -75,6 +72,25 @@ pub const Actions = extern struct {
|
|
|
75
72
|
return true;
|
|
76
73
|
}
|
|
77
74
|
|
|
75
|
+
/// TODO
|
|
76
|
+
pub fn matchesAny(a: Actions, bs: []Actions, i: usize) bool {
|
|
77
|
+
for (bs, 0..) |b, j| {
|
|
78
|
+
// TODO: is skipping this redundant check worth it?
|
|
79
|
+
if (i == j) continue;
|
|
80
|
+
if (b.matches(a)) return true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/// TODO
|
|
86
|
+
pub fn relax(actions: Actions) Actions {
|
|
87
|
+
if (!options.overwrite) return actions;
|
|
88
|
+
var a = actions;
|
|
89
|
+
if (a.p1.confusion == .overwritten) a.p1.confusion = .continuing;
|
|
90
|
+
if (a.p2.confusion == .overwritten) a.p2.confusion = .continuing;
|
|
91
|
+
return a;
|
|
92
|
+
}
|
|
93
|
+
|
|
78
94
|
pub fn fmt(self: Actions, writer: anytype, shape: bool) !void {
|
|
79
95
|
try writer.writeAll("<P1 = ");
|
|
80
96
|
try self.p1.fmt(writer, shape);
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
|
-
const rng = @import("../../common/rng.zig");
|
|
6
3
|
const gen1 = @import("../../gen1/data.zig");
|
|
4
|
+
const rng = @import("../../common/rng.zig");
|
|
5
|
+
const std = @import("std");
|
|
7
6
|
|
|
8
7
|
const assert = std.debug.assert;
|
|
9
|
-
|
|
10
8
|
const percent = rng.Gen12.percent;
|
|
11
9
|
const Type = gen1.Type;
|
|
12
10
|
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const gen1 = @import("../../gen1/data.zig");
|
|
4
|
+
const std = @import("std");
|
|
6
5
|
|
|
7
6
|
const assert = std.debug.assert;
|
|
8
|
-
|
|
9
7
|
const Stats = gen1.Stats;
|
|
10
8
|
const Types = gen1.Types;
|
|
11
9
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
//! Code generated by `tools/generate` - manual edits will be overwritten.
|
|
2
2
|
|
|
3
|
-
const std = @import("std");
|
|
4
|
-
|
|
5
3
|
const gen1 = @import("../../gen1/data.zig");
|
|
4
|
+
const std = @import("std");
|
|
6
5
|
|
|
7
6
|
const assert = std.debug.assert;
|
|
8
7
|
const Effectiveness = gen1.Effectiveness;
|
package/src/lib/gen1/data.zig
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
1
|
const builtin = @import("builtin");
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
2
|
+
const calc = @import("calc.zig");
|
|
3
|
+
const chance = @import("chance.zig");
|
|
6
4
|
const data = @import("../common/data.zig");
|
|
5
|
+
const mechanics = @import("mechanics.zig");
|
|
6
|
+
const moves = @import("data/moves.zig");
|
|
7
|
+
const pkmn = @import("../pkmn.zig");
|
|
7
8
|
const protocol = @import("../common/protocol.zig");
|
|
8
9
|
const rng = @import("../common/rng.zig");
|
|
9
|
-
const util = @import("../common/util.zig");
|
|
10
|
-
|
|
11
|
-
const moves = @import("data/moves.zig");
|
|
12
10
|
const species = @import("data/species.zig");
|
|
11
|
+
const std = @import("std");
|
|
13
12
|
const types = @import("data/types.zig");
|
|
14
|
-
|
|
15
|
-
const calc = @import("calc.zig");
|
|
16
|
-
const chance = @import("chance.zig");
|
|
17
|
-
const mechanics = @import("mechanics.zig");
|
|
13
|
+
const util = @import("../common/util.zig");
|
|
18
14
|
|
|
19
15
|
const assert = std.debug.assert;
|
|
20
16
|
const expectEqual = std.testing.expectEqual;
|
package/src/lib/gen1/helpers.zig
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
const std = @import("std");
|
|
2
1
|
const builtin = @import("builtin");
|
|
3
|
-
|
|
4
2
|
const common = @import("../common/data.zig");
|
|
3
|
+
const data = @import("data.zig");
|
|
5
4
|
const options = @import("../common/options.zig");
|
|
6
5
|
const protocol = @import("../common/protocol.zig");
|
|
7
6
|
const rng = @import("../common/rng.zig");
|
|
7
|
+
const std = @import("std");
|
|
8
8
|
const util = @import("../common/util.zig");
|
|
9
9
|
|
|
10
|
-
const data = @import("data.zig");
|
|
11
|
-
|
|
12
10
|
const assert = std.debug.assert;
|
|
13
|
-
|
|
14
11
|
const Choice = common.Choice;
|
|
15
|
-
|
|
16
|
-
const showdown = options.showdown;
|
|
17
|
-
|
|
18
|
-
const PSRNG = rng.PSRNG;
|
|
19
|
-
|
|
20
12
|
const DVs = data.DVs;
|
|
21
13
|
const Move = data.Move;
|
|
22
14
|
const MoveSlot = data.MoveSlot;
|
|
15
|
+
const PSRNG = rng.PSRNG;
|
|
16
|
+
const showdown = options.showdown;
|
|
23
17
|
const Species = data.Species;
|
|
24
18
|
const Stats = data.Stats;
|
|
25
19
|
|
|
@@ -267,7 +261,6 @@ fn durations(m: Move) bool {
|
|
|
267
261
|
// Any moves that have effects that result in duration tracking with -Dchance
|
|
268
262
|
return switch (Move.get(m).effect) {
|
|
269
263
|
.Haze,
|
|
270
|
-
.Thrashing,
|
|
271
264
|
.Metronome,
|
|
272
265
|
=> true,
|
|
273
266
|
else => false,
|