area.zig 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. const std = @import("std");
  2. const shapeModule = @import("shape.zig");
  3. const Shape = shapeModule.Shape;
  4. const kShapeSize = shapeModule.kShapeSize;
  5. pub const Area = struct {
  6. rows: i32 = 0,
  7. cols: i32 = 0,
  8. data: []u8 = undefined,
  9. dataAllocator: std.mem.Allocator,
  10. pub fn init(allocator: std.mem.Allocator, rows: i32, cols: i32) !Area {
  11. var area: Area = .{
  12. .rows = rows,
  13. .cols = cols,
  14. .data = try allocator.alloc(u8, @intCast(rows*cols)),
  15. .dataAllocator = allocator,
  16. };
  17. for (0 .. area.data.len) |i| {
  18. area.data[i] = '.';
  19. }
  20. return area;
  21. }
  22. pub fn deinit(self: *const Area) void {
  23. self.dataAllocator.free(self.data);
  24. }
  25. pub fn copy(self: *const Area, allocator: std.mem.Allocator) !Area {
  26. const area: Area = .{
  27. .rows = self.rows,
  28. .cols = self.cols,
  29. .data = try allocator.alloc(u8, @intCast(self.rows*self.cols)),
  30. .dataAllocator = allocator,
  31. };
  32. std.mem.copyForwards(u8, area.data, self.data);
  33. return area;
  34. }
  35. pub fn totalFreeSize(self: *const Area) usize {
  36. var freeSize:usize = 0;
  37. for (self.data) |d| {
  38. if (d == '.') {
  39. freeSize += 1;
  40. }
  41. }
  42. return freeSize;
  43. }
  44. pub fn getCell(self: *const Area, row: i32, col: i32) u8 {
  45. return self.data[@intCast(row*self.cols + col)];
  46. }
  47. pub fn setCell(self: *Area, row: i32, col: i32, cell: u8) void {
  48. self.data[@intCast(row*self.cols + col)] = cell;
  49. }
  50. pub fn print(self: *const Area, allocator: std.mem.Allocator) !void {
  51. const rows:usize = @intCast(self.rows);
  52. const cols:usize = @intCast(self.cols);
  53. for (0..rows) |row| {
  54. for (0..cols) |col| {
  55. const cell = self.getCell(@intCast(row), @intCast(col));
  56. try std.fs.File.stdout().writeAll(
  57. try std.fmt.allocPrint(allocator, "{c}", .{cell}));
  58. }
  59. try std.fs.File.stdout().writeAll("\n");
  60. }
  61. }
  62. pub fn appendShape(self: * const Area, allocator: std.mem.Allocator,
  63. shape: *const Shape, row: i32, col: i32, shapeSymbol: u8) !?Area {
  64. var area = try self.copy(allocator);
  65. for (0..kShapeSize) |shapeRow| {
  66. for (0..kShapeSize) |shapeCol| {
  67. if (shape.getCell(@intCast(shapeRow), @intCast(shapeCol)) == '.') {
  68. continue;
  69. }
  70. var areaRow:i32 = @intCast(shapeRow);
  71. areaRow += row;
  72. if (areaRow >= area.rows) {
  73. area.deinit();
  74. return null;
  75. }
  76. var areaCol:i32 = @intCast(shapeCol);
  77. areaCol += col;
  78. if (areaCol >= area.cols) {
  79. area.deinit();
  80. return null;
  81. }
  82. if (area.getCell(areaRow, areaCol) != '.') {
  83. area.deinit();
  84. return null;
  85. }
  86. area.setCell(areaRow, areaCol, shapeSymbol);
  87. }
  88. }
  89. return area;
  90. }
  91. };