@pkmn/engine 0.1.0-dev.b3197aa3 → 0.1.0-dev.b396399c
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 +17 -53
- package/build/pkg/addon/wasm.js.map +1 -1
- package/build/pkg/addon.d.ts +4 -4
- package/build/pkg/addon.js.map +1 -1
- package/build/pkg/data.js.map +1 -1
- package/build/pkg/gen1.js.map +1 -1
- package/build/pkg/protocol.d.ts +11 -2
- package/build/pkg/protocol.js.map +1 -1
- package/build/tools/debug.js +37 -3
- package/build/tools/debug.js.map +1 -1
- package/build/tools/display/debug.jsx +1 -87
- package/build/tools/display/debug.jsx.map +1 -1
- package/build/tools/display/ui.jsx +3 -2
- package/build/tools/display/ui.jsx.map +1 -1
- package/build/tools/display/util.js +125 -1
- package/build/tools/display/util.js.map +1 -1
- package/build.zig +141 -232
- package/package.json +22 -21
- package/src/bin/install-pkmn-engine +22 -7
- package/src/lib/bindings/c.zig +27 -82
- package/src/lib/bindings/node.zig +7 -7
- package/src/lib/bindings/wasm.zig +6 -15
- package/src/lib/common/array.zig +5 -12
- package/src/lib/common/debug.zig +33 -59
- package/src/lib/common/js.zig +3 -5
- package/src/lib/common/optional.zig +11 -21
- package/src/lib/common/protocol.zig +224 -189
- package/src/lib/common/rational.zig +18 -38
- package/src/lib/common/util.zig +14 -46
- package/src/lib/gen1/calc.zig +121 -108
- package/src/lib/gen1/chance.zig +112 -75
- package/src/lib/gen1/data/types.zig +1 -1
- package/src/lib/gen1/data.zig +5 -5
- package/src/lib/gen1/helpers.zig +8 -10
- package/src/lib/gen1/mechanics.zig +31 -31
- package/src/lib/gen2/calc.zig +3 -6
- package/src/lib/gen2/chance.zig +12 -18
- package/src/lib/gen2/data.zig +5 -5
- package/src/lib/gen2/helpers.zig +4 -6
- package/src/lib/gen2/mechanics.zig +16 -16
- package/src/lib/napi.h +2 -0
- package/src/lib/node.zig +1 -1
- package/src/lib/pkmn.zig +91 -17
- package/src/lib/wasm.zig +2 -6
- package/src/tools/display/dom.ts +40 -25
- package/src/lib/common/napi.zig +0 -4
|
@@ -6,13 +6,6 @@ const expect = std.testing.expect;
|
|
|
6
6
|
const expectEqual = std.testing.expectEqual;
|
|
7
7
|
const expectError = std.testing.expectError;
|
|
8
8
|
|
|
9
|
-
const Int = if (@hasField(std.builtin.Type, "int")) .int else .Int;
|
|
10
|
-
const Float = if (@hasField(std.builtin.Type, "float")) .float else .Float;
|
|
11
|
-
const ComptimeInt =
|
|
12
|
-
if (@hasField(std.builtin.Type, "comptime_int")) .comptime_int else .ComptimeInt;
|
|
13
|
-
const ComptimeFloat =
|
|
14
|
-
if (@hasField(std.builtin.Type, "comptime_float")) .comptime_float else .ComptimeFloat;
|
|
15
|
-
|
|
16
9
|
/// Specialization of a rational number used by the engine to compute probabilties.
|
|
17
10
|
/// For performance reasons the rational is only reduced lazily and thus `reduce` must be
|
|
18
11
|
/// invoked explicitly before reading. Note that this laziness means that this implementation
|
|
@@ -23,14 +16,14 @@ pub fn Rational(comptime T: type) type {
|
|
|
23
16
|
// instead start reducing when we get sufficiently close to the limit of the mantissa
|
|
24
17
|
// (in our domain we expect updates to involve numbers < 2**10, so we should be safe
|
|
25
18
|
// not reducing before we are 2**10 away from "overflowing" the mantissa)
|
|
26
|
-
const o = if (@typeInfo(T) ==
|
|
19
|
+
const o = if (@typeInfo(T) == .float)
|
|
27
20
|
std.math.pow(T, 2, std.math.floatMantissaBits(T) - 10)
|
|
28
21
|
else
|
|
29
22
|
0;
|
|
30
23
|
|
|
31
24
|
const Err = switch (@typeInfo(T)) {
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
.int => error{Overflow},
|
|
26
|
+
.float => error{},
|
|
34
27
|
else => unreachable,
|
|
35
28
|
};
|
|
36
29
|
|
|
@@ -78,13 +71,7 @@ pub fn Rational(comptime T: type) type {
|
|
|
78
71
|
reduce_(r);
|
|
79
72
|
}
|
|
80
73
|
|
|
81
|
-
pub fn format(
|
|
82
|
-
self: Self,
|
|
83
|
-
comptime fmt: []const u8,
|
|
84
|
-
opts: std.fmt.FormatOptions,
|
|
85
|
-
writer: anytype,
|
|
86
|
-
) !void {
|
|
87
|
-
_ = .{ fmt, opts };
|
|
74
|
+
pub fn format(self: Self, writer: *std.Io.Writer) !void {
|
|
88
75
|
try writer.print("{d}/{d}", .{ self.p, self.q });
|
|
89
76
|
}
|
|
90
77
|
} else struct {
|
|
@@ -130,13 +117,7 @@ pub fn Rational(comptime T: type) type {
|
|
|
130
117
|
reduce_(r);
|
|
131
118
|
}
|
|
132
119
|
|
|
133
|
-
pub fn format(
|
|
134
|
-
self: Self,
|
|
135
|
-
comptime fmt: []const u8,
|
|
136
|
-
opts: std.fmt.FormatOptions,
|
|
137
|
-
writer: anytype,
|
|
138
|
-
) !void {
|
|
139
|
-
_ = .{ fmt, opts };
|
|
120
|
+
pub fn format(self: Self, writer: *std.Io.Writer) !void {
|
|
140
121
|
try writer.print("{d}/{d}", .{ self.p, self.q });
|
|
141
122
|
}
|
|
142
123
|
};
|
|
@@ -150,12 +131,12 @@ fn update_(comptime T: type, comptime o: comptime_int, r: anytype, p: anytype, q
|
|
|
150
131
|
// If our parameters are not fully reduced they may prematurely
|
|
151
132
|
// cause overflow/loss of precision after the multiplication below
|
|
152
133
|
assert(switch (@typeInfo(@TypeOf(p, q))) {
|
|
153
|
-
|
|
134
|
+
.comptime_int, .comptime_float => comptime gcd(p, q),
|
|
154
135
|
else => 1,
|
|
155
136
|
} == 1);
|
|
156
137
|
|
|
157
138
|
switch (@typeInfo(T)) {
|
|
158
|
-
|
|
139
|
+
.int => {
|
|
159
140
|
// Greedily attempt to multiply and if it fails, reduce and try again
|
|
160
141
|
multiplication(T, r, p, q) catch |err| switch (err) {
|
|
161
142
|
error.Overflow => {
|
|
@@ -165,16 +146,16 @@ fn update_(comptime T: type, comptime o: comptime_int, r: anytype, p: anytype, q
|
|
|
165
146
|
else => unreachable,
|
|
166
147
|
};
|
|
167
148
|
},
|
|
168
|
-
|
|
149
|
+
.float => {
|
|
169
150
|
// Reduce in situations where we're likely to start losing precision
|
|
170
151
|
if (r.q > o or r.p > o) r.reduce();
|
|
171
152
|
|
|
172
153
|
r.p *= switch (@typeInfo(@TypeOf(p))) {
|
|
173
|
-
|
|
154
|
+
.float, .comptime_float => p,
|
|
174
155
|
else => @floatFromInt(p),
|
|
175
156
|
};
|
|
176
157
|
r.q *= switch (@typeInfo(@TypeOf(q))) {
|
|
177
|
-
|
|
158
|
+
.float, .comptime_float => q,
|
|
178
159
|
else => @floatFromInt(q),
|
|
179
160
|
};
|
|
180
161
|
|
|
@@ -188,7 +169,7 @@ fn update_(comptime T: type, comptime o: comptime_int, r: anytype, p: anytype, q
|
|
|
188
169
|
|
|
189
170
|
fn add_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !void {
|
|
190
171
|
switch (@typeInfo(T)) {
|
|
191
|
-
|
|
172
|
+
.int => {
|
|
192
173
|
if (r.q == s.q) {
|
|
193
174
|
r.p = std.math.add(T, r.p, s.p) catch |err| switch (err) {
|
|
194
175
|
error.Overflow => val: {
|
|
@@ -209,7 +190,7 @@ fn add_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !voi
|
|
|
209
190
|
};
|
|
210
191
|
}
|
|
211
192
|
},
|
|
212
|
-
|
|
193
|
+
.float => {
|
|
213
194
|
if (r.q == s.q) {
|
|
214
195
|
if (r.p > o) r.reduce();
|
|
215
196
|
if (s.p > o) s.reduce();
|
|
@@ -233,7 +214,7 @@ fn add_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !voi
|
|
|
233
214
|
|
|
234
215
|
fn mul_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !void {
|
|
235
216
|
switch (@typeInfo(T)) {
|
|
236
|
-
|
|
217
|
+
.int => {
|
|
237
218
|
multiplication(T, r, s.p, s.q) catch |err| switch (err) {
|
|
238
219
|
error.Overflow => {
|
|
239
220
|
r.reduce();
|
|
@@ -243,7 +224,7 @@ fn mul_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !voi
|
|
|
243
224
|
else => unreachable,
|
|
244
225
|
};
|
|
245
226
|
},
|
|
246
|
-
|
|
227
|
+
.float => {
|
|
247
228
|
if (r.q > o or r.p > o) r.reduce();
|
|
248
229
|
if (s.q > o or s.p > o) s.reduce();
|
|
249
230
|
|
|
@@ -259,7 +240,7 @@ fn mul_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !voi
|
|
|
259
240
|
|
|
260
241
|
fn cmp_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !std.math.Order {
|
|
261
242
|
switch (@typeInfo(T)) {
|
|
262
|
-
|
|
243
|
+
.int => {
|
|
263
244
|
const ad = std.math.mul(T, r.p, s.q) catch |err| switch (err) {
|
|
264
245
|
error.Overflow => ad: {
|
|
265
246
|
r.reduce();
|
|
@@ -279,7 +260,7 @@ fn cmp_(comptime T: type, comptime o: comptime_int, r: anytype, s: anytype) !std
|
|
|
279
260
|
|
|
280
261
|
return std.math.order(ad, bc);
|
|
281
262
|
},
|
|
282
|
-
|
|
263
|
+
.float => {
|
|
283
264
|
if (r.q > o or r.p > o) r.reduce();
|
|
284
265
|
if (s.q > o or s.p > o) s.reduce();
|
|
285
266
|
|
|
@@ -332,7 +313,7 @@ fn gcd(p: anytype, q: anytype) @TypeOf(p, q) {
|
|
|
332
313
|
};
|
|
333
314
|
|
|
334
315
|
switch (@typeInfo(T)) {
|
|
335
|
-
|
|
316
|
+
.int => {
|
|
336
317
|
// std.math.gcd but without some checks because we have a stricter range
|
|
337
318
|
var x: T = @intCast(p);
|
|
338
319
|
var y: T = @intCast(q);
|
|
@@ -373,8 +354,7 @@ fn gcd(p: anytype, q: anytype) @TypeOf(p, q) {
|
|
|
373
354
|
}
|
|
374
355
|
|
|
375
356
|
test gcd {
|
|
376
|
-
|
|
377
|
-
var prng = (if (@hasDecl(std, "Random")) std.Random else std.rand).DefaultPrng.init(seed);
|
|
357
|
+
var prng = std.Random.DefaultPrng.init(std.testing.random_seed);
|
|
378
358
|
var random = prng.random();
|
|
379
359
|
|
|
380
360
|
for (0..1000) |_| {
|
package/src/lib/common/util.zig
CHANGED
|
@@ -3,11 +3,8 @@ const std = @import("std");
|
|
|
3
3
|
const expect = std.testing.expect;
|
|
4
4
|
const expectEqual = std.testing.expectEqual;
|
|
5
5
|
|
|
6
|
-
const Pointer = if (@hasField(std.builtin.Type, "pointer")) .pointer else .Pointer;
|
|
7
|
-
const One = if (@hasField(std.builtin.Type.Pointer.Size, "one")) .one else .One;
|
|
8
|
-
|
|
9
6
|
pub fn PointerType(comptime P: type, comptime C: type) type {
|
|
10
|
-
return if (@
|
|
7
|
+
return if (@typeInfo(P).pointer.is_const) *const C else *C;
|
|
11
8
|
}
|
|
12
9
|
|
|
13
10
|
test PointerType {
|
|
@@ -18,7 +15,7 @@ test PointerType {
|
|
|
18
15
|
pub fn isPointerTo(p: anytype, comptime P: type) bool {
|
|
19
16
|
const info = @typeInfo(@TypeOf(p));
|
|
20
17
|
return switch (info) {
|
|
21
|
-
|
|
18
|
+
.pointer => info.pointer.child == P,
|
|
22
19
|
else => false,
|
|
23
20
|
};
|
|
24
21
|
}
|
|
@@ -30,47 +27,18 @@ test isPointerTo {
|
|
|
30
27
|
try expect(isPointerTo(&s, S));
|
|
31
28
|
}
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
fn BytesAsValueReturnType(comptime T: type, comptime B: type) type {
|
|
39
|
-
return CopyPtrAttrs(B, One, T);
|
|
40
|
-
}
|
|
30
|
+
pub fn repeat(comptime xs: anytype, comptime n: usize) [xs.len * n]@TypeOf(xs[0]) {
|
|
31
|
+
comptime {
|
|
32
|
+
const T = @TypeOf(xs[0]);
|
|
33
|
+
var ts: [xs.len * n]T = undefined;
|
|
41
34
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const args: std.builtin.Type.Pointer = if (@hasField(std.builtin.Type.Pointer, "sentinel")) .{
|
|
49
|
-
.size = size,
|
|
50
|
-
.is_const = info.is_const,
|
|
51
|
-
.is_volatile = info.is_volatile,
|
|
52
|
-
.is_allowzero = info.is_allowzero,
|
|
53
|
-
.alignment = info.alignment,
|
|
54
|
-
.address_space = info.address_space,
|
|
55
|
-
.child = child,
|
|
56
|
-
.sentinel = null,
|
|
57
|
-
} else .{
|
|
58
|
-
.size = size,
|
|
59
|
-
.is_const = info.is_const,
|
|
60
|
-
.is_volatile = info.is_volatile,
|
|
61
|
-
.is_allowzero = info.is_allowzero,
|
|
62
|
-
.alignment = info.alignment,
|
|
63
|
-
.address_space = info.address_space,
|
|
64
|
-
.child = child,
|
|
65
|
-
.sentinel_ptr = null,
|
|
66
|
-
};
|
|
67
|
-
return @Type(if (@hasField(std.builtin.Type, "pointer"))
|
|
68
|
-
.{ .pointer = args }
|
|
69
|
-
else
|
|
70
|
-
.{ .Pointer = args });
|
|
71
|
-
}
|
|
35
|
+
var i: usize = 0;
|
|
36
|
+
while (i < n) : (i += 1) {
|
|
37
|
+
for (xs, 0..) |v, j| {
|
|
38
|
+
ts[i * xs.len + j] = v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
72
41
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return std.meta.fieldInfo(T, field).type;
|
|
42
|
+
return ts;
|
|
43
|
+
}
|
|
76
44
|
}
|