-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f660d06
commit ea6eebd
Showing
3 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
local grid = require "algo.Grid" | ||
|
||
-- Tests west, north, east, south | ||
local g = grid:new(10, 10) | ||
local u = g:node(1, 1) | ||
assert(not g:west(u)) | ||
assert(not g:north(u)) | ||
assert(g:east(u) == g:node(1, 2)) | ||
assert(g:east(u, 9) == g:node(1, 10)) | ||
assert(not g:east(u, 10)) | ||
assert(g:south(u) == g:node(2, 1)) | ||
assert(g:south(u, 9) == g:node(10, 1)) | ||
assert(not g:south(u, 10)) | ||
|
||
local u = g:node(10, 10) | ||
assert(not g:east(u)) | ||
assert(not g:south(u)) | ||
assert(g:west(u) == g:node(10, 9)) | ||
assert(g:west(u, 9) == g:node(10, 1)) | ||
assert(not g:west(u, 10)) | ||
assert(g:north(u) == g:node(9, 10)) | ||
assert(g:north(u, 9) == g:node(1, 10)) | ||
assert(not g:north(u, 10)) | ||
|
||
-- Negative test with dy or dx is non-positive | ||
local u = g:node(5, 5) | ||
for _, f in ipairs {g.west, g.north, g.east, g.south} do | ||
assert(pcall(f, g, u, 2)) | ||
assert(not pcall(f, g, u, 0)) | ||
assert(not pcall(f, g, u, -1)) | ||
end | ||
|
||
-- Test Grid:node() and Grid:coord() | ||
for y = 1, g.height do | ||
for x = 1, g.width do | ||
local node = g:node(y, x) | ||
local y1, x1 = g:coord(node) | ||
assert(x == x1 and y == y1) | ||
end | ||
end | ||
|
||
os.exit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
local Grid = require "algo.GridBase" | ||
|
||
function Grid:manhattan_dist(u, v) | ||
local y1, x1 = self:coord(u) | ||
local y2, x2 = self:coord(v) | ||
return self:manhattan_dist_coord(y1, x1, y2, x2) | ||
end | ||
|
||
--- Returns a unique node number as a function of the given (y,x) coorindate | ||
--- within the grid; or nil if (y, x) is outside the grid. | ||
---@param y (number) | ||
---@param x (number) | ||
---@return (number) or nil | ||
function Grid:node(y, x) | ||
if y <= self.height and x <= self.width then | ||
return (y << self._intern.wbits) + x | ||
end | ||
end | ||
|
||
---Inverse of Grid:node(y, x) | ||
---@param node (number) | ||
---@return (number) y, (number) x | ||
function Grid:coord(node) | ||
return node >> self._intern.wbits, node & self._intern.wmask | ||
end | ||
|
||
function Grid:new(width, height) | ||
assert(width > 0 and height > 0) | ||
local g = { | ||
width = width, | ||
height = height | ||
} | ||
local wbits = math.ceil(math.log(width + 1, 2)) | ||
g._intern = { | ||
wbits = wbits, | ||
wmask = (1 << wbits) - 1 | ||
} | ||
setmetatable(g, self) | ||
self.__index = self | ||
return g | ||
end | ||
|
||
return Grid |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
local Grid = {} | ||
|
||
local function move_y(grid, y, x, dy) | ||
local y1 = y + dy | ||
if y1 > 0 and y1 <= grid.height then | ||
return grid:node(y1, x) | ||
end | ||
end | ||
|
||
local function move_x(grid, y, x, dx) | ||
local x1 = x + dx | ||
if x1 > 0 and x1 <= grid.width then | ||
return grid:node(y, x1) | ||
end | ||
end | ||
|
||
function Grid:up(y, x, dy) | ||
dy = dy or 1 | ||
assert(dy > 0) | ||
return move_y(self, y, x, -dy) | ||
end | ||
|
||
function Grid:north(node, dy) | ||
local y, x = self:coord(node) | ||
return self:up(y, x, dy) | ||
end | ||
|
||
function Grid:down(y, x, dy) | ||
dy = dy or 1 | ||
assert(dy > 0) | ||
return move_y(self, y, x, dy) | ||
end | ||
|
||
function Grid:south(node, dy) | ||
local y, x = self:coord(node) | ||
return self:down(y, x, dy) | ||
end | ||
|
||
function Grid:left(y, x, dx) | ||
dx = dx or 1 | ||
assert(dx > 0) | ||
return move_x(self, y, x, -dx) | ||
end | ||
|
||
function Grid:west(node, dx) | ||
local y, x = self:coord(node) | ||
return self:left(y, x, dx) | ||
end | ||
|
||
function Grid:right(y, x, dx) | ||
dx = dx or 1 | ||
assert(dx > 0) | ||
return move_x(self, y, x, dx) | ||
end | ||
|
||
function Grid:east(node, dx) | ||
local y, x = self:coord(node) | ||
return self:right(y, x, dx) | ||
end | ||
|
||
function Grid:manhattan_dist_coord(y1, x1, y2, x2) | ||
return math.abs(y1 - y2) + math.abs(x1 - x2) | ||
end | ||
|
||
return Grid |