local Object = require 'libs.classic' local Grid = Object:extend() local empty = { skin = "", colour = "", oob=false } local oob = { skin = "", colour = "", oob=true } local block = { skin = "2tie", colour = "A", oob=false } function Grid:new(width, height) self.grid = {} self.grid_age = {} self.width = width self.height = height for y = 1, self.height do self.grid[y] = {} self.grid_age[y] = {} for x = 1, self.width do self.grid[y][x] = empty self.grid_age[y][x] = 0 end end end function Grid:clear() for y = 1, self.height do for x = 1, self.width do self.grid[y][x] = empty self.grid_age[y][x] = 0 end end end function Grid:getCell(x, y) if x < 1 or x > self.width or y > self.height then return oob elseif y < 1 then return oob else return self.grid[y][x] end end function Grid:isOccupied(x, y) return self:getCell(x+1, y+1) ~= empty end function Grid:isRowFull(row) for index, square in pairs(self.grid[row]) do if square == empty then return false end end return true end function Grid:canPlacePiece(piece) local offsets = piece:getBlockOffsets() for index, offset in pairs(offsets) do local x = piece.position.x + offset.x local y = piece.position.y + offset.y if self:isOccupied(x, y) then return false end end return true end function Grid:canPlacePieceInVisibleGrid(piece) local offsets = piece:getBlockOffsets() for index, offset in pairs(offsets) do local x = piece.position.x + offset.x local y = piece.position.y + offset.y if y < 1 or self:isOccupied(x, y) ~= empty then return false end end return true end function Grid:getClearedRowCount() local count = 0 local cleared_row_table = {} for row = 1, self.height do if self:isRowFull(row) then count = count + 1 table.insert(cleared_row_table, row) end end return count, cleared_row_table end function Grid:markClearedRows() local block_table = {} for row = 1, self.height do if self:isRowFull(row) then block_table[row] = {} for x = 1, self.width do block_table[row][x] = { skin = self.grid[row][x].skin, colour = self.grid[row][x].colour, } self.grid[row][x] = { skin = self.grid[row][x].skin, colour = "X" } end end end return block_table end function Grid:clearClearedRows() for row = 1, self.height do if self:isRowFull(row) then for above_row = row, 2, -1 do self.grid[above_row] = self.grid[above_row - 1] self.grid_age[above_row] = self.grid_age[above_row - 1] end self.grid[1] = {} self.grid_age[1] = {} for i = 1, self.width do self.grid[1][i] = empty self.grid_age[1][i] = 0 end end end return true end function Grid:clearSpecificRow(row) for col = 1, self.width do self.grid[row][col] = empty end end function Grid:applyPiece(piece) if piece.big then self:applyBigPiece(piece) return end for index, offset in pairs(piece:getBlockOffsets()) do local x = piece.position.x + offset.x local y = piece.position.y + offset.y if y + 1 > 0 and y < self.height then self.grid[y+1][x+1] = { skin = piece.skin, colour = piece.colour, flash = 5 } end end end function Grid:checkStackHeight() for i = 0, self.height - 1 do for j = 0, self.width - 1 do if self:isOccupied(j, i) then return self.height - i end end end return 0 end function Grid:applyMap(map) for y, row in pairs(map) do for x, block in pairs(row) do self.grid_age[y][x] = 0 self.grid[y][x] = block end end end function Grid:update() for y = 1, self.height do for x = 1, self.width do if self.grid[y][x] ~= empty then self.grid_age[y][x] = self.grid_age[y][x] + 1 end end end end function Grid:draw(greyscale, timer) love.graphics.setColor(0,0,0,1) love.graphics.rectangle("fill", 256, 31, 80, 45, 0, 0) love.graphics.setColor(0.3, 0.3, 0.3, 1) love.graphics.line(256,31,256,31+45) love.graphics.line(256,31,256+80,31) love.graphics.line(256+80,31,256+80,31+45) love.graphics.line(256,31+45,256+80,31+45) for y = 1, self.height do for x = 1, self.width do if BLOCKS[self.grid[y][x].skin] and BLOCKS[self.grid[y][x].skin][self.grid[y][x].colour] then if self.grid[y][x].flash ~= nil then if self.grid[y][x].flash > 0 then love.graphics.setColor(0.4+(self.grid[y][x].flash*0.1), 0.4+(self.grid[y][x].flash*0.1), 0.4+(self.grid[y][x].flash*0.1), 1) love.graphics.draw(BLOCKS[self.grid[y][x].skin]['W'], 200+x*16, 64+y*16) self.grid[y][x].flash = self.grid[y][x].flash - 1 else love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(BLOCKS[self.grid[y][x].skin][self.grid[y][x].colour..'_d'], 200+x*16, 64+y*16) end end if greyscale then if timer > 1 then timer = 1 end love.graphics.setColor(0.7, 0.7, 0.7, 0+timer) if self.grid[y][x] ~= empty and self.grid[y][x].colour ~= 'X' then love.graphics.draw(BLOCKS[self.grid[y][x].skin]["A"], 200+x*16, 64+y*16) end end end end end end return Grid