const std = @import("std"); const engine = @import("../engine.zig"); const TileMap = @import("tile_map.zig").TileMap; pub const Level = struct { pub const Tile = enum { Grass, }; pub const Collectable = enum { Exit, Star, }; character: engine.Point, tiles: TileMap(Tile), collectables: TileMap(Collectable), pub fn init(allocator: std.mem.Allocator, path: []const u8) !Level { const path_ = try std.fs.realpathAlloc(allocator, path); defer allocator.free(path_); const file = try std.fs.openFileAbsolute(path_, .{ .mode = .read_only }); defer file.close(); const data = try file.readToEndAlloc(allocator, 1024 * 1024); defer allocator.free(data); return try Level.initFromMemory(allocator, data); } pub fn initFromMemory(allocator: std.mem.Allocator, data: []const u8) !Level { const n = std.mem.count(u8, data, "\n"); _ = n; var character: ?engine.Point = null; var tiles = TileMap(Tile).init(allocator); var collectables = TileMap(Collectable).init(allocator); var lines = std.mem.split(u8, data, "\n"); var y: i64 = 0; while (lines.next()) |line| { defer y += 1; for (line, 0..) |tile, column| { const x = @as(i64, @intCast(column)); switch (tile) { 'P' => character = engine.pt(x, y), 'S' => try collectables.set(x, y, .Star), 'E' => try collectables.set(x, y, .Exit), 'x' => try tiles.set(x, y, .Grass), else => {}, } } } return Level{ .character = character.?, .tiles = tiles, .collectables = collectables, }; } pub fn deinit(self: *Level) void { self.tiles.deinit(); self.collectables.deinit(); } };