Separate sockets/plugs, fix join search function

master
Louis Pearson 2022-08-08 12:45:34 -06:00
parent 8c26b29ca6
commit b4cc068efa
5 changed files with 188 additions and 77 deletions

View File

@ -10,7 +10,7 @@
},
"jsonVersion": "1.1.3",
"appBuildId": 458364,
"nextUid": 128,
"nextUid": 133,
"identifierStyle": "Capitalize",
"worldLayout": "GridVania",
"worldGridWidth": 160,
@ -84,6 +84,7 @@
{ "value": 1, "identifier": "Conduit", "color": "#248913" },
{ "value": 8, "identifier": "Outlet", "color": "#248913" },
{ "value": 2, "identifier": "Plug", "color": "#EFC41D" },
{ "value": 10, "identifier": "Socket", "color": "#7B47B2" },
{ "value": 3, "identifier": "Switch_Off", "color": "#452A47" },
{ "value": 4, "identifier": "Switch_On", "color": "#F800FF" },
{ "value": 5, "identifier": "Join", "color": "#FF0000" },
@ -725,6 +726,110 @@
}
]
},
{
"uid": 128,
"name": "Sockets",
"active": true,
"isOptional": false,
"rules": [
{
"uid": 129,
"active": true,
"size": 3,
"tileIds": [16],
"chance": 1,
"breakOnMatch": true,
"pattern": [0,1000001,0,0,10,0,0,0,0],
"flipX": false,
"flipY": false,
"xModulo": 1,
"yModulo": 1,
"xOffset": 0,
"yOffset": 0,
"checker": "None",
"tileMode": "Single",
"pivotX": 0,
"pivotY": 0,
"outOfBoundsValue": null,
"perlinActive": false,
"perlinSeed": 7140682,
"perlinScale": 0.2,
"perlinOctaves": 2
},
{
"uid": 130,
"active": true,
"size": 3,
"tileIds": [17],
"chance": 1,
"breakOnMatch": true,
"pattern": [0,0,0,1000001,10,0,0,0,0],
"flipX": false,
"flipY": false,
"xModulo": 1,
"yModulo": 1,
"xOffset": 0,
"yOffset": 0,
"checker": "None",
"tileMode": "Single",
"pivotX": 0,
"pivotY": 0,
"outOfBoundsValue": null,
"perlinActive": false,
"perlinSeed": 4621333,
"perlinScale": 0.2,
"perlinOctaves": 2
},
{
"uid": 131,
"active": true,
"size": 3,
"tileIds": [18],
"chance": 1,
"breakOnMatch": true,
"pattern": [0,0,0,0,10,1000001,0,0,0],
"flipX": false,
"flipY": false,
"xModulo": 1,
"yModulo": 1,
"xOffset": 0,
"yOffset": 0,
"checker": "None",
"tileMode": "Single",
"pivotX": 0,
"pivotY": 0,
"outOfBoundsValue": null,
"perlinActive": false,
"perlinSeed": 7076749,
"perlinScale": 0.2,
"perlinOctaves": 2
},
{
"uid": 132,
"active": true,
"size": 3,
"tileIds": [19],
"chance": 1,
"breakOnMatch": true,
"pattern": [0,0,0,0,10,0,0,1000001,0],
"flipX": false,
"flipY": false,
"xModulo": 1,
"yModulo": 1,
"xOffset": 0,
"yOffset": 0,
"checker": "None",
"tileMode": "Single",
"pivotX": 0,
"pivotY": 0,
"outOfBoundsValue": null,
"perlinActive": false,
"perlinSeed": 8968821,
"perlinScale": 0.2,
"perlinOctaves": 2
}
]
},
{
"uid": 33,
"name": "Conduit",
@ -2638,10 +2743,10 @@
0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,3,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,1,2,0,0,
0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,1,10,0,0,
0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,8,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,
1,1,2,0,2,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
1,1,2,0,10,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
@ -2705,10 +2810,10 @@
{ "px": [48,120], "src": [72,48], "f": 0, "t": 105, "d": [45,306] },
{ "px": [96,120], "src": [72,48], "f": 0, "t": 105, "d": [45,312] },
{ "px": [80,136], "src": [72,48], "f": 0, "t": 105, "d": [45,350] },
{ "px": [56,80], "src": [8,8], "f": 0, "t": 17, "d": [58,207] },
{ "px": [56,80], "src": [8,8], "f": 0, "t": 17, "d": [130,207] },
{ "px": [32,112], "src": [0,8], "f": 0, "t": 16, "d": [129,284] },
{ "px": [16,112], "src": [8,8], "f": 0, "t": 17, "d": [58,282] },
{ "px": [80,72], "src": [0,8], "f": 0, "t": 16, "d": [57,190] },
{ "px": [32,112], "src": [0,8], "f": 0, "t": 16, "d": [57,284] },
{ "px": [96,64], "src": [96,8], "f": 0, "t": 28, "d": [78,172] },
{ "px": [48,112], "src": [96,8], "f": 0, "t": 28, "d": [78,286] },
{ "px": [152,8], "src": [48,48], "f": 0, "t": 102, "d": [68,39] }
@ -3085,7 +3190,7 @@
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,8,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,8,1,0,0,0,0,
0,1,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
@ -3115,8 +3220,8 @@
{ "px": [40,16], "src": [72,48], "f": 0, "t": 105, "d": [45,45] },
{ "px": [40,24], "src": [72,48], "f": 0, "t": 105, "d": [45,65] },
{ "px": [40,32], "src": [72,48], "f": 0, "t": 105, "d": [45,85] },
{ "px": [40,72], "src": [24,8], "f": 0, "t": 19, "d": [56,185] },
{ "px": [88,72], "src": [24,8], "f": 0, "t": 19, "d": [56,191] },
{ "px": [40,72], "src": [24,8], "f": 0, "t": 19, "d": [132,185] },
{ "px": [88,72], "src": [24,8], "f": 0, "t": 19, "d": [132,191] },
{ "px": [64,56], "src": [0,8], "f": 0, "t": 16, "d": [57,148] },
{ "px": [40,40], "src": [96,8], "f": 0, "t": 28, "d": [78,105] },
{ "px": [152,8], "src": [40,48], "f": 0, "t": 101, "d": [72,39] },
@ -3528,11 +3633,11 @@
"optionalRules": [],
"intGridCsv": [
0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,1,0,0,0,0,0,0,0,0,0,0,1,0,0,
0,0,0,2,1,0,0,1,2,0,0,0,0,0,0,2,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,
0,0,0,2,1,0,0,1,10,0,0,0,0,0,0,2,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,
1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,8,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,1,1,1,1,1,6,1,1,1,1,1,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,
0,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,1,1,1,1,1,6,1,1,1,1,1,1,0,1,0,0,0,0,0,0,10,0,0,0,0,0,0,0,
0,0,0,10,0,1,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
0,0,1,1,1,1,1,1,1,9,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,
1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,6,1,1,0,1,0,0,0,
@ -3626,12 +3731,12 @@
{ "px": [40,144], "src": [72,48], "f": 0, "t": 105, "d": [45,365] },
{ "px": [72,144], "src": [72,48], "f": 0, "t": 105, "d": [45,369] },
{ "px": [152,8], "src": [16,48], "f": 0, "t": 98, "d": [49,39] },
{ "px": [24,16], "src": [8,8], "f": 0, "t": 17, "d": [130,43] },
{ "px": [56,64], "src": [0,8], "f": 0, "t": 16, "d": [129,167] },
{ "px": [144,64], "src": [0,8], "f": 0, "t": 16, "d": [129,178] },
{ "px": [80,16], "src": [24,8], "f": 0, "t": 19, "d": [56,50] },
{ "px": [96,72], "src": [24,8], "f": 0, "t": 19, "d": [56,192] },
{ "px": [144,8], "src": [16,8], "f": 0, "t": 18, "d": [59,38] },
{ "px": [24,16], "src": [8,8], "f": 0, "t": 17, "d": [58,43] },
{ "px": [56,64], "src": [0,8], "f": 0, "t": 16, "d": [57,167] },
{ "px": [144,64], "src": [0,8], "f": 0, "t": 16, "d": [57,178] },
{ "px": [40,128], "src": [96,8], "f": 0, "t": 28, "d": [78,325] },
{ "px": [72,128], "src": [96,8], "f": 0, "t": 28, "d": [78,329] },
{ "px": [0,8], "src": [48,48], "f": 0, "t": 102, "d": [68,20] },

View File

@ -193,10 +193,10 @@ pub fn extractLevel(opt: Options) !void {
.Conduit, .Source, .Join => opt.conduit.find(autotile),
.Switch_On => opt.switch_on.find(autotile),
.Switch_Off => opt.switch_off.find(autotile),
.Plug => opt.plug.find(autotile),
.Plug, .Socket => opt.plug.find(autotile),
.And => world.Tiles.LogicAnd,
.Xor => world.Tiles.LogicXor,
else => 0,
.None, .Outlet => 0,
};
circuit.map[i] = tile;
}

View File

@ -258,9 +258,12 @@ fn loadLevel(lvl: usize) !void {
var i: usize = 0;
while (level.getJoin(i)) |join| : (i += 1) {
const globalc = Coord.fromWorld(level.world_x, level.world_y).addC(join);
var e = false;
if (db.isEnergized(globalc)) {
circuit.addSource(.{join.val[0], join.val[1]});
e = true;
circuit.addSource(.{ join.val[0], join.val[1] });
}
w4.tracef("---- Join %d: (%d, %d) <%d>", i, globalc.val[0], globalc.val[1], @boolToInt(e));
}
}
@ -714,19 +717,20 @@ fn updateCircuit() !void {
db.updateCircuit();
for (db.circuit_info) |node, n| {
const e = @boolToInt(node.energized);
switch (node.kind) {
.Conduit => |Conduit| w4.tracef("[%d]: Conduit [%d, %d]", n, Conduit[0], Conduit[1]),
.And => |And| w4.tracef("[%d]: And [%d, %d]", n, And[0], And[1]),
.Xor => |Xor| w4.tracef("[%d]: Xor [%d, %d]", n, Xor[0], Xor[1]),
.Conduit => |Conduit| w4.tracef("[%d]: Conduit [%d, %d] <%d>", n, Conduit[0], Conduit[1], e),
.And => |And| w4.tracef("[%d]: And [%d, %d] <%d>", n, And[0], And[1], e),
.Xor => |Xor| w4.tracef("[%d]: Xor [%d, %d] <%d>", n, Xor[0], Xor[1], e),
.Source => w4.tracef("[%d]: Source", n),
.Plug => |Plug| {
const plug = Plug orelse std.math.maxInt(world.NodeID);
w4.tracef("[%d]: Plug [%d]", n, plug);
.Socket => |Socket| {
const socket = Socket orelse std.math.maxInt(world.NodeID);
w4.tracef("[%d]: Socket [%d] <%d>", n, socket, e);
},
.Jack => |Jack| w4.tracef("[%d]: Jack [%d]", n, Jack),
.Switch => |Switch| w4.tracef("[%d]: Switch [%s]", n, &@tagName(Switch)),
.Join => |Join| w4.tracef("[%d]: Join [%d]", n, Join),
.Outlet => |Outlet| w4.tracef("[%d]: Outlet [%d]", n, Outlet),
.Plug => |Plug| w4.tracef("[%d]: Plug [%d] <%d>", n, Plug, e),
.Switch => |Switch| w4.tracef("[%d]: Switch [%s] <%d>", n, &@tagName(Switch), e),
.Join => |Join| w4.tracef("[%d]: Join [%d] <%d>", n, Join, e),
.Outlet => |Outlet| w4.tracef("[%d]: Outlet [%d] <%d>", n, Outlet, e),
}
}
}

View File

@ -15,6 +15,7 @@ pub const CircuitType = enum(u4) {
Xor = 7,
Outlet = 8,
Source = 9,
Socket = 10,
};
/// This lists the most important tiles so I don't have to keep rewriting things
@ -319,6 +320,7 @@ pub const Level = struct {
const y = @intCast(i16, @divFloor(i, 20));
return Coord.init(.{ x, y });
}
joinCount += 1;
}
},
else => continue,
@ -647,11 +649,11 @@ pub const Database = struct {
const p1id = db.getNodeID(p1) orelse return;
const p2id = db.getNodeID(p2) orelse return;
if (db.circuit_info[p1id].kind == .Jack and db.circuit_info[p2id].kind == .Plug) {
db.circuit_info[p2id].kind.Plug = p1id;
} else if (db.circuit_info[p2id].kind == .Jack and db.circuit_info[p1id].kind == .Plug) {
db.circuit_info[p1id].kind.Plug = p2id;
} else if (db.circuit_info[p2id].kind == .Jack and db.circuit_info[p1id].kind == .Plug) {
if (db.circuit_info[p1id].kind == .Plug and db.circuit_info[p2id].kind == .Socket) {
db.circuit_info[p2id].kind.Socket = p1id;
} else if (db.circuit_info[p2id].kind == .Plug and db.circuit_info[p1id].kind == .Socket) {
db.circuit_info[p1id].kind.Socket = p2id;
} else if (db.circuit_info[p2id].kind == .Socket and db.circuit_info[p1id].kind == .Plug) {
return error.Unimplemented;
}
}
@ -690,15 +692,15 @@ pub const Database = struct {
const input2 = db.circuit_info[Conduit[1]].energized;
db.circuit_info[i].energized = (input1 or input2);
},
.Plug => |plug_opt| {
if (plug_opt) |input| {
.Socket => |socket_opt| {
if (socket_opt) |input| {
db.circuit_info[i].energized = db.circuit_info[input].energized;
} else {
db.circuit_info[i].energized = false;
}
},
.Jack => |Jack| {
db.circuit_info[i].energized = db.circuit_info[Jack].energized;
.Plug => |Plug| {
db.circuit_info[i].energized = db.circuit_info[Plug].energized;
},
.Switch => |state| {
// TODO Rework switch to make sense
@ -768,7 +770,7 @@ const NodeEnum = enum(u4) {
Source,
Conduit,
Plug,
Jack,
Socket,
Switch,
Join,
Outlet,
@ -783,11 +785,14 @@ pub const NodeKind = union(NodeEnum) {
Source,
/// Connects multiple nodes
Conduit: [2]NodeID,
/// This node represents a physical plug in the game world. The
/// NodeID points to another plug, if connected
Plug: ?NodeID,
/// If a plug is connected to a circuit fragment with a source, it is a jack.
Jack: NodeID,
/// A "male" receptacle. Wires attached can provide power to
/// a socket on the other end.
Plug: NodeID,
/// A "female" receptacle. Wires attached provide power from
/// a plug on the other side.
///
/// No visual difference from a plug.
Socket: ?NodeID,
/// A switch can be in one of five states, though only
/// two apply to any one switch.
/// Vertical = Off or Top/Bottom, depending on flow
@ -822,16 +827,16 @@ pub const NodeKind = union(NodeEnum) {
try reader.readInt(NodeID, .Little),
} };
},
.Plug => {
const plug = try reader.readInt(NodeID, .Little);
if (plug == std.math.maxInt(NodeID)) {
kind = .{ .Plug = null };
.Socket => {
const socket = try reader.readInt(NodeID, .Little);
if (socket == std.math.maxInt(NodeID)) {
kind = .{ .Socket = null };
} else {
kind = .{ .Plug = plug };
kind = .{ .Socket = socket };
}
},
.Jack => {
kind = .{ .Jack = try reader.readInt(NodeID, .Little) };
.Plug => {
kind = .{ .Plug = try reader.readInt(NodeID, .Little) };
},
.Switch => {
kind = .{
@ -865,11 +870,11 @@ pub const NodeKind = union(NodeEnum) {
try writer.writeInt(NodeID, Conduit[1], .Little);
},
.Plug => |Plug| {
const plug = Plug orelse std.math.maxInt(NodeID);
try writer.writeInt(NodeID, plug, .Little);
try writer.writeInt(NodeID, Plug, .Little);
},
.Jack => |Jack| {
try writer.writeInt(NodeID, Jack, .Little);
.Socket => |Socket| {
const socket = Socket orelse std.math.maxInt(NodeID);
try writer.writeInt(NodeID, socket, .Little);
},
.Switch => |Switch| {
try writer.writeInt(NodeID, @enumToInt(Switch), .Little);
@ -892,8 +897,8 @@ pub const NodeKind = union(NodeEnum) {
.And => |And| std.fmt.format(writer, "{s} [{}, {}]", .{ name, And[0], And[1] }),
.Xor => |Xor| std.fmt.format(writer, "{s} [{}, {}]", .{ name, Xor[0], Xor[1] }),
.Source => std.fmt.format(writer, "{s}", .{name}),
.Plug => |Plug| std.fmt.format(writer, "{s} [{?}]", .{ name, Plug }),
.Jack => |Jack| std.fmt.format(writer, "{s} [{}]", .{ name, Jack }),
.Plug => |Plug| std.fmt.format(writer, "{s} [{}]", .{ name, Plug }),
.Socket => |Socket| std.fmt.format(writer, "{s} [{?}]", .{ name, Socket }),
.Switch => |Switch| std.fmt.format(writer, "{s} [{s}]", .{ name, @tagName(Switch) }),
.Join => |Join| std.fmt.format(writer, "{s} [{}]", .{ name, Join }),
.Outlet => |Outlet| std.fmt.format(writer, "{s} [{}]", .{ name, Outlet }),

View File

@ -286,7 +286,7 @@ pub fn buildCircuit(alloc: std.mem.Allocator, levels: []world.Level) !std.ArrayL
var nodes = std.ArrayList(world.CircuitNode).init(alloc);
var sources = Queue{};
var plugs = Queue{};
var sockets = Queue{};
var level_hashmap = std.AutoHashMap(u16, world.Level).init(alloc);
defer level_hashmap.deinit();
@ -317,10 +317,10 @@ pub fn buildCircuit(alloc: std.mem.Allocator, levels: []world.Level) !std.ArrayL
try nodes.append(.{ .kind = .Source, .coord = Coord.init(.{ x, y }) });
sources.append(coordinate);
},
.Plug => {
.Socket => {
// try nodes.append(.{ .kind = .{ .Plug = null } });
coordinate.data.last_node = std.math.maxInt(world.NodeID);
plugs.append(coordinate);
sockets.append(coordinate);
},
else => {
// Do nothing
@ -341,7 +341,7 @@ pub fn buildCircuit(alloc: std.mem.Allocator, levels: []world.Level) !std.ArrayL
var run: usize = 0;
while (run < 2) : (run += 1) {
if (run == 0) bfs_queue.concatByMoving(&sources);
if (run == 1) bfs_queue.concatByMoving(&plugs);
if (run == 1) bfs_queue.concatByMoving(&sockets);
// bfs_queue.concatByMoving(&outlets);
while (bfs_queue.popFirst()) |node| {
@ -370,24 +370,21 @@ pub fn buildCircuit(alloc: std.mem.Allocator, levels: []world.Level) !std.ArrayL
// Collects from two other nodes. Needs to store more info in coordinate queue
// TODO
},
.Plug => {
if (last_node == std.math.maxInt(world.NodeID)) {
.Socket => {
next_node = @intCast(world.NodeID, nodes.items.len);
try nodes.append(.{
.kind = .{ .Plug = null },
.kind = .{ .Socket = null },
.coord = coord,
});
} else {
// This plug is connected directly to a circuit fragment
// with a source, so we are at the end of the search along
// this conduit path. Make the plug a jack instead, so it
// looks at the last node instead of being null
},
.Plug => {
// Plugs by their nature end a conduit path, so don't add
// surrounding tiles.
try nodes.append(.{
.kind = .{ .Jack = last_node },
.kind = .{ .Plug = last_node },
.coord = coord,
});
continue;
}
},
.Outlet => {
next_node = @intCast(world.NodeID, nodes.items.len);
@ -519,7 +516,7 @@ pub fn buildCircuit(alloc: std.mem.Allocator, levels: []world.Level) !std.ArrayL
try multi_input.put(coord, next_node);
}
},
else => continue,
.None => continue,
}
const right = try alloc.create(Node);