@pkmn/engine 0.1.0-dev.53787794 → 0.1.0-dev.54a1aa85
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 +5 -4
- package/build/pkg/addon/browser.d.ts +1 -1
- package/build/pkg/addon/browser.js +2 -1
- package/build/pkg/addon/browser.js.map +1 -1
- package/build/pkg/addon/node.js +2 -1
- package/build/pkg/addon/node.js.map +1 -1
- package/build/pkg/addon/wasm.d.ts +2 -0
- package/build/pkg/addon/wasm.js +44 -0
- package/build/pkg/addon/wasm.js.map +1 -0
- package/build/pkg/addon.d.ts +23 -3
- 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 +13 -17
- package/build/pkg/gen1.js +6 -10
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/index.d.ts +35 -100
- package/build/pkg/index.js +6 -68
- package/build/pkg/index.js.map +1 -1
- package/build/tools/debug.js +2 -2
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +21 -8
- package/build/tools/display/debug.jsx.map +1 -1
- package/build/tools/display/index.js +17 -8
- package/build/tools/display/index.js.map +1 -1
- package/build/tools/display/ui.jsx +7 -7
- package/build/tools/display/ui.jsx.map +1 -1
- package/build.zig +112 -68
- package/package.json +24 -16
- package/src/bin/install-pkmn-engine +1 -1
- package/src/lib/common/debug.zig +11 -6
- package/src/lib/common/options.zig +2 -0
- package/src/lib/common/protocol.zig +4 -8
- package/src/lib/common/rational.zig +7 -5
- package/src/lib/common/rng.zig +1 -3
- package/src/lib/gen1/calc.zig +96 -98
- package/src/lib/gen1/chance.zig +37 -21
- 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 +5 -18
- package/src/lib/gen1/mechanics.zig +108 -90
- package/src/lib/gen2/calc.zig +9 -17
- 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 +2 -4
- package/src/lib/pkmn.zig +4 -0
- package/src/lib/wasm.zig +36 -1
- package/src/tools/display/ui.css +12 -9
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
|
|
@@ -119,6 +110,14 @@ pub const Calc = struct {
|
|
|
119
110
|
}) val else null;
|
|
120
111
|
}
|
|
121
112
|
|
|
113
|
+
pub fn confusion(self: *Calc, player: Player) void {
|
|
114
|
+
if (!enabled) return;
|
|
115
|
+
|
|
116
|
+
if (self.overrides.get(player).confusion == .started) {
|
|
117
|
+
self.overrides.get(player).confusion = .None;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
122
121
|
pub fn base(self: *Calc, player: Player, val: u16) void {
|
|
123
122
|
if (!enabled) return;
|
|
124
123
|
|
|
@@ -152,6 +151,10 @@ const Null = struct {
|
|
|
152
151
|
return null;
|
|
153
152
|
}
|
|
154
153
|
|
|
154
|
+
pub fn confusion(self: Null, player: Player) void {
|
|
155
|
+
_ = .{ self, player };
|
|
156
|
+
}
|
|
157
|
+
|
|
155
158
|
pub fn base(self: Null, player: Player, val: u16) void {
|
|
156
159
|
_ = .{ self, player, val };
|
|
157
160
|
}
|
|
@@ -179,7 +182,7 @@ pub const Options = struct {
|
|
|
179
182
|
metronome: bool = false,
|
|
180
183
|
};
|
|
181
184
|
|
|
182
|
-
pub const MAX_FRONTIER =
|
|
185
|
+
pub const MAX_FRONTIER = 81;
|
|
183
186
|
|
|
184
187
|
pub fn transitions(
|
|
185
188
|
battle: anytype,
|
|
@@ -198,11 +201,11 @@ pub fn transitions(
|
|
|
198
201
|
var frontier = std.ArrayList(Actions).init(allocator);
|
|
199
202
|
defer frontier.deinit();
|
|
200
203
|
|
|
201
|
-
const
|
|
204
|
+
const d = options.durations;
|
|
202
205
|
|
|
203
206
|
var opts = pkmn.battle.options(
|
|
204
207
|
protocol.NULL,
|
|
205
|
-
Chance(Rational(u128)){ .probability = .{}, .durations =
|
|
208
|
+
Chance(Rational(u128)){ .probability = .{}, .durations = d },
|
|
206
209
|
Calc{},
|
|
207
210
|
);
|
|
208
211
|
|
|
@@ -242,20 +245,20 @@ pub fn transitions(
|
|
|
242
245
|
};
|
|
243
246
|
|
|
244
247
|
for (Rolls.speedTie(f.p1)) |tie| { a.p1.speed_tie = tie; a.p2.speed_tie = tie;
|
|
245
|
-
for (Rolls.sleep(f.p1,
|
|
246
|
-
for (Rolls.sleep(f.p2,
|
|
247
|
-
for (Rolls.disable(f.p1,
|
|
248
|
-
for (Rolls.disable(f.p2,
|
|
249
|
-
for (Rolls.
|
|
250
|
-
for (Rolls.
|
|
248
|
+
for (Rolls.sleep(f.p1, d.p1)) |p1_slp| { a.p1.sleep = p1_slp;
|
|
249
|
+
for (Rolls.sleep(f.p2, d.p2)) |p2_slp| { a.p2.sleep = p2_slp;
|
|
250
|
+
for (Rolls.disable(f.p1, d.p1, p1_slp)) |p1_dis| { a.p1.disable = p1_dis;
|
|
251
|
+
for (Rolls.disable(f.p2, d.p2, p2_slp)) |p2_dis| { a.p2.disable = p2_dis;
|
|
252
|
+
for (Rolls.attacking(f.p1, d.p1, p1_slp)) |p1_atk| { a.p1.attacking = p1_atk;
|
|
253
|
+
for (Rolls.attacking(f.p2, d.p2, p2_slp)) |p2_atk| { a.p2.attacking = p2_atk;
|
|
254
|
+
for (Rolls.confusion(f.p1, d.p1, p1_atk, p1_slp)) |p1_cfz| { a.p1.confusion = p1_cfz;
|
|
255
|
+
for (Rolls.confusion(f.p2, d.p2, p2_atk, p2_slp)) |p2_cfz| { a.p2.confusion = p2_cfz;
|
|
251
256
|
for (Rolls.confused(f.p1, p1_cfz)) |p1_cfzd| { a.p1.confused = p1_cfzd;
|
|
252
257
|
for (Rolls.confused(f.p2, p2_cfz)) |p2_cfzd| { a.p2.confused = p2_cfzd;
|
|
253
258
|
for (Rolls.paralyzed(f.p1, p1_cfzd)) |p1_par| { a.p1.paralyzed = p1_par;
|
|
254
259
|
for (Rolls.paralyzed(f.p2, p2_cfzd)) |p2_par| { a.p2.paralyzed = p2_par;
|
|
255
|
-
for (Rolls.
|
|
256
|
-
for (Rolls.
|
|
257
|
-
for (Rolls.binding(f.p1, durations.p1, p1_par)) |p1_bind| { a.p1.binding = p1_bind;
|
|
258
|
-
for (Rolls.binding(f.p2, durations.p2, p2_par)) |p2_bind| { a.p2.binding = p2_bind;
|
|
260
|
+
for (Rolls.binding(f.p1, d.p1, p1_par)) |p1_bind| { a.p1.binding = p1_bind;
|
|
261
|
+
for (Rolls.binding(f.p2, d.p2, p2_par)) |p2_bind| { a.p2.binding = p2_bind;
|
|
259
262
|
for (Rolls.hit(f.p1, p1_par)) |p1_hit| { a.p1.hit = p1_hit;
|
|
260
263
|
for (Rolls.hit(f.p2, p2_par)) |p2_hit| { a.p2.hit = p2_hit;
|
|
261
264
|
for (Rolls.psywave(f.p1, p1, p1_hit)) |p1_psywave| { a.p1.psywave = p1_psywave;
|
|
@@ -283,7 +286,7 @@ pub fn transitions(
|
|
|
283
286
|
|
|
284
287
|
opts.calc.overrides = a;
|
|
285
288
|
opts.calc.summaries = .{};
|
|
286
|
-
opts.chance = .{ .probability = .{}, .durations =
|
|
289
|
+
opts.chance = .{ .probability = .{}, .durations = d };
|
|
287
290
|
const q = &opts.chance.probability;
|
|
288
291
|
|
|
289
292
|
b = battle;
|
|
@@ -300,7 +303,7 @@ pub fn transitions(
|
|
|
300
303
|
try Rolls.coalesce(.P2, @as(u8, @intCast(p2_dmg.min)), summaries, cap);
|
|
301
304
|
|
|
302
305
|
if (opts.chance.actions.matches(f)) {
|
|
303
|
-
if (!
|
|
306
|
+
if (!opts.chance.actions.relax().eql(a)) {
|
|
304
307
|
if (!summary) {
|
|
305
308
|
try debug(writer, opts.chance.actions, .{
|
|
306
309
|
.p1_max = p1_max,
|
|
@@ -334,10 +337,13 @@ pub fn transitions(
|
|
|
334
337
|
}
|
|
335
338
|
}
|
|
336
339
|
}
|
|
337
|
-
|
|
338
340
|
if (p1_max != p1_min) try q.update(p1_max - p1_min + 1, 1);
|
|
339
341
|
if (p2_max != p2_dmg.min) try q.update(p2_max - p2_dmg.min + 1, 1);
|
|
342
|
+
|
|
343
|
+
q.reduce();
|
|
340
344
|
try p.add(q);
|
|
345
|
+
p.reduce();
|
|
346
|
+
|
|
341
347
|
stats.saved += 1;
|
|
342
348
|
|
|
343
349
|
if (p.q < p.p) {
|
|
@@ -345,7 +351,7 @@ pub fn transitions(
|
|
|
345
351
|
return error.TestUnexpectedResult;
|
|
346
352
|
}
|
|
347
353
|
} else {
|
|
348
|
-
if (!
|
|
354
|
+
if (!opts.chance.actions.matchesAny(frontier.items, i)) {
|
|
349
355
|
try frontier.append(opts.chance.actions);
|
|
350
356
|
|
|
351
357
|
try debug(writer, opts.chance.actions, .{
|
|
@@ -515,23 +521,6 @@ fn unfix(actual: anytype) data.Battle(data.PRNG) {
|
|
|
515
521
|
};
|
|
516
522
|
}
|
|
517
523
|
|
|
518
|
-
fn map(actions: Actions) Actions {
|
|
519
|
-
if (!pkmn.options.overwrite) return actions;
|
|
520
|
-
var a = actions;
|
|
521
|
-
if (a.p1.confusion == .overwritten) a.p1.confusion = .continuing;
|
|
522
|
-
if (a.p2.confusion == .overwritten) a.p2.confusion = .continuing;
|
|
523
|
-
return a;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
fn matches(actions: Actions, i: usize, frontier: []Actions) bool {
|
|
527
|
-
for (frontier, 0..) |f, j| {
|
|
528
|
-
// TODO: is skipping this redundant check worth it?
|
|
529
|
-
if (i == j) continue;
|
|
530
|
-
if (f.matches(actions)) return true;
|
|
531
|
-
}
|
|
532
|
-
return false;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
524
|
fn err(comptime fmt: []const u8, v: anytype, seed: ?u64) void {
|
|
536
525
|
const w = std.io.getStdErr().writer();
|
|
537
526
|
w.print(fmt, v) catch return;
|
|
@@ -641,65 +630,67 @@ pub const Rolls = struct {
|
|
|
641
630
|
duration: Duration,
|
|
642
631
|
parent: Optional(Observation),
|
|
643
632
|
) []const Optional(Observation) {
|
|
644
|
-
// if (parent == .started or parent == .continuing) return &OBS_NONE;
|
|
645
|
-
_ = parent; // FIXME
|
|
646
633
|
if (action.disable == .None) return &OBS_NONE;
|
|
647
634
|
return if (duration.disable == 0 and action.speed_tie != .None)
|
|
648
635
|
&OBS_ALL
|
|
649
636
|
else switch (action.disable) {
|
|
650
637
|
.started => &OBS_STARTED,
|
|
651
|
-
else => if (duration.disable >= 8)
|
|
638
|
+
else => if (duration.disable >= 8)
|
|
639
|
+
&OBS_ENDED
|
|
640
|
+
else if (parent != .None and parent != .started)
|
|
641
|
+
&OBS_CONTINUING
|
|
642
|
+
else
|
|
643
|
+
&OBS,
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/// FIXME
|
|
648
|
+
pub fn attacking(
|
|
649
|
+
action: Action,
|
|
650
|
+
duration: Duration,
|
|
651
|
+
parent: Optional(Observation),
|
|
652
|
+
) []const Optional(Observation) {
|
|
653
|
+
return switch (action.attacking) {
|
|
654
|
+
.None => &OBS_NONE,
|
|
655
|
+
.started => &OBS_STARTED,
|
|
656
|
+
else => if (duration.attacking >= 3)
|
|
657
|
+
&OBS_ENDED
|
|
658
|
+
else if ((parent == .continuing and parent == .ended) or duration.attacking < 2)
|
|
659
|
+
&OBS_CONTINUING
|
|
660
|
+
else
|
|
661
|
+
&OBS,
|
|
652
662
|
};
|
|
653
663
|
}
|
|
654
664
|
|
|
655
665
|
const CFZ_NONE = [_]Optional(Confusion){.None};
|
|
656
666
|
const CFZ_STARTED = [_]Optional(Confusion){.started};
|
|
667
|
+
const CFZ_OVERWRITTEN = [_]Optional(Confusion){ .started, .overwritten };
|
|
657
668
|
const CFZ_CONTINUING = [_]Optional(Confusion){.continuing};
|
|
658
669
|
const CFZ_ENDED = [_]Optional(Confusion){.ended};
|
|
659
670
|
const CFZ = [_]Optional(Confusion){ .continuing, .ended };
|
|
660
671
|
|
|
661
|
-
///
|
|
662
|
-
/// and the state of the `parent` (observation of the player's Pokémon sleep status).
|
|
672
|
+
/// FIXME
|
|
663
673
|
pub fn confusion(
|
|
664
674
|
action: Action,
|
|
665
675
|
duration: Duration,
|
|
676
|
+
sibling: Optional(Observation),
|
|
666
677
|
parent: Optional(Observation),
|
|
667
678
|
) []const Optional(Confusion) {
|
|
668
|
-
// if (parent == .started or parent == .continuing) return &CFZ_NONE;
|
|
669
|
-
_ = parent; // FIXME
|
|
670
679
|
return switch (action.confusion) {
|
|
671
680
|
.None => &CFZ_NONE,
|
|
672
|
-
.started =>
|
|
681
|
+
.started => if (pkmn.options.overwrite and sibling == .ended and duration.confusion < 5)
|
|
682
|
+
&CFZ_OVERWRITTEN
|
|
683
|
+
else
|
|
684
|
+
&CFZ_STARTED,
|
|
673
685
|
else => if (duration.confusion >= 5)
|
|
674
686
|
&CFZ_ENDED
|
|
675
|
-
else if (duration.confusion < 2)
|
|
687
|
+
else if ((parent == .continuing and parent == .ended) or duration.confusion < 2)
|
|
676
688
|
&CFZ_CONTINUING
|
|
677
689
|
else
|
|
678
690
|
&CFZ,
|
|
679
691
|
};
|
|
680
692
|
}
|
|
681
693
|
|
|
682
|
-
/// Returns a slice with a range of values for attacking given the `action`, observed
|
|
683
|
-
/// `durations`, and the state of the `parent` (whether the player's Pokémon was fully
|
|
684
|
-
/// paralyzed).
|
|
685
|
-
pub fn attacking(
|
|
686
|
-
action: Action,
|
|
687
|
-
duration: Duration,
|
|
688
|
-
parent: Optional(bool),
|
|
689
|
-
) []const Optional(Observation) {
|
|
690
|
-
if (parent == .true) return &OBS_NONE;
|
|
691
|
-
return switch (action.attacking) {
|
|
692
|
-
.None => &OBS_NONE,
|
|
693
|
-
.started => &OBS_STARTED,
|
|
694
|
-
else => if (duration.attacking >= 3)
|
|
695
|
-
&OBS_ENDED
|
|
696
|
-
else if (duration.attacking < 2)
|
|
697
|
-
&OBS_CONTINUING
|
|
698
|
-
else
|
|
699
|
-
&OBS,
|
|
700
|
-
};
|
|
701
|
-
}
|
|
702
|
-
|
|
703
694
|
/// Returns a slice with a range of values for binding given the `action`, observed `durations`,
|
|
704
695
|
/// and the state of the `parent` (whether the player's Pokémon was fully paralyzed).
|
|
705
696
|
pub fn binding(
|
|
@@ -728,7 +719,7 @@ pub const Rolls = struct {
|
|
|
728
719
|
/// Returns a slice with the correct range of values for critical hits given the `action` state
|
|
729
720
|
/// and the state of the `parent` (whether the player's Pokémon's move hit).
|
|
730
721
|
pub fn criticalHit(action: Action, parent: Optional(bool)) []const Optional(bool) {
|
|
731
|
-
if (parent == .false) return &BOOL_NONE;
|
|
722
|
+
if (pkmn.options.showdown and parent == .false) return &BOOL_NONE;
|
|
732
723
|
return if (action.critical_hit == .None) &BOOL_NONE else &BOOLS;
|
|
733
724
|
}
|
|
734
725
|
|
|
@@ -766,8 +757,7 @@ pub const Rolls = struct {
|
|
|
766
757
|
/// Returns a slice with the correct range of values for confused given the `action` state and
|
|
767
758
|
/// the state of the `parent` (observation of the player's Pokémon confusion status).
|
|
768
759
|
pub fn confused(action: Action, parent: Optional(Confusion)) []const Optional(bool) {
|
|
769
|
-
const done =
|
|
770
|
-
_ = parent; // FIXME
|
|
760
|
+
const done = parent == .None or parent == .ended;
|
|
771
761
|
return if (done or action.confused == .None) &BOOL_NONE else &BOOLS;
|
|
772
762
|
}
|
|
773
763
|
|
|
@@ -898,15 +888,23 @@ test "Rolls.criticalHit" {
|
|
|
898
888
|
&.{ .false, .true },
|
|
899
889
|
Rolls.criticalHit(actions.p1, .None),
|
|
900
890
|
);
|
|
901
|
-
try expectEqualSlices(
|
|
891
|
+
try expectEqualSlices(
|
|
892
|
+
Optional(bool),
|
|
893
|
+
if (pkmn.options.showdown) &.{.None} else &.{ .false, .true },
|
|
894
|
+
Rolls.criticalHit(actions.p1, .false),
|
|
895
|
+
);
|
|
902
896
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.criticalHit(actions.p2, .None));
|
|
903
897
|
}
|
|
904
898
|
|
|
905
899
|
test "Rolls.confused" {
|
|
906
900
|
const actions: Actions = .{ .p2 = .{ .confused = .true } };
|
|
907
901
|
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p1, .None));
|
|
908
|
-
try expectEqualSlices(
|
|
909
|
-
|
|
902
|
+
try expectEqualSlices(
|
|
903
|
+
Optional(bool),
|
|
904
|
+
&.{ .false, .true },
|
|
905
|
+
Rolls.confused(actions.p2, .continuing),
|
|
906
|
+
);
|
|
907
|
+
try expectEqualSlices(Optional(bool), &.{.None}, Rolls.confused(actions.p2, .ended));
|
|
910
908
|
}
|
|
911
909
|
|
|
912
910
|
test "Rolls.paralyzed" {
|
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);
|
|
@@ -224,7 +240,7 @@ pub const Action = packed struct(u64) {
|
|
|
224
240
|
};
|
|
225
241
|
|
|
226
242
|
/// TODO
|
|
227
|
-
pub const Durations = struct {
|
|
243
|
+
pub const Durations = extern struct {
|
|
228
244
|
/// TODO
|
|
229
245
|
p1: Duration = .{},
|
|
230
246
|
/// TODO
|
|
@@ -375,7 +391,7 @@ pub fn Chance(comptime Rational: type) type {
|
|
|
375
391
|
|
|
376
392
|
// If the move actually lands we can commit any past critical hit / damage rolls. Note
|
|
377
393
|
// we can't rely on the presence or absence of a damage roll to determine whether a
|
|
378
|
-
// "critical hit" was spurious or not as moves that do 1 or less damage don't
|
|
394
|
+
// "critical hit" was spurious or not as moves that do 1 or less damage don't roll for
|
|
379
395
|
// damage but can still crit (instead, whether or not a roll is deemed to be a no-op is
|
|
380
396
|
// passed to the critical hit helper).
|
|
381
397
|
//
|
|
@@ -391,7 +407,7 @@ pub fn Chance(comptime Rational: type) type {
|
|
|
391
407
|
action.critical_hit = if (self.pending.crit) .true else .false;
|
|
392
408
|
} else assert(!self.pending.glitch);
|
|
393
409
|
|
|
394
|
-
if (self.pending.damage_roll > 0) {
|
|
410
|
+
if (self.pending.damage_roll > 0 and (!self.pending.glitch or self.pending.hit)) {
|
|
395
411
|
try self.probability.update(1, 39);
|
|
396
412
|
action.damage = self.pending.damage_roll;
|
|
397
413
|
}
|
|
@@ -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
|
|
|
@@ -266,14 +260,7 @@ fn blocked(m: Move) bool {
|
|
|
266
260
|
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
|
-
.
|
|
270
|
-
.Bide,
|
|
271
|
-
.Sleep,
|
|
272
|
-
.Rage,
|
|
273
|
-
.Binding,
|
|
274
|
-
.Thrashing,
|
|
275
|
-
.ConfusionChance,
|
|
276
|
-
.Disable,
|
|
263
|
+
.Haze,
|
|
277
264
|
.Metronome,
|
|
278
265
|
=> true,
|
|
279
266
|
else => false,
|