121 lines
3.1 KiB
Lua
121 lines
3.1 KiB
Lua
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.cellSize * 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
|
|
|
|
-- Checks if all lines have been connected and all dots are fulfilled
|
|
---@return boolean
|
|
function Grid:isCompleted()
|
|
local requiredCount, totalCount = self.size.x * self.size.y, 0
|
|
for _, line in ipairs( self.lines ) do
|
|
if not line:endpointsConnected() then
|
|
return false
|
|
end
|
|
totalCount = totalCount + #line.points
|
|
end
|
|
return totalCount == requiredCount
|
|
end
|