require 'tablefuncs' require 'config' require 'point' -- Game grid table, acts as "global level" of some sort ---@class Grid ---@field lines Line[] ---@field size Point Grid = { lines = {}, size = Point:new( Point:coords() ) } -- Factory function ---@param size Point ---@returns Grid function Grid:new( size ) local grid = { lines = {}, size = size } setmetatable( grid, { __index = self } ) return grid end -- Add new line to grid ---@param line Line function Grid:push( line ) table.insert( self.lines, line ) end -- Draw lines and the whole grid function Grid:draw() -- Draw grid for x = 1, self.size.x do-- Draw lines for _, line in ipairs( self.lines ) do line:draw() end for y = 1, self.size.y do local px, py = x * Config.cellSize, y * Config.cellSize love.graphics.circle( "fill", px - Config.cellSize / 2, py - Config.cellSize / 2, Config.pointRadius) end end -- Draw lines for _, line in ipairs( self.lines ) do line:draw() end end -- Check all lines and return one, which contains point (if any) -- TODO: rewrite this function to extract clear/reverse behavior ---@param point Point ---@param ignoreEnd boolean function Grid:matchesLine( point, ignoreEnd ) local line = self.lines[TableFind( self.lines, point, function( value, innervalue ) return innervalue:has( value ) end )] if line ~= nil and not ignoreEnd then if line.startpoint:equals( point ) then line:clear() line:push( line.startpoint ) end if line.endpoint:equals( point ) then line:clear() line:reverse() return line end end -- Try to check endpoint if line == nil and not ignoreEnd then line = self.lines[TableFind( self.lines, point, function( value, innervalue ) if innervalue.endpoint:equals( value ) then innervalue:clear() innervalue:reverse() return true end return false end )] end return line end -- Checks if specified point does belong to any line endpoint but not specified line ---@param line Line ---@param point GridPoint ---@return boolean function Grid:isOtherEndpoint( line, point ) return TableHas( self.lines, { line=line, point=point }, function( value, innervalue ) return innervalue ~= value.line and innervalue.endpoint:equals( value.point ) end ) end -- Checks if point is in grid bounds ---@param point GridPoint ---@return boolean function Grid:inBounds( point ) return point.x <= self.size.x and point.y <= self.size.y end