@pkmn/engine 0.1.0-dev.9f75c7ae → 0.1.0-dev.a0167a9d

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.
Files changed (42) hide show
  1. package/LICENSE +1 -3
  2. package/README.md +44 -19
  3. package/build/pkg/addon.js +6 -7
  4. package/build/pkg/addon.js.map +1 -1
  5. package/build/pkg/data.d.ts +4 -4
  6. package/build/pkg/data.js.map +1 -1
  7. package/build/pkg/gen1.js.map +1 -1
  8. package/build/pkg/index.d.ts +2 -1
  9. package/build/pkg/index.js.map +1 -1
  10. package/build/pkg/protocol.js +5 -5
  11. package/build/pkg/protocol.js.map +1 -1
  12. package/build/test/display.js +2 -2
  13. package/build/test/display.js.map +1 -1
  14. package/build/tools/debug.js +5 -4
  15. package/build/tools/debug.js.map +1 -1
  16. package/build.zig +82 -90
  17. package/package.json +31 -23
  18. package/src/bin/install-pkmn-engine +26 -18
  19. package/src/lib/common/data.zig +4 -4
  20. package/src/lib/common/debug.zig +2 -2
  21. package/src/lib/common/optional.zig +1 -1
  22. package/src/lib/common/options.zig +2 -0
  23. package/src/lib/common/protocol.zig +393 -396
  24. package/src/lib/common/rational.zig +109 -15
  25. package/src/lib/common/rng.zig +11 -11
  26. package/src/lib/gen1/calc.zig +269 -97
  27. package/src/lib/gen1/chance.zig +126 -160
  28. package/src/lib/gen1/data/species.zig +1 -1
  29. package/src/lib/gen1/data.zig +21 -21
  30. package/src/lib/gen1/helpers.zig +191 -206
  31. package/src/lib/gen1/mechanics.zig +308 -285
  32. package/src/lib/gen2/chance.zig +211 -121
  33. package/src/lib/gen2/data.zig +13 -11
  34. package/src/lib/gen2/generated.zig +15 -24
  35. package/src/lib/gen2/helpers.zig +37 -7
  36. package/src/lib/gen2/mechanics.zig +855 -413
  37. package/src/lib/{binding/node.zig → node.zig} +9 -12
  38. package/src/lib/pkmn.zig +27 -12
  39. package/src/lib/{binding/wasm.zig → wasm.zig} +2 -1
  40. package/src/test/display/pkmn.html.tmpl +5 -5
  41. package/src/lib/gen1/README.md +0 -894
  42. package/src/lib/gen2/README.md +0 -330
@@ -14,7 +14,7 @@ const util = @import("../common/util.zig");
14
14
  const Player = @import("../common/data.zig").Player;
15
15
  const Optional = @import("../common/optional.zig").Optional;
16
16
 
17
- const data = @import("./data.zig");
17
+ const data = @import("data.zig");
18
18
 
19
19
  const enabled = options.chance;
20
20
  const showdown = options.showdown;
@@ -48,6 +48,11 @@ pub const Actions = extern struct {
48
48
  self.p2.reset();
49
49
  }
50
50
 
51
+ /// TODO
52
+ pub fn durations(self: Actions) Durations {
53
+ return .{ .p1 = self.p1.durations(), .p2 = self.p2.durations() };
54
+ }
55
+
51
56
  /// Returns true if `a` is equal to `b`.
52
57
  pub fn eql(a: Actions, b: Actions) bool {
53
58
  return @as(u128, @bitCast(a.p1)) == @as(u128, @bitCast(b.p1)) and
@@ -64,15 +69,17 @@ pub const Actions = extern struct {
64
69
  const b_val = @field(@field(b, player.name), field.name);
65
70
 
66
71
  switch (@typeInfo(@TypeOf(a_val))) {
67
- .Struct => inline for (@typeInfo(@TypeOf(a_val)).Struct.fields) |f| {
68
- const a_val_f = @field(a_val, f.name);
69
- const b_val_f = @field(b_val, f.name);
70
- switch (@typeInfo(@TypeOf(a_val_f))) {
71
- .Int => if ((a_val_f > 0) != (b_val_f > 0)) return false,
72
- .Bool => if (a_val_f != b_val_f) return false,
73
- else => unreachable,
74
- }
75
- },
72
+ // TODO: ziglang/zig#19730
73
+ // .Struct => inline for (@typeInfo(@TypeOf(a_val)).Struct.fields) |f| {
74
+ // const a_val_f = @field(a_val, f.name);
75
+ // const b_val_f = @field(b_val, f.name);
76
+ // switch (@typeInfo(@TypeOf(a_val_f))) {
77
+ // .Int => if ((a_val_f > 0) != (b_val_f > 0)) return false,
78
+ // .Bool => if (a_val_f != b_val_f) return false,
79
+ // else => unreachable,
80
+ // }
81
+ // },
82
+ .Bool => if (a_val != b_val) return false, // TODO
76
83
  .Enum => if ((@intFromEnum(a_val) > 0) != (@intFromEnum(b_val) > 0))
77
84
  return false,
78
85
  .Int => if ((a_val > 0) != (b_val > 0)) return false,
@@ -97,16 +104,17 @@ pub const Actions = extern struct {
97
104
  }
98
105
  };
99
106
 
107
+ // TODO: ziglang/zig#19730
100
108
  test Actions {
101
109
  const a: Actions = .{ .p1 = .{ .hit = .true, .critical_hit = .false, .damage = 245 } };
102
110
  const b: Actions = .{ .p1 = .{ .hit = .false, .critical_hit = .true, .damage = 246 } };
103
111
  const c: Actions = .{ .p1 = .{ .hit = .true } };
104
- const d: Actions = .{ .p2 = .{ .hit = .true, .durations = .{ .sleep = 2 } } };
105
- const e: Actions = .{ .p2 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
106
- const f: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .sleep = 4 } } };
107
- const g: Actions = .{ .p1 = .{ .hit = .false, .durations = .{ .confusion = 1 } } };
112
+ const d: Actions = .{ .p2 = .{ .hit = .true, .durations_sleep = 2 } };
113
+ const e: Actions = .{ .p2 = .{ .hit = .false, .durations_sleep = 4 } };
114
+ const f: Actions = .{ .p1 = .{ .hit = .false, .durations_sleep = 4 } };
115
+ const g: Actions = .{ .p1 = .{ .hit = .false, .durations_confusion = 1 } };
108
116
  const h: Actions =
109
- .{ .p1 = .{ .hit = .false, .durations = .{ .confusion = 1, .thrash = true } } };
117
+ .{ .p1 = .{ .hit = .false, .durations_confusion = 1, .durations_thrash = true } };
110
118
 
111
119
  try expect(a.eql(a));
112
120
  try expect(!a.eql(b));
@@ -188,10 +196,26 @@ pub const Action = packed struct(u128) {
188
196
  /// If not None, the Move to return for Rolls.metronome.
189
197
  metronome: Move = .None,
190
198
 
191
- _: u16 = 0,
199
+ _: u28 = 0,
200
+
201
+ // TODO: ziglang/zig#19730
202
+ /// Observed values of various durations_ Does not influence future RNG calls. TODO
203
+ // durations: Duration = .{},
192
204
 
193
- /// Observed values of various durations. Does not influence future RNG calls. TODO
194
- durations: Duration = .{},
205
+ /// The number of turns a Pokémon has been observed to be sleeping.
206
+ durations_sleep: u3 = 0,
207
+ /// The number of turns a Pokémon has been observed to be confused.
208
+ durations_confusion: u3 = 0,
209
+ /// TODO
210
+ durations_thrash: bool = false,
211
+ /// The number of turns a Pokémon has been observed to be disabled.
212
+ durations_disable: u4 = 0,
213
+ /// The number of turns a Pokémon has been observed to be attacking.
214
+ durations_attacking: u3 = 0,
215
+ /// The number of turns a Pokémon has been observed to be binding their opponent.
216
+ durations_binding: u3 = 0,
217
+ /// The number of turns a Pokémon has been observed to be encored.
218
+ durations_encore: u3 = 0,
195
219
 
196
220
  pub const DURATIONS: u128 = 0xFFFFFFFF00000000_0000000000000000;
197
221
 
@@ -202,6 +226,19 @@ pub const Action = packed struct(u128) {
202
226
  self.* = @bitCast(@as(u128, @bitCast(self.*)) & DURATIONS);
203
227
  }
204
228
 
229
+ // TODO: ziglang/zig#19730
230
+ pub fn durations(self: Action) Duration {
231
+ return .{
232
+ .sleep = self.durations_sleep,
233
+ .confusion = self.durations_confusion,
234
+ .thrash = self.durations_thrash,
235
+ .disable = self.durations_disable,
236
+ .attacking = self.durations_attacking,
237
+ .binding = self.durations_binding,
238
+ .encore = self.durations_encore,
239
+ };
240
+ }
241
+
205
242
  pub fn format(a: Action, comptime f: []const u8, o: std.fmt.FormatOptions, w: anytype) !void {
206
243
  _ = .{ f, o };
207
244
  try fmt(a, w, false);
@@ -213,18 +250,19 @@ pub const Action = packed struct(u128) {
213
250
  inline for (@typeInfo(Action).Struct.fields) |field| {
214
251
  const val = @field(self, field.name);
215
252
  switch (@typeInfo(@TypeOf(val))) {
216
- .Struct => inline for (@typeInfo(@TypeOf(val)).Struct.fields) |f| {
217
- const v = @field(val, f.name);
218
- if (v != 0) {
219
- if (printed) try writer.writeAll(", ");
220
- if (shape) {
221
- try writer.print("{s}:?", .{f.name});
222
- } else {
223
- try writer.print("{s}:{d}", .{ f.name, v });
224
- }
225
- printed = true;
226
- }
227
- },
253
+ // TODO: ziglang/zig#19730
254
+ // .Struct => inline for (@typeInfo(@TypeOf(val)).Struct.fields) |f| {
255
+ // const v = @field(val, f.name);
256
+ // if (v != 0) {
257
+ // if (printed) try writer.writeAll(", ");
258
+ // if (shape) {
259
+ // try writer.print("{s}:?", .{f.name});
260
+ // } else {
261
+ // try writer.print("{s}:{d}", .{ f.name, v });
262
+ // }
263
+ // printed = true;
264
+ // }
265
+ // },
228
266
  .Enum => if (val != .None) {
229
267
  if (printed) try writer.writeAll(", ");
230
268
  if (shape) {
@@ -256,12 +294,24 @@ pub const Action = packed struct(u128) {
256
294
  };
257
295
 
258
296
  test Action {
259
- var a: Action = .{ .hit = .true, .durations = .{ .sleep = 3 }, .damage = 225 };
297
+ var a: Action = .{ .hit = .true, .durations_sleep = 3, .damage = 225 };
260
298
  a.reset();
261
299
 
262
- try expectEqual(Action{ .hit = .None, .durations = .{ .sleep = 3 }, .damage = 0 }, a);
300
+ try expectEqual(Action{ .hit = .None, .durations_sleep = 3, .damage = 0 }, a);
263
301
  }
264
302
 
303
+ /// TODO
304
+ pub const Durations = extern struct {
305
+ /// Information about the durations for Player 1.
306
+ p1: Duration = .{},
307
+ /// Information about the durations for Player 2.
308
+ p2: Duration = .{},
309
+
310
+ comptime {
311
+ assert(@sizeOf(Durations) == 4);
312
+ }
313
+ };
314
+
265
315
  /// Observed values for various durations that need to be tracked in order to properly
266
316
  /// deduplicate transitions with a primary key. TODO
267
317
  pub const Duration = packed struct(u32) {
@@ -323,11 +373,19 @@ pub fn Chance(comptime Rational: type) type {
323
373
 
324
374
  var action = self.actions.get(player);
325
375
 
326
- const slp = action.durations.sleep;
327
- action.durations = .{};
376
+ const slp = action.durations_sleep;
377
+ // TODO: ziglang/zig#19730
378
+ // action.durations = .{};
379
+ action.durations_sleep = 0;
380
+ action.durations_confusion = 0;
381
+ action.durations_thrash = false;
382
+ action.durations_disable = 0;
383
+ action.durations_attacking = 0;
384
+ action.durations_binding = 0;
385
+ action.durations_encore = 0;
328
386
 
329
387
  self.sleeps[@intFromEnum(player)][out - 1] = slp;
330
- action.durations.sleep = @intCast(self.sleeps[@intFromEnum(player)][in - 1]);
388
+ action.durations_sleep = @intCast(self.sleeps[@intFromEnum(player)][in - 1]);
331
389
  }
332
390
 
333
391
  pub fn speedTie(self: *Self, p1: bool) Error!void {
@@ -526,95 +584,127 @@ pub fn Chance(comptime Rational: type) type {
526
584
  ) void {
527
585
  if (!enabled) return;
528
586
 
529
- var durations = &self.actions.get(target).durations;
530
- assert(@field(durations, @tagName(field)) == 0 or
531
- (field == .confusion and player == target));
532
- @field(durations, @tagName(field)) = 1;
533
- if (field == .confusion) durations.thrash = player == target;
587
+ // TODO: ziglang/zig#19730
588
+ // var durations = &self.actions.get(target).durations;
589
+ // assert(@field(durations, @tagName(field)) == 0 or
590
+ // (field == .confusion and player == target));
591
+ // @field(durations, @tagName(field)) = 1;
592
+ // if (field == .confusion) durations_thrash = player == target;
593
+ switch (field) {
594
+ .sleep => {
595
+ assert(self.actions.get(target).durations_sleep == 0);
596
+ self.actions.get(target).durations_sleep = 1;
597
+ },
598
+ .confusion => {
599
+ assert(self.actions.get(target).durations_confusion == 0 or
600
+ player == target);
601
+ self.actions.get(target).durations_thrash = player == target;
602
+ self.actions.get(target).durations_confusion = 1;
603
+ },
604
+ .thrash => unreachable,
605
+ .disable => {
606
+ assert(self.actions.get(target).durations_disable == 0);
607
+ self.actions.get(target).durations_disable = 1;
608
+ },
609
+ .attacking => {
610
+ assert(self.actions.get(target).durations_attacking == 0);
611
+ self.actions.get(target).durations_attacking = 1;
612
+ },
613
+ .binding => {
614
+ assert(self.actions.get(target).durations_binding == 0);
615
+ self.actions.get(target).durations_binding = 1;
616
+ },
617
+ .encore => {
618
+ assert(self.actions.get(target).durations_encore == 0);
619
+ self.actions.get(target).durations_encore = 1;
620
+ },
621
+ ._ => unreachable,
622
+ }
623
+
534
624
  self.actions.get(player).duration = if (options.key) 1 else turns;
535
625
  }
536
626
 
537
627
  pub fn sleep(self: *Self, player: Player, turns: u4) Error!void {
538
628
  if (!enabled) return;
539
629
 
540
- var durations = &self.actions.get(player).durations;
541
- const n = durations.sleep;
630
+ const durations_sleep = &self.actions.get(player).durations_sleep;
631
+ const n = durations_sleep.*;
542
632
  if (turns == 0) {
543
633
  assert(n >= 1 and n <= 6);
544
634
  if (n != 6) try self.probability.update(1, 7 - @as(u4, n));
545
- durations.sleep = 0;
635
+ durations_sleep.* = 0;
546
636
  } else {
547
637
  assert(n >= 1 and n < 6);
548
638
  try self.probability.update(7 - @as(u4, n) - 1, 7 - @as(u4, n));
549
- durations.sleep += 1;
639
+ durations_sleep.* += 1;
550
640
  }
551
641
  }
552
642
 
553
643
  pub fn confusion(self: *Self, player: Player, turns: u4) Error!void {
554
644
  if (!enabled) return;
555
645
 
556
- var durations = &self.actions.get(player).durations;
557
- const n = durations.confusion;
558
- const hi: u8 = if (durations.thrash) 3 else 5;
646
+ const durations_confusion = &self.actions.get(player).durations_confusion;
647
+ const n = durations_confusion.*;
648
+ const hi: u8 = if (self.actions.get(player).durations_thrash) 3 else 5;
559
649
  const p = hi + 1;
560
650
  if (turns == 0) {
561
651
  assert(n >= 2 and n <= hi);
562
652
  if (n != hi) try self.probability.update(1, p - @as(u4, n));
563
- durations.confusion = 0;
653
+ durations_confusion.* = 0;
564
654
  } else {
565
655
  assert(n >= 1 and n < hi);
566
656
  if (n > 1) try self.probability.update(p - @as(u4, n) - 1, p - @as(u4, n));
567
- durations.confusion += 1;
657
+ durations_confusion.* += 1;
568
658
  }
569
659
  }
570
660
 
571
661
  pub fn disable(self: *Self, player: Player, turns: u4) Error!void {
572
662
  if (!enabled) return;
573
663
 
574
- var durations = &self.actions.get(player).durations;
575
- const n = durations.disable;
664
+ const durations_disable = &self.actions.get(player).durations_disable;
665
+ const n = durations_disable.*;
576
666
  const hi = if (showdown) 5 else 8;
577
667
  const p = hi + 1;
578
668
  if (turns == 0) {
579
669
  assert(n >= 2 and n <= hi);
580
670
  if (n != hi) try self.probability.update(1, p - n);
581
- durations.disable = 0;
671
+ durations_disable.* = 0;
582
672
  } else {
583
673
  assert(n >= 1 and n < hi);
584
674
  if (n > 1) try self.probability.update(p - n - 1, p - n);
585
- durations.disable += 1;
675
+ durations_disable.* += 1;
586
676
  }
587
677
  }
588
678
 
589
679
  pub fn attacking(self: *Self, player: Player, turns: u4) Error!void {
590
680
  if (!enabled) return;
591
681
 
592
- var durations = &self.actions.get(player).durations;
593
- const n = durations.attacking;
682
+ const durations_attacking = &self.actions.get(player).durations_attacking;
683
+ const n = durations_attacking.*;
594
684
  if (turns == 0) {
595
685
  assert(n >= 2 and n <= 3);
596
686
  if (n != 3) try self.probability.update(1, 4 - @as(u4, n));
597
- durations.attacking = 0;
687
+ durations_attacking.* = 0;
598
688
  } else {
599
689
  assert(n >= 1 and n < 3);
600
690
  if (n > 1) try self.probability.update(4 - @as(u4, n) - 1, 4 - @as(u4, n));
601
- durations.attacking += 1;
691
+ durations_attacking.* += 1;
602
692
  }
603
693
  }
604
694
 
605
695
  pub fn binding(self: *Self, player: Player, turns: u4) Error!void {
606
696
  if (!enabled) return;
607
697
 
608
- var durations = &self.actions.get(player).durations;
609
- const n = durations.binding;
698
+ const durations_binding = &self.actions.get(player).durations_binding;
699
+ const n = durations_binding.*;
610
700
  if (turns == 0) {
611
701
  assert(n >= 2 and n <= 5);
612
702
  if (n != 5) try self.probability.update(1, 6 - @as(u4, n));
613
- durations.binding = 0;
703
+ durations_binding.* = 0;
614
704
  } else {
615
705
  assert(n >= 1 and n < 5);
616
706
  if (n > 1) try self.probability.update(6 - @as(u4, n) - 1, 6 - @as(u4, n));
617
- durations.binding += 1;
707
+ durations_binding.* += 1;
618
708
  }
619
709
  }
620
710
 
@@ -622,16 +712,16 @@ pub fn Chance(comptime Rational: type) type {
622
712
  pub fn encore(self: *Self, player: Player, turns: u4) Error!void {
623
713
  if (!enabled) return;
624
714
 
625
- var durations = &self.actions.get(player).durations;
626
- const n = durations.encore;
715
+ const durations_encore = &self.actions.get(player).durations_encore;
716
+ const n = durations_encore.*;
627
717
  if (turns == 0) {
628
718
  assert(n >= 2 and n <= 5);
629
719
  if (n != 5) try self.probability.update(1, 6 - @as(u4, n));
630
- durations.encore = 0;
720
+ durations_encore.* = 0;
631
721
  } else {
632
722
  assert(n >= 1 and n < 5);
633
723
  if (n > 1) try self.probability.update(6 - @as(u4, n) - 1, 6 - @as(u4, n));
634
- durations.encore += 1;
724
+ durations_encore.* += 1;
635
725
  }
636
726
  }
637
727
  };
@@ -699,7 +789,7 @@ test "Chance.damage" {
699
789
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
700
790
 
701
791
  try chance.damage(.P1, 217);
702
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
792
+ try expectValue(217, chance.actions.p1.damage);
703
793
  try expectProbability(&chance.probability, 1, 39);
704
794
  }
705
795
 
@@ -824,7 +914,7 @@ test "Chance.present" {
824
914
  } else {
825
915
  try expectProbability(&chance.probability, 25, 256);
826
916
  }
827
- try expectValue(@as(u3, 4), chance.actions.p2.present);
917
+ try expectValue(4, chance.actions.p2.present);
828
918
 
829
919
  chance.reset();
830
920
 
@@ -834,7 +924,7 @@ test "Chance.present" {
834
924
  } else {
835
925
  try expectProbability(&chance.probability, 51, 256);
836
926
  }
837
- try expectValue(@as(u3, 1), chance.actions.p1.present);
927
+ try expectValue(1, chance.actions.p1.present);
838
928
  }
839
929
 
840
930
  test "Chance.magnitude" {
@@ -846,7 +936,7 @@ test "Chance.magnitude" {
846
936
  } else {
847
937
  try expectProbability(&chance.probability, 13, 256);
848
938
  }
849
- try expectValue(@as(u3, 7), chance.actions.p2.magnitude);
939
+ try expectValue(7, chance.actions.p2.magnitude);
850
940
 
851
941
  chance.reset();
852
942
 
@@ -856,7 +946,7 @@ test "Chance.magnitude" {
856
946
  } else {
857
947
  try expectProbability(&chance.probability, 51, 256);
858
948
  }
859
- try expectValue(@as(u3, 5), chance.actions.p1.magnitude);
949
+ try expectValue(5, chance.actions.p1.magnitude);
860
950
  }
861
951
 
862
952
  test "Chance.tripleKick" {
@@ -864,7 +954,7 @@ test "Chance.tripleKick" {
864
954
 
865
955
  try chance.tripleKick(.P1, 2);
866
956
  try expectProbability(&chance.probability, 1, 3);
867
- try expectValue(@as(u2, 2), chance.actions.p1.triple_kick);
957
+ try expectValue(2, chance.actions.p1.triple_kick);
868
958
  }
869
959
 
870
960
  test "Chance.spite" {
@@ -872,7 +962,7 @@ test "Chance.spite" {
872
962
 
873
963
  try chance.spite(.P1, 3);
874
964
  try expectProbability(&chance.probability, 1, 4);
875
- try expectValue(@as(u3, 3), chance.actions.p1.spite);
965
+ try expectValue(3, chance.actions.p1.spite);
876
966
  }
877
967
 
878
968
  test "Chance.conversion2" {
@@ -899,7 +989,7 @@ test "Chance.psywave" {
899
989
 
900
990
  try chance.psywave(.P2, 100, 150);
901
991
  try expectProbability(&chance.probability, 1, 150);
902
- try expectValue(@as(u8, 100), chance.actions.p2.psywave);
992
+ try expectValue(100, chance.actions.p2.psywave);
903
993
  }
904
994
 
905
995
  test "Chance.metronome" {
@@ -915,19 +1005,19 @@ test "Chance.moveSlot" {
915
1005
 
916
1006
  try chance.moveSlot(.P2, 2, 2);
917
1007
  try expectProbability(&chance.probability, 1, 2);
918
- try expectValue(@as(u4, 2), chance.actions.p2.move_slot);
1008
+ try expectValue(2, chance.actions.p2.move_slot);
919
1009
 
920
1010
  chance.reset();
921
1011
 
922
1012
  try chance.moveSlot(.P1, 1, 3);
923
1013
  try expectProbability(&chance.probability, 1, 3);
924
- try expectValue(@as(u4, 1), chance.actions.p1.move_slot);
1014
+ try expectValue(1, chance.actions.p1.move_slot);
925
1015
 
926
1016
  chance.reset();
927
1017
 
928
1018
  try chance.moveSlot(.P1, 4, 1);
929
1019
  try expectProbability(&chance.probability, 1, 1);
930
- try expectValue(@as(u4, 4), chance.actions.p1.move_slot);
1020
+ try expectValue(4, chance.actions.p1.move_slot);
931
1021
  }
932
1022
 
933
1023
  test "Chance.forceSwitch" {
@@ -935,19 +1025,19 @@ test "Chance.forceSwitch" {
935
1025
 
936
1026
  try chance.forceSwitch(.P2, 2, 2);
937
1027
  try expectProbability(&chance.probability, 1, 2);
938
- try expectValue(@as(u4, 2), chance.actions.p2.force_switch);
1028
+ try expectValue(2, chance.actions.p2.force_switch);
939
1029
 
940
1030
  chance.reset();
941
1031
 
942
1032
  try chance.forceSwitch(.P1, 1, 3);
943
1033
  try expectProbability(&chance.probability, 1, 3);
944
- try expectValue(@as(u4, 1), chance.actions.p1.force_switch);
1034
+ try expectValue(1, chance.actions.p1.force_switch);
945
1035
 
946
1036
  chance.reset();
947
1037
 
948
1038
  try chance.forceSwitch(.P1, 4, 1);
949
1039
  try expectProbability(&chance.probability, 1, 1);
950
- try expectValue(@as(u4, 4), chance.actions.p1.force_switch);
1040
+ try expectValue(4, chance.actions.p1.force_switch);
951
1041
  }
952
1042
 
953
1043
  test "Chance.multiHit" {
@@ -955,39 +1045,39 @@ test "Chance.multiHit" {
955
1045
 
956
1046
  try chance.multiHit(.P1, 3);
957
1047
  try expectProbability(&chance.probability, 3, 8);
958
- try expectValue(@as(u4, 3), chance.actions.p1.multi_hit);
1048
+ try expectValue(3, chance.actions.p1.multi_hit);
959
1049
 
960
1050
  chance.reset();
961
1051
 
962
1052
  try chance.multiHit(.P2, 5);
963
1053
  try expectProbability(&chance.probability, 1, 8);
964
- try expectValue(@as(u4, 5), chance.actions.p2.multi_hit);
1054
+ try expectValue(5, chance.actions.p2.multi_hit);
965
1055
  }
966
1056
 
967
1057
  test "Chance.duration" {
968
1058
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
969
1059
 
970
1060
  chance.duration(.sleep, .P1, .P2, 2);
971
- try expectValue(@as(u4, 2), chance.actions.p1.duration);
972
- try expectValue(@as(u3, 1), chance.actions.p2.durations.sleep);
1061
+ try expectValue(2, chance.actions.p1.duration);
1062
+ try expectValue(1, chance.actions.p2.durations_sleep);
973
1063
  }
974
1064
 
975
1065
  test "Chance.sleep" {
976
1066
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
977
1067
 
978
1068
  for ([_]u8{ 6, 5, 4, 3, 2, 1 }, 1..7) |d, i| {
979
- chance.actions.p1.durations.sleep = @intCast(i);
1069
+ chance.actions.p1.durations_sleep = @intCast(i);
980
1070
  try chance.sleep(.P1, 0);
981
1071
  try expectProbability(&chance.probability, 1, d);
982
- try expectValue(@as(u3, 0), chance.actions.p1.durations.sleep);
1072
+ try expectValue(0, chance.actions.p1.durations_sleep);
983
1073
 
984
1074
  chance.reset();
985
1075
 
986
1076
  if (i < 6) {
987
- chance.actions.p1.durations.sleep = @intCast(i);
1077
+ chance.actions.p1.durations_sleep = @intCast(i);
988
1078
  try chance.sleep(.P1, 1);
989
1079
  try expectProbability(&chance.probability, d - 1, d);
990
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p1.durations.sleep);
1080
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p1.durations_sleep);
991
1081
 
992
1082
  chance.reset();
993
1083
  }
@@ -997,24 +1087,24 @@ test "Chance.sleep" {
997
1087
  test "Chance.confusion" {
998
1088
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
999
1089
 
1000
- chance.actions.p2.durations.thrash = false;
1090
+ chance.actions.p2.durations_thrash = false;
1001
1091
  for ([_]u8{ 1, 4, 3, 2, 1 }, 1..6) |d, i| {
1002
1092
  if (i > 1) {
1003
- chance.actions.p2.durations.confusion = @intCast(i);
1093
+ chance.actions.p2.durations_confusion = @intCast(i);
1004
1094
  try chance.confusion(.P2, 0);
1005
1095
  try expectProbability(&chance.probability, 1, d);
1006
- try expectValue(@as(u3, 0), chance.actions.p2.durations.confusion);
1007
- try expectValue(false, chance.actions.p2.durations.thrash);
1096
+ try expectValue(0, chance.actions.p2.durations_confusion);
1097
+ try expectValue(false, chance.actions.p2.durations_thrash);
1008
1098
 
1009
1099
  chance.reset();
1010
1100
  }
1011
1101
 
1012
1102
  if (i < 5) {
1013
- chance.actions.p2.durations.confusion = @intCast(i);
1103
+ chance.actions.p2.durations_confusion = @intCast(i);
1014
1104
  try chance.confusion(.P2, 1);
1015
1105
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1016
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations.confusion);
1017
- try expectValue(false, chance.actions.p2.durations.thrash);
1106
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations_confusion);
1107
+ try expectValue(false, chance.actions.p2.durations_thrash);
1018
1108
 
1019
1109
  chance.reset();
1020
1110
  }
@@ -1022,24 +1112,24 @@ test "Chance.confusion" {
1022
1112
 
1023
1113
  chance.reset();
1024
1114
 
1025
- chance.actions.p2.durations.thrash = true;
1115
+ chance.actions.p2.durations_thrash = true;
1026
1116
  for ([_]u8{ 1, 2, 1 }, 1..4) |d, i| {
1027
1117
  if (i > 1) {
1028
- chance.actions.p2.durations.confusion = @intCast(i);
1118
+ chance.actions.p2.durations_confusion = @intCast(i);
1029
1119
  try chance.confusion(.P2, 0);
1030
1120
  try expectProbability(&chance.probability, 1, d);
1031
- try expectValue(@as(u3, 0), chance.actions.p2.durations.confusion);
1032
- try expectValue(true, chance.actions.p2.durations.thrash);
1121
+ try expectValue(0, chance.actions.p2.durations_confusion);
1122
+ try expectValue(true, chance.actions.p2.durations_thrash);
1033
1123
 
1034
1124
  chance.reset();
1035
1125
  }
1036
1126
 
1037
1127
  if (i < 3) {
1038
- chance.actions.p2.durations.confusion = @intCast(i);
1128
+ chance.actions.p2.durations_confusion = @intCast(i);
1039
1129
  try chance.confusion(.P2, 1);
1040
1130
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1041
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations.confusion);
1042
- try expectValue(true, chance.actions.p2.durations.thrash);
1131
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations_confusion);
1132
+ try expectValue(true, chance.actions.p2.durations_thrash);
1043
1133
 
1044
1134
  chance.reset();
1045
1135
  }
@@ -1051,19 +1141,19 @@ test "Chance.disable" {
1051
1141
  if (showdown) {
1052
1142
  for ([_]u8{ 1, 4, 3, 2, 1 }, 1..6) |d, i| {
1053
1143
  if (i > 1) {
1054
- chance.actions.p2.durations.disable = @intCast(i);
1144
+ chance.actions.p2.durations_disable = @intCast(i);
1055
1145
  try chance.disable(.P2, 0);
1056
1146
  try expectProbability(&chance.probability, 1, d);
1057
- try expectValue(@as(u4, 0), chance.actions.p2.durations.disable);
1147
+ try expectValue(0, chance.actions.p2.durations_disable);
1058
1148
 
1059
1149
  chance.reset();
1060
1150
  }
1061
1151
 
1062
1152
  if (i < 5) {
1063
- chance.actions.p2.durations.disable = @intCast(i);
1153
+ chance.actions.p2.durations_disable = @intCast(i);
1064
1154
  try chance.disable(.P2, 1);
1065
1155
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1066
- try expectValue(@as(u4, @intCast(i)) + 1, chance.actions.p2.durations.disable);
1156
+ try expectValue(@as(u4, @intCast(i)) + 1, chance.actions.p2.durations_disable);
1067
1157
 
1068
1158
  chance.reset();
1069
1159
  }
@@ -1071,19 +1161,19 @@ test "Chance.disable" {
1071
1161
  } else {
1072
1162
  for ([_]u8{ 1, 7, 6, 5, 4, 3, 2, 1 }, 1..9) |d, i| {
1073
1163
  if (i > 1) {
1074
- chance.actions.p2.durations.disable = @intCast(i);
1164
+ chance.actions.p2.durations_disable = @intCast(i);
1075
1165
  try chance.disable(.P2, 0);
1076
1166
  try expectProbability(&chance.probability, 1, d);
1077
- try expectValue(@as(u4, 0), chance.actions.p2.durations.disable);
1167
+ try expectValue(0, chance.actions.p2.durations_disable);
1078
1168
 
1079
1169
  chance.reset();
1080
1170
  }
1081
1171
 
1082
1172
  if (i < 8) {
1083
- chance.actions.p2.durations.disable = @intCast(i);
1173
+ chance.actions.p2.durations_disable = @intCast(i);
1084
1174
  try chance.disable(.P2, 1);
1085
1175
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1086
- try expectValue(@as(u4, @intCast(i)) + 1, chance.actions.p2.durations.disable);
1176
+ try expectValue(@as(u4, @intCast(i)) + 1, chance.actions.p2.durations_disable);
1087
1177
 
1088
1178
  chance.reset();
1089
1179
  }
@@ -1096,19 +1186,19 @@ test "Chance.attacking" {
1096
1186
 
1097
1187
  for ([_]u8{ 1, 2, 1 }, 1..4) |d, i| {
1098
1188
  if (i > 1) {
1099
- chance.actions.p2.durations.attacking = @intCast(i);
1189
+ chance.actions.p2.durations_attacking = @intCast(i);
1100
1190
  try chance.attacking(.P2, 0);
1101
1191
  try expectProbability(&chance.probability, 1, d);
1102
- try expectValue(@as(u3, 0), chance.actions.p2.durations.attacking);
1192
+ try expectValue(0, chance.actions.p2.durations_attacking);
1103
1193
 
1104
1194
  chance.reset();
1105
1195
  }
1106
1196
 
1107
1197
  if (i < 3) {
1108
- chance.actions.p2.durations.attacking = @intCast(i);
1198
+ chance.actions.p2.durations_attacking = @intCast(i);
1109
1199
  try chance.attacking(.P2, 1);
1110
1200
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1111
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations.attacking);
1201
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations_attacking);
1112
1202
 
1113
1203
  chance.reset();
1114
1204
  }
@@ -1120,19 +1210,19 @@ test "Chance.binding" {
1120
1210
 
1121
1211
  for ([_]u8{ 1, 4, 3, 2, 1 }, 1..6) |d, i| {
1122
1212
  if (i > 1) {
1123
- chance.actions.p2.durations.binding = @intCast(i);
1213
+ chance.actions.p2.durations_binding = @intCast(i);
1124
1214
  try chance.binding(.P2, 0);
1125
1215
  try expectProbability(&chance.probability, 1, d);
1126
- try expectValue(@as(u3, 0), chance.actions.p2.durations.binding);
1216
+ try expectValue(0, chance.actions.p2.durations_binding);
1127
1217
 
1128
1218
  chance.reset();
1129
1219
  }
1130
1220
 
1131
1221
  if (i < 5) {
1132
- chance.actions.p2.durations.binding = @intCast(i);
1222
+ chance.actions.p2.durations_binding = @intCast(i);
1133
1223
  try chance.binding(.P2, 1);
1134
1224
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1135
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations.binding);
1225
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations_binding);
1136
1226
 
1137
1227
  chance.reset();
1138
1228
  }
@@ -1144,19 +1234,19 @@ test "Chance.encore" {
1144
1234
 
1145
1235
  for ([_]u8{ 1, 4, 3, 2, 1 }, 1..6) |d, i| {
1146
1236
  if (i > 1) {
1147
- chance.actions.p2.durations.encore = @intCast(i);
1237
+ chance.actions.p2.durations_encore = @intCast(i);
1148
1238
  try chance.encore(.P2, 0);
1149
1239
  try expectProbability(&chance.probability, 1, d);
1150
- try expectValue(@as(u3, 0), chance.actions.p2.durations.encore);
1240
+ try expectValue(0, chance.actions.p2.durations_encore);
1151
1241
 
1152
1242
  chance.reset();
1153
1243
  }
1154
1244
 
1155
1245
  if (i < 5) {
1156
- chance.actions.p2.durations.encore = @intCast(i);
1246
+ chance.actions.p2.durations_encore = @intCast(i);
1157
1247
  try chance.encore(.P2, 1);
1158
1248
  try expectProbability(&chance.probability, if (d > 1) d - 1 else d, d);
1159
- try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations.encore);
1249
+ try expectValue(@as(u3, @intCast(i)) + 1, chance.actions.p2.durations_encore);
1160
1250
 
1161
1251
  chance.reset();
1162
1252
  }