const std = @import("std"); const shapeModule = @import("shape.zig"); const Shape = shapeModule.Shape; const kShapeSize = shapeModule.kShapeSize; pub const Area = struct { rows: i32 = 0, cols: i32 = 0, data: []u8 = undefined, dataAllocator: std.mem.Allocator, pub fn init(allocator: std.mem.Allocator, rows: i32, cols: i32) !Area { var area: Area = .{ .rows = rows, .cols = cols, .data = try allocator.alloc(u8, @intCast(rows*cols)), .dataAllocator = allocator, }; for (0 .. area.data.len) |i| { area.data[i] = '.'; } return area; } pub fn deinit(self: *const Area) void { self.dataAllocator.free(self.data); } pub fn copy(self: *const Area, allocator: std.mem.Allocator) !Area { const area: Area = .{ .rows = self.rows, .cols = self.cols, .data = try allocator.alloc(u8, @intCast(self.rows*self.cols)), .dataAllocator = allocator, }; std.mem.copyForwards(u8, area.data, self.data); return area; } pub fn totalFreeSize(self: *const Area) usize { var freeSize:usize = 0; for (self.data) |d| { if (d == '.') { freeSize += 1; } } return freeSize; } pub fn getCell(self: *const Area, row: i32, col: i32) u8 { return self.data[@intCast(row*self.cols + col)]; } pub fn setCell(self: *Area, row: i32, col: i32, cell: u8) void { self.data[@intCast(row*self.cols + col)] = cell; } pub fn print(self: *const Area, allocator: std.mem.Allocator) !void { const rows:usize = @intCast(self.rows); const cols:usize = @intCast(self.cols); for (0..rows) |row| { for (0..cols) |col| { const cell = self.getCell(@intCast(row), @intCast(col)); try std.fs.File.stdout().writeAll( try std.fmt.allocPrint(allocator, "{c}", .{cell})); } try std.fs.File.stdout().writeAll("\n"); } } pub fn appendShape(self: * const Area, allocator: std.mem.Allocator, shape: *const Shape, row: i32, col: i32, shapeSymbol: u8) !?Area { var area = try self.copy(allocator); for (0..kShapeSize) |shapeRow| { for (0..kShapeSize) |shapeCol| { if (shape.getCell(@intCast(shapeRow), @intCast(shapeCol)) == '.') { continue; } var areaRow:i32 = @intCast(shapeRow); areaRow += row; if (areaRow >= area.rows) { area.deinit(); return null; } var areaCol:i32 = @intCast(shapeCol); areaCol += col; if (areaCol >= area.cols) { area.deinit(); return null; } if (area.getCell(areaRow, areaCol) != '.') { area.deinit(); return null; } area.setCell(areaRow, areaCol, shapeSymbol); } } return area; } };