const SDL = @import("sdl2"); const std = @import("std"); const Color = @import("color.zig"); const Grid = @import("grid.zig"); const Self = @This(); pub const Rot = enum(u2) { right = 0, left = 2, }; pub const Type = enum { o, i, l, j, s, z, t, }; const ncols = 4; const nrows = 4; // Positions relative to a grid row: i32, col: i32, // 4x4 grid indicating piece form structure: [4][4]bool, // Should this be dropped and become part of the grid (flag) dropped: bool = false, swapped: bool = false, piece_type: Type, color: SDL.SDL_Color, pub fn init(piece_type: Type) Self { return Self{ .row = Grid.buffer - 3, .col = (Grid.ncolumns / 2) - (ncols / 2), .piece_type = piece_type, .structure = switch (piece_type) { Type.o => .{ .{ false, true, true, false }, .{ false, true, true, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.i => .{ .{ false, false, false, false }, .{ true, true, true, true }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.l => .{ .{ false, false, true, false }, .{ true, true, true, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.j => .{ .{ true, false, false, false }, .{ true, true, true, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.s => .{ .{ false, true, true, false }, .{ true, true, false, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.z => .{ .{ true, true, false, false }, .{ false, true, true, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, Type.t => .{ .{ false, true, false, false }, .{ true, true, true, false }, .{ false, false, false, false }, .{ false, false, false, false }, }, }, .color = switch (piece_type) { Type.o => Color.yellow, Type.i => Color.cyan, Type.l => Color.orange, Type.j => Color.blue, Type.s => Color.green, Type.z => Color.red, Type.t => Color.purple, }, }; } pub fn rotate(self: Self, dir: Rot) Self { if (self.piece_type == Type.o) { return self; } var new_piece = self; if (self.piece_type == Type.i) { const sequences = .{ .{ .{ 1, 0 }, .{ 0, 2 }, .{ 2, 3 }, .{ 3, 1 } }, .{ .{ 2, 0 }, .{ 0, 1 }, .{ 1, 3 }, .{ 3, 2 } }, .{ .{ 1, 1 }, .{ 1, 2 }, .{ 2, 2 }, .{ 2, 1 } } }; inline for (sequences) |seq| { inline for (seq) |_, i| { new_piece.structure[seq[i][0]][seq[i][1]] = self.structure[seq[(i + @enumToInt(dir) - 1) % 4][0]][seq[(i + @enumToInt(dir) - 1) % 4][1]]; } } } else { const sequences = .{ .{ .{ 0, 0 }, .{ 0, 2 }, .{ 2, 2 }, .{ 2, 0 } }, .{ .{ 0, 1 }, .{ 1, 2 }, .{ 2, 1 }, .{ 1, 0 } } }; inline for (sequences) |seq| { inline for (seq) |_, i| { new_piece.structure[seq[i][0]][seq[i][1]] = self.structure[seq[(i + @enumToInt(dir) - 1) % 4][0]][seq[(i + @enumToInt(dir) - 1) % 4][1]]; } } } //[0,0][0,1][0,2] //[1,0][1,1][1,2] //[2,0][2,1][2,2] return new_piece; } pub fn render(self: Self, renderer: *SDL.SDL_Renderer, cell_size: i32, pos_x: i32, pos_y: i32) void { var rect = SDL.SDL_Rect{ .x = pos_x, .y = pos_y, .w = cell_size, .h = cell_size, }; for (self.structure) |_, y| { for (self.structure[y]) |_, x| { // We don't want to paint void cells if (self.structure[y][x] == false) { continue; } var r = self.color.r; var g = self.color.g; var b = self.color.b; var a = self.color.a; rect.x = pos_x + (@intCast(i32, x) + self.col) * cell_size; rect.y = pos_y + (@intCast(i32, y) + self.row) * cell_size; _ = SDL.SDL_SetRenderDrawColor(renderer, r, g, b, a); _ = SDL.SDL_RenderFillRect(renderer, &rect); _ = SDL.SDL_SetRenderDrawColor(renderer, r -| 30, g -| 30, b -| 30, a +| 30); _ = SDL.SDL_RenderDrawRect(renderer, &rect); } } }