@pkmn/engine 0.1.0-dev.028ab165 → 0.1.0-dev.047d6e71

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.
@@ -3,8 +3,8 @@ const builtin = @import("builtin");
3
3
 
4
4
  const pkmn = @import("../pkmn.zig");
5
5
 
6
- const data = @import("./data.zig");
7
- const options = @import("./options.zig");
6
+ const data = @import("data.zig");
7
+ const options = @import("options.zig");
8
8
 
9
9
  const assert = std.debug.assert;
10
10
  const print = std.debug.print;
@@ -14,6 +14,8 @@ const enabled = options.log;
14
14
  const Player = data.Player;
15
15
  const ID = data.ID;
16
16
 
17
+ const endian = builtin.cpu.arch.endian();
18
+
17
19
  pub const ArgType = enum(u8) {
18
20
  None,
19
21
 
@@ -71,7 +73,7 @@ pub const ArgType = enum(u8) {
71
73
  EndAbility,
72
74
  ClearNegativeBoost,
73
75
  FormeChange,
74
- NoTarget,
76
+ LastNoTarget, // FIXME
75
77
 
76
78
  // Gen 4
77
79
  SwapBoost,
@@ -218,6 +220,7 @@ pub const Activate = enum(u8) {
218
220
  BeatUp, // FIXME of
219
221
 
220
222
  Magnitude,
223
+ Spite,
221
224
  };
222
225
 
223
226
  pub const Start = enum(u8) {
@@ -359,8 +362,8 @@ pub fn Log(comptime Writer: type) type {
359
362
  } else {
360
363
  try self.writer.writeAll(&.{ @intFromEnum(args[1].species), args[1].level });
361
364
  }
362
- try self.writer.writeIntNative(u16, args[1].hp);
363
- try self.writer.writeIntNative(u16, args[1].stats.hp);
365
+ try self.writer.writeInt(u16, args[1].hp, endian);
366
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
364
367
  try self.writer.writeAll(&.{args[1].status});
365
368
  }
366
369
 
@@ -391,7 +394,7 @@ pub fn Log(comptime Writer: type) type {
391
394
  if (!enabled) return;
392
395
 
393
396
  try self.writer.writeByte(@intFromEnum(ArgType.Turn));
394
- try self.writer.writeIntNative(u16, args[0]);
397
+ try self.writer.writeInt(u16, args[0], endian);
395
398
  try self.writer.writeByte(@intFromEnum(ArgType.None));
396
399
  }
397
400
 
@@ -423,8 +426,8 @@ pub fn Log(comptime Writer: type) type {
423
426
  @intFromEnum(ArgType.Damage),
424
427
  @as(u8, @bitCast(args[0])),
425
428
  });
426
- try self.writer.writeIntNative(u16, args[1].hp);
427
- try self.writer.writeIntNative(u16, args[1].stats.hp);
429
+ try self.writer.writeInt(u16, args[1].hp, endian);
430
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
428
431
  try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Damage, args[2])) });
429
432
  if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
430
433
  }
@@ -436,8 +439,8 @@ pub fn Log(comptime Writer: type) type {
436
439
 
437
440
  assert(args[2] != .Drain or args.len == 4);
438
441
  try self.writer.writeAll(&.{ @intFromEnum(ArgType.Heal), @as(u8, @bitCast(args[0])) });
439
- try self.writer.writeIntNative(u16, args[1].hp);
440
- try self.writer.writeIntNative(u16, args[1].stats.hp);
442
+ try self.writer.writeInt(u16, args[1].hp, endian);
443
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
441
444
  try self.writer.writeAll(&.{ args[1].status, @intFromEnum(@as(Heal, args[2])) });
442
445
  if (args.len == 4) try self.writer.writeByte(@as(u8, @bitCast(args[3])));
443
446
  }
@@ -542,6 +545,7 @@ pub fn Log(comptime Writer: type) type {
542
545
  // ident: ID, reason: Activate
543
546
  // ident: ID, reason: .SubstituteBlock, m: <Move>
544
547
  // ident: ID, reason: .Magnitude, num: u8
548
+ // ident: ID, reason: .Spite, m: <Move>, num: u8
545
549
  pub fn activate(self: Self, args: anytype) Error!void {
546
550
  if (!enabled) return;
547
551
 
@@ -559,6 +563,9 @@ pub fn Log(comptime Writer: type) type {
559
563
  assert(reason == .Magnitude);
560
564
  try self.writer.writeByte(args[2]);
561
565
  }
566
+ } else if (args.len == 4) {
567
+ assert(reason == .Spite);
568
+ try self.writer.writeAll(&.{ @intFromEnum(args[2]), args[3] });
562
569
  }
563
570
  }
564
571
 
@@ -706,8 +713,8 @@ pub fn Log(comptime Writer: type) type {
706
713
  if (!enabled) return;
707
714
 
708
715
  try self.writer.writeAll(&.{ @intFromEnum(ArgType.SetHP), @as(u8, @bitCast(args[0])) });
709
- try self.writer.writeIntNative(u16, args[1].hp);
710
- try self.writer.writeIntNative(u16, args[1].stats.hp);
716
+ try self.writer.writeInt(u16, args[1].hp, endian);
717
+ try self.writer.writeInt(u16, args[1].stats.hp, endian);
711
718
  try self.writer.writeAll(&.{args[1].status});
712
719
  try self.writer.writeByte(@intFromEnum(@as(SetHP, args[2])));
713
720
  }
@@ -831,10 +838,10 @@ pub const ByteStream = struct {
831
838
  try self.stream.writeByte(byte);
832
839
  }
833
840
 
834
- pub fn writeIntNative(self: Writer, comptime T: type, value: T) Error!void {
841
+ pub fn writeInt(self: Writer, comptime T: type, v: T, end: std.builtin.Endian) Error!void {
835
842
  // TODO: rework this to write directly to the buffer?
836
- var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
837
- std.mem.writeIntNative(T, &bytes, value);
843
+ var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
844
+ std.mem.writeInt(std.math.ByteAlignedInt(@TypeOf(v)), &bytes, v, end);
838
845
  return self.writeAll(&bytes);
839
846
  }
840
847
  };
@@ -943,19 +950,19 @@ pub fn format(
943
950
  if (a[i] == N(gen.Gender.Unknown)) {
944
951
  i += 1;
945
952
  } else {
946
- var gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
953
+ const gender = if (a[i] == N(gen.Gender.Male)) "M" else "F";
947
954
  printc(", {s}", .{gender}, a, b, &i, 1, color);
948
955
  }
949
956
  }
950
957
  printc(" L{d}", .{a[i]}, a, b, &i, 1, color);
951
958
  switch (endian) {
952
- .Big => {
959
+ .big => {
953
960
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
954
961
  printc(" {d}", .{hp}, a, b, &i, 2, color);
955
962
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
956
963
  printc("/{d}", .{hp}, a, b, &i, 2, color);
957
964
  },
958
- .Little => {
965
+ .little => {
959
966
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
960
967
  printc(" {d}", .{hp}, a, b, &i, 2, color);
961
968
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -986,8 +993,8 @@ pub fn format(
986
993
  },
987
994
  .Turn => {
988
995
  const turn = switch (endian) {
989
- .Big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
990
- .Little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
996
+ .big => @as(u16, a[i]) << 8 | @as(u16, a[i + 1]),
997
+ .little => @as(u16, a[i + 1]) << 8 | @as(u16, a[i]),
991
998
  };
992
999
  printc(" {d}", .{turn}, a, b, &i, 2, color);
993
1000
  },
@@ -998,13 +1005,13 @@ pub fn format(
998
1005
  var id = ID.from(@intCast(a[i]));
999
1006
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1000
1007
  switch (endian) {
1001
- .Big => {
1008
+ .big => {
1002
1009
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1003
1010
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1004
1011
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1005
1012
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1006
1013
  },
1007
- .Little => {
1014
+ .little => {
1008
1015
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1009
1016
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1010
1017
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1126,13 +1133,13 @@ pub fn format(
1126
1133
  const id = ID.from(@intCast(a[i]));
1127
1134
  printc(" {s}({d})", .{ @tagName(id.player), id.id }, a, b, &i, 1, color);
1128
1135
  switch (endian) {
1129
- .Big => {
1136
+ .big => {
1130
1137
  var hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1131
1138
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1132
1139
  hp = @as(u16, a[i]) << 8 | @as(u16, a[i + 1]);
1133
1140
  printc("/{d}", .{hp}, a, b, &i, 2, color);
1134
1141
  },
1135
- .Little => {
1142
+ .little => {
1136
1143
  var hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
1137
1144
  printc(" {d}", .{hp}, a, b, &i, 2, color);
1138
1145
  hp = @as(u16, a[i + 1]) << 8 | @as(u16, a[i]);
@@ -1200,14 +1207,11 @@ pub fn expectLog(
1200
1207
  ) !void {
1201
1208
  if (!enabled) return;
1202
1209
 
1203
- const color = color: {
1204
- if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR")) {
1205
- break :color true;
1206
- } else if (std.process.hasEnvVarConstant("NO_COLOR")) {
1207
- break :color false;
1208
- } else {
1209
- break :color std.io.getStdErr().supportsAnsiEscapeCodes();
1210
- }
1210
+ const color = if (std.process.hasEnvVarConstant("ZIG_DEBUG_COLOR"))
1211
+ true
1212
+ else switch (std.io.tty.detectConfig(std.io.getStdErr())) {
1213
+ .escape_codes => true,
1214
+ else => false,
1211
1215
  };
1212
1216
 
1213
1217
  expectEqualBytes(expected, actual, offset) catch |err| switch (err) {
@@ -1239,8 +1243,6 @@ fn expectEqualBytes(expected: []const u8, actual: []const u8, offset: usize) !vo
1239
1243
  }
1240
1244
  }
1241
1245
 
1242
- const endian = builtin.target.cpu.arch.endian();
1243
-
1244
1246
  fn N(e: anytype) u8 {
1245
1247
  return @intFromEnum(e);
1246
1248
  }
@@ -1248,20 +1250,13 @@ fn N(e: anytype) u8 {
1248
1250
  const p1 = Player.P1;
1249
1251
  const p2 = Player.P2;
1250
1252
 
1251
- const gen1 = struct {
1252
- pub usingnamespace @import("../gen1/data.zig");
1253
- pub const helpers = @import("../gen1/helpers.zig");
1254
- };
1255
-
1256
- const gen2 = struct {
1257
- pub usingnamespace @import("../gen2/data.zig");
1258
- pub const helpers = @import("../gen2/helpers.zig");
1259
- };
1260
-
1261
1253
  var buf: [pkmn.LOGS_SIZE]u8 = undefined;
1262
1254
  var stream: ByteStream = .{ .buffer = &buf };
1263
1255
  var log: FixedLog = .{ .writer = stream.writer() };
1264
1256
 
1257
+ const gen1 = pkmn.gen1;
1258
+ const gen2 = pkmn.gen2;
1259
+
1265
1260
  const M1 = gen1.Move;
1266
1261
  const S1 = gen1.Species;
1267
1262
 
@@ -1350,8 +1345,8 @@ test "|switch|" {
1350
1345
  try log.switched(.{ p2.ident(3), &snorlax });
1351
1346
  const par = 0b1000000;
1352
1347
  var expected: []const u8 = switch (endian) {
1353
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1354
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1348
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 0, 200, 1, 144, par },
1349
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 91, 200, 0, 144, 1, par },
1355
1350
  };
1356
1351
  try expectLog1(expected, buf[0..9]);
1357
1352
  stream.reset();
@@ -1361,8 +1356,8 @@ test "|switch|" {
1361
1356
  snorlax.status = 0;
1362
1357
  try log.switched(.{ p2.ident(3), &snorlax });
1363
1358
  expected = switch (endian) {
1364
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1365
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1359
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 1, 144, 0 },
1360
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 0, 0, 144, 1, 0 },
1366
1361
  };
1367
1362
  try expectLog1(expected, buf[0..9]);
1368
1363
  stream.reset();
@@ -1370,8 +1365,8 @@ test "|switch|" {
1370
1365
  snorlax.hp = 400;
1371
1366
  try log.switched(.{ p2.ident(3), &snorlax });
1372
1367
  expected = switch (endian) {
1373
- .Big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1374
- .Little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1368
+ .big => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 1, 144, 1, 144, 0 },
1369
+ .little => &.{ N(ArgType.Switch), 0b1011, N(S1.Snorlax), 100, 144, 1, 144, 1, 0 },
1375
1370
  };
1376
1371
  try expectLog1(expected, buf[0..9]);
1377
1372
  stream.reset();
@@ -1389,8 +1384,8 @@ test "|switch|" {
1389
1384
  N(gen2.Gender.Female),
1390
1385
  91,
1391
1386
  } ++ switch (endian) {
1392
- .Big => .{ 0, 200, 1, 144, par },
1393
- .Little => .{ 200, 0, 144, 1, par },
1387
+ .big => .{ 0, 200, 1, 144, par },
1388
+ .little => .{ 200, 0, 144, 1, par },
1394
1389
  });
1395
1390
  try expectLog2(expected, buf[0..10]);
1396
1391
  stream.reset();
@@ -1418,9 +1413,9 @@ test "|faint|" {
1418
1413
 
1419
1414
  test "|turn|" {
1420
1415
  try log.turn(.{42});
1421
- var expected = switch (endian) {
1422
- .Big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1423
- .Little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1416
+ const expected = switch (endian) {
1417
+ .big => &.{ N(ArgType.Turn), 0, 42, N(ArgType.None) },
1418
+ .little => &.{ N(ArgType.Turn), 42, 0, N(ArgType.None) },
1424
1419
  };
1425
1420
  try expectLog1(expected, buf[0..4]);
1426
1421
  stream.reset();
@@ -1444,8 +1439,8 @@ test "|-damage|" {
1444
1439
  chansey.status = gen1.Status.slp(1);
1445
1440
  try log.damage(.{ p2.ident(2), &chansey, .None });
1446
1441
  var expected: []const u8 = switch (endian) {
1447
- .Big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1448
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1442
+ .big => &.{ N(ArgType.Damage), 0b1010, 2, 100, 2, 191, 1, N(Damage.None) },
1443
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 2, 191, 2, 1, N(Damage.None) },
1449
1444
  };
1450
1445
  try expectLog1(expected, buf[0..8]);
1451
1446
  stream.reset();
@@ -1455,8 +1450,8 @@ test "|-damage|" {
1455
1450
  chansey.status = 0;
1456
1451
  try log.damage(.{ p2.ident(2), &chansey, .Confusion });
1457
1452
  expected = switch (endian) {
1458
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1459
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1453
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0, N(Damage.Confusion) },
1454
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0, N(Damage.Confusion) },
1460
1455
  };
1461
1456
  try expectLog1(expected, buf[0..8]);
1462
1457
  stream.reset();
@@ -1464,8 +1459,8 @@ test "|-damage|" {
1464
1459
  chansey.status = gen1.Status.init(.PSN);
1465
1460
  try log.damage(.{ p2.ident(2), &chansey, .RecoilOf, p1.ident(1) });
1466
1461
  expected = switch (endian) {
1467
- .Big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1468
- .Little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1462
+ .big => &.{ N(ArgType.Damage), 0b1010, 0, 100, 1, 0, 0b1000, N(Damage.RecoilOf), 1 },
1463
+ .little => &.{ N(ArgType.Damage), 0b1010, 100, 0, 0, 1, 0b1000, N(Damage.RecoilOf), 1 },
1469
1464
  };
1470
1465
  try expectLog1(expected, buf[0..9]);
1471
1466
  stream.reset();
@@ -1477,8 +1472,8 @@ test "|-heal|" {
1477
1472
  chansey.status = gen1.Status.slp(1);
1478
1473
  try log.heal(.{ p2.ident(2), &chansey, .None });
1479
1474
  var expected: []const u8 = switch (endian) {
1480
- .Big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1481
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1475
+ .big => &.{ N(ArgType.Heal), 0b1010, 2, 100, 2, 191, 1, N(Heal.None) },
1476
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 2, 191, 2, 1, N(Heal.None) },
1482
1477
  };
1483
1478
  try expectLog1(expected, buf[0..8]);
1484
1479
  stream.reset();
@@ -1488,16 +1483,16 @@ test "|-heal|" {
1488
1483
  chansey.status = 0;
1489
1484
  try log.heal(.{ p2.ident(2), &chansey, .Silent });
1490
1485
  expected = switch (endian) {
1491
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1492
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1486
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Silent) },
1487
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Silent) },
1493
1488
  };
1494
1489
  try expectLog1(expected, buf[0..8]);
1495
1490
  stream.reset();
1496
1491
 
1497
1492
  try log.heal(.{ p2.ident(2), &chansey, .Drain, p1.ident(1) });
1498
1493
  expected = switch (endian) {
1499
- .Big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1500
- .Little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1494
+ .big => &.{ N(ArgType.Heal), 0b1010, 0, 100, 1, 0, 0, N(Heal.Drain), 1 },
1495
+ .little => &.{ N(ArgType.Heal), 0b1010, 100, 0, 0, 1, 0, N(Heal.Drain), 1 },
1501
1496
  };
1502
1497
  try expectLog1(expected, buf[0..9]);
1503
1498
  stream.reset();
@@ -1740,8 +1735,8 @@ test "|drag|" {
1740
1735
  N(gen2.Gender.Female),
1741
1736
  91,
1742
1737
  } ++ switch (endian) {
1743
- .Big => .{ 0, 200, 1, 144, par },
1744
- .Little => .{ 200, 0, 144, 1, par },
1738
+ .big => .{ 0, 200, 1, 144, par },
1739
+ .little => .{ 200, 0, 144, 1, par },
1745
1740
  });
1746
1741
  try expectLog2(expected, buf[0..10]);
1747
1742
  stream.reset();
@@ -1773,9 +1768,9 @@ test "|-sethp|" {
1773
1768
  var blissey = gen2.helpers.Pokemon.init(.{ .species = .Blissey, .moves = &.{.PainSplit} });
1774
1769
  blissey.hp = 612;
1775
1770
  try log.sethp(.{ p2.ident(2), &blissey, .Silent });
1776
- var expected: []const u8 = switch (endian) {
1777
- .Big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1778
- .Little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1771
+ const expected: []const u8 = switch (endian) {
1772
+ .big => &.{ N(ArgType.SetHP), 0b1010, 2, 100, 2, 201, 0, N(SetHP.Silent) },
1773
+ .little => &.{ N(ArgType.SetHP), 0b1010, 100, 2, 201, 2, 0, N(SetHP.Silent) },
1779
1774
  };
1780
1775
  try expectLog2(expected, buf[0..8]);
1781
1776
  stream.reset();
@@ -192,9 +192,9 @@ pub fn Rational(comptime T: type) type {
192
192
 
193
193
  fn addition(r: *Self, p: anytype, q: anytype) !void {
194
194
  // (a/b) + (c/d) = (ad+bc)/(bd)
195
- var d = try std.math.mul(T, r.q, q);
196
- var n1 = try std.math.mul(T, r.p, q);
197
- var n2 = try std.math.mul(T, r.q, p);
195
+ const d = try std.math.mul(T, r.q, q);
196
+ const n1 = try std.math.mul(T, r.p, q);
197
+ const n2 = try std.math.mul(T, r.q, p);
198
198
 
199
199
  r.p = try std.math.add(T, n1, n2);
200
200
  r.q = d;
@@ -234,6 +234,8 @@ test Rational {
234
234
  var r: Rational(t) = .{};
235
235
 
236
236
  var c: t = 128;
237
+ _ = &c;
238
+
237
239
  try r.update(c, 256);
238
240
  try doTurn(&r);
239
241
 
@@ -320,6 +322,8 @@ test BigRational {
320
322
  try r.reset();
321
323
 
322
324
  var c: u8 = 128;
325
+ _ = &c;
326
+
323
327
  try r.update(c, 256);
324
328
  try doTurn(&r);
325
329
 
@@ -1,6 +1,6 @@
1
1
  const std = @import("std");
2
2
 
3
- const options = @import("./options.zig");
3
+ const options = @import("options.zig");
4
4
 
5
5
  const assert = std.debug.assert;
6
6
  const expectEqual = std.testing.expectEqual;
@@ -66,11 +66,15 @@ pub const PSRNG = extern struct {
66
66
  (@as(u64, self.range(u16, 0, 0x10000)) << 16) |
67
67
  (@as(u64, self.range(u16, 0, 0x10000)));
68
68
  }
69
+
70
+ pub fn Bound(comptime T: type) type {
71
+ return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
72
+ }
69
73
  };
70
74
 
71
75
  test PSRNG {
72
76
  var psrng: PSRNG = .{ .src = .{ .seed = 0x0001000200030004 } };
73
- try expectEqual(@as(u8, 121), psrng.range(u8, 0, 256));
77
+ try expectEqual(121, psrng.range(u8, 0, 256));
74
78
  try expectEqual(false, psrng.chance(u8, 128, 256)); // 226 < 128
75
79
  }
76
80
 
@@ -107,9 +111,9 @@ test Gen12 {
107
111
  try expectEqual(e, rng.next());
108
112
  }
109
113
 
110
- try expectEqual(@as(u8, 16), Gen12.percent(6) + 1);
111
- try expectEqual(@as(u8, 16), Gen12.percent(7) - 1);
112
- try expectEqual(@as(u8, 128), Gen12.percent(50) + 1);
114
+ try expectEqual(16, Gen12.percent(6) + 1);
115
+ try expectEqual(16, Gen12.percent(7) - 1);
116
+ try expectEqual(128, Gen12.percent(50) + 1);
113
117
  }
114
118
 
115
119
  // https://pkmn.cc/pokeemerald/src/random.c
@@ -197,7 +201,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
197
201
  for (0..n) |_| _ = self.next();
198
202
  }
199
203
 
200
- pub fn range(self: *Self, comptime T: type, from: T, to: Bound(T)) T {
204
+ pub fn range(self: *Self, comptime T: type, from: T, to: PSRNG.Bound(T)) T {
201
205
  assert(showdown);
202
206
  return @intCast(@as(u64, self.next()) * (to - from) / divisor + from);
203
207
  }
@@ -206,7 +210,7 @@ pub fn FixedRNG(comptime gen: comptime_int, comptime len: usize) type {
206
210
  self: *Self,
207
211
  comptime T: type,
208
212
  numerator: T,
209
- denominator: Bound(T),
213
+ denominator: PSRNG.Bound(T),
210
214
  ) bool {
211
215
  assert(showdown);
212
216
  assert(denominator > 0);
@@ -237,7 +241,3 @@ fn Output(comptime gen: comptime_int) type {
237
241
  else => unreachable,
238
242
  };
239
243
  }
240
-
241
- fn Bound(comptime T: type) type {
242
- return std.math.IntFittingRange(0, std.math.maxInt(T) + 1);
243
- }
@@ -211,8 +211,8 @@ pub fn transitions(
211
211
  ) !?Stats {
212
212
  var stats: Stats = .{};
213
213
 
214
- var actions = options.actions;
215
- var cap = options.cap;
214
+ const actions = options.actions;
215
+ const cap = options.cap;
216
216
 
217
217
  var seen = std.AutoHashMap(Actions, void).init(allocator);
218
218
  defer seen.deinit();
@@ -232,8 +232,8 @@ pub fn transitions(
232
232
  _ = try b.update(c1, c2, &opts);
233
233
  stats.updates += 1;
234
234
 
235
- var p1 = b.side(.P1);
236
- var p2 = b.side(.P2);
235
+ const p1 = b.side(.P1);
236
+ const p2 = b.side(.P2);
237
237
 
238
238
  var p: Rational(u128) = .{ .p = 0, .q = 1 };
239
239
  try frontier.append(opts.chance.actions);
@@ -247,7 +247,7 @@ pub fn transitions(
247
247
  var i: usize = 0;
248
248
  assert(frontier.items.len == 1);
249
249
  while (i < frontier.items.len) : (i += 1) {
250
- var template = frontier.items[i];
250
+ const template = frontier.items[i];
251
251
  opts.calc.overrides.durations = .{
252
252
  .p1 = template.p1.durations,
253
253
  .p2 = template.p2.durations,
@@ -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;
@@ -706,19 +706,19 @@ test "Chance.damage" {
706
706
 
707
707
  try chance.damage(.P1, 217);
708
708
  if (showdown) {
709
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
709
+ try expectValue(217, chance.actions.p1.damage);
710
710
  try expectProbability(&chance.probability, 1, 39);
711
711
  } else {
712
712
  try expectProbability(&chance.probability, 1, 1);
713
- try expectValue(@as(u8, 0), chance.actions.p1.damage);
713
+ try expectValue(0, chance.actions.p1.damage);
714
714
 
715
715
  try chance.commit(.P1, .miss);
716
716
  try expectProbability(&chance.probability, 1, 1);
717
- try expectValue(@as(u8, 0), chance.actions.p1.damage);
717
+ try expectValue(0, chance.actions.p1.damage);
718
718
 
719
719
  try chance.commit(.P1, .hit);
720
720
  try expectProbability(&chance.probability, 1, 39);
721
- try expectValue(@as(u8, 217), chance.actions.p1.damage);
721
+ try expectValue(217, chance.actions.p1.damage);
722
722
  }
723
723
  }
724
724
 
@@ -770,13 +770,13 @@ test "Chance.moveSlot" {
770
770
 
771
771
  try chance.moveSlot(.P2, 2, &ms, 2);
772
772
  try expectProbability(&chance.probability, 1, 2);
773
- try expectValue(@as(u4, 2), chance.actions.p2.move_slot);
773
+ try expectValue(2, chance.actions.p2.move_slot);
774
774
 
775
775
  chance.reset();
776
776
 
777
777
  try chance.moveSlot(.P1, 1, &ms, 0);
778
778
  try expectProbability(&chance.probability, 1, 3);
779
- try expectValue(@as(u4, 1), chance.actions.p1.move_slot);
779
+ try expectValue(1, chance.actions.p1.move_slot);
780
780
  }
781
781
 
782
782
  test "Chance.multiHit" {
@@ -784,32 +784,32 @@ test "Chance.multiHit" {
784
784
 
785
785
  try chance.multiHit(.P1, 3);
786
786
  try expectProbability(&chance.probability, 3, 8);
787
- try expectValue(@as(u4, 3), chance.actions.p1.multi_hit);
787
+ try expectValue(3, chance.actions.p1.multi_hit);
788
788
 
789
789
  chance.reset();
790
790
 
791
791
  try chance.multiHit(.P2, 5);
792
792
  try expectProbability(&chance.probability, 1, 8);
793
- try expectValue(@as(u4, 5), chance.actions.p2.multi_hit);
793
+ try expectValue(5, chance.actions.p2.multi_hit);
794
794
  }
795
795
 
796
796
  test "Chance.duration" {
797
797
  var chance: Chance(rational.Rational(u64)) = .{ .probability = .{} };
798
798
 
799
799
  chance.duration(.sleep, .P1, .P2, 2);
800
- try expectValue(@as(u4, 2), chance.actions.p1.duration);
801
- try expectValue(@as(u3, 1), chance.actions.p2.durations.sleep);
800
+ try expectValue(2, chance.actions.p1.duration);
801
+ try expectValue(1, chance.actions.p2.durations.sleep);
802
802
 
803
803
  chance.reset();
804
804
 
805
805
  chance.duration(.binding, .P2, .P2, 4);
806
806
  if (!showdown) {
807
- try expectValue(@as(u4, 0), chance.actions.p2.duration);
808
- try expectValue(@as(u3, 0), chance.actions.p2.durations.binding);
807
+ try expectValue(0, chance.actions.p2.duration);
808
+ try expectValue(0, chance.actions.p2.durations.binding);
809
809
  try chance.commit(.P2, .hit);
810
810
  }
811
- try expectValue(@as(u4, 4), chance.actions.p2.duration);
812
- try expectValue(@as(u3, 1), chance.actions.p2.durations.binding);
811
+ try expectValue(4, chance.actions.p2.duration);
812
+ try expectValue(1, chance.actions.p2.durations.binding);
813
813
  }
814
814
 
815
815
  test "Chance.sleep" {
@@ -819,7 +819,7 @@ test "Chance.sleep" {
819
819
  chance.actions.p1.durations.sleep = @intCast(i);
820
820
  try chance.sleep(.P1, 0);
821
821
  try expectProbability(&chance.probability, 1, d);
822
- try expectValue(@as(u3, 0), chance.actions.p1.durations.sleep);
822
+ try expectValue(0, chance.actions.p1.durations.sleep);
823
823
 
824
824
  chance.reset();
825
825
 
@@ -842,7 +842,7 @@ test "Chance.confusion" {
842
842
  chance.actions.p2.durations.confusion = @intCast(i);
843
843
  try chance.confusion(.P2, 0);
844
844
  try expectProbability(&chance.probability, 1, d);
845
- try expectValue(@as(u3, 0), chance.actions.p2.durations.confusion);
845
+ try expectValue(0, chance.actions.p2.durations.confusion);
846
846
 
847
847
  chance.reset();
848
848
  }
@@ -865,7 +865,7 @@ test "Chance.disable" {
865
865
  chance.actions.p1.durations.disable = @intCast(i);
866
866
  try chance.disable(.P1, 0);
867
867
  try expectProbability(&chance.probability, 1, d);
868
- try expectValue(@as(u4, 0), chance.actions.p1.durations.disable);
868
+ try expectValue(0, chance.actions.p1.durations.disable);
869
869
 
870
870
  chance.reset();
871
871
 
@@ -888,7 +888,7 @@ test "Chance.attacking" {
888
888
  chance.actions.p2.durations.attacking = @intCast(i);
889
889
  try chance.attacking(.P2, 0);
890
890
  try expectProbability(&chance.probability, 1, d);
891
- try expectValue(@as(u3, 0), chance.actions.p2.durations.attacking);
891
+ try expectValue(0, chance.actions.p2.durations.attacking);
892
892
 
893
893
  chance.reset();
894
894
  }
@@ -914,7 +914,7 @@ test "Chance.binding" {
914
914
  chance.actions.p1.durations.binding = @intCast(i);
915
915
  try chance.binding(.P1, 0);
916
916
  try expectProbability(&chance.probability, p, q);
917
- try expectValue(@as(u3, 0), chance.actions.p1.durations.binding);
917
+ try expectValue(0, chance.actions.p1.durations.binding);
918
918
 
919
919
  chance.reset();
920
920
 
@@ -934,7 +934,7 @@ test "Chance.psywave" {
934
934
 
935
935
  try chance.psywave(.P2, 100, 150);
936
936
  try expectProbability(&chance.probability, 1, 150);
937
- try expectValue(@as(u8, 101), chance.actions.p2.psywave);
937
+ try expectValue(101, chance.actions.p2.psywave);
938
938
  }
939
939
 
940
940
  test "Chance.metronome" {
@@ -1091,7 +1091,7 @@ pub const Species = enum(u8) {
1091
1091
  /// The number of Pokémon species in this generation.
1092
1092
  pub const size = 151;
1093
1093
 
1094
- /// The Pokémon's critical hit rate=io out of 256.
1094
+ /// The Pokémon's critical hit ratio out of 256.
1095
1095
  pub fn chance(id: Species) u8 {
1096
1096
  assert(id != .None);
1097
1097
  return CHANCES[@intFromEnum(id) - 1];