2013-03-28 1 views
3

나는 때때로 Lua에서 작은 게임을 만들고, 그리드 나 보드로 2D 배열을 구현해야한다. grid[outOfBoundsNum][anything]가 호출 될 때 그래서2D Lua 테이블에서 한계를 보아라.

setmetatable(grid, { 
    __index = 
    function(t, key) 
     if not table[key] then 
      return {} 
     else 
      return table[key] 
     end 
    end}) 

: 나는 특정 셀 주변의 세포를 검사 할 때 그리드 [outOfBoundsNum] 대신 오류의 빈 테이블을 반환 색인 때 그래서 나는 보통 2 차원 배열을 메타 테이블을 제공 이면 nil을 반환합니다. 그런 다음 주변 세포를 확인하려면 다음과 같이하십시오.

for k, v in ipairs(neighbours) do 
    local cell = grid[v[1][v[2]] 
    if cell then -- check if this is actually within the 2D array 
     if cell == 1 then 
      -- do something 
     elseif cell == 2 then 
      -- do something else 
     ... 
    end 
end 

이 방법은 효과가 있지만 어색한 것으로 보입니다. 더 좋은 방법이 있습니까?

+0

왜''{{X1, Y1을 포함 neighbours' 않습니다 : 그것은 그래서이 줄에 해당하는 비교적 흔한 루아 관용구는 C. 에서 삼항 연산자처럼 행동 식 논리 andor을 사용하는 것입니다 }, {x2, y2}, ...}'{cell1, cell2, ...}'가 아닌가? – Eric

+0

이유가 없습니다, 단지 예일뿐입니다. 내가 쓰는 모듈은 실제로 두 번째 메소드 {cell1, cell2, ...}를 사용합니다. –

답변

3

메타 테이블이 필요하지 않습니다.

for k, v in ipairs(neighbours) do 
    local cell = grid[v[1]] and grid[v[1]][v[2]] 

    if cell == 1 then 
     -- do something 
    elseif cell == 2 then 
     -- do something else 
    ... 
    end 
end 

이 작업을 수행해야합니다.

local cell = nil 
if grid[v[1]]~=nil then 
    cell = grid[v[1]][v[2]] 
end 
2

격자, 위치 및 함수를 취한 다음 각 기존 인접 필드와 함께 호출하는 forEachNeighbor() 함수를 작성하여 함수의 두 번째 코드 단에 if 외부를 캡슐화하면 다음과 같이 사용할 수 있습니다. : 또한

forEachNeighbor(grid, position, function(cell) 
    if cell == 1 then 
     -- do something 
    elseif cell == 2 then 
     -- do something else 
    ... 
end) 

, 당신은 grid[v[1]][v[2]]at(grid, v)이되도록, 하나 개의 매개 변수로 그리드 위치를 가지고 해당 필드 또는 nil를 반환 할 것 인 at() 기능을 제공 할 수있다. 이 방법은 __index 메타 메서드 외에 또는 대신 구현할 수도 있습니다. __index를 들어

자체를 메타 메소드 : 첫째, 당신은 아마 (무한 재귀를 야기) t 대신 tablerawget(t, key) 대신 t[key]을 의미했다. 그러나 지적한대로 __indexonly called when the key is not present in t이기 때문에 수표는 모두 불필요합니다. 그래서 당신은 쓸 수 :

__index = function(t, key) 
    return {} 
end 

마지막 말 :

I sometimes make small games in Lua, and often have to implement a 2D array

는 왜 한 번 실행하고 다른 게임에 재사용하지 않습니다를? 그것은 modules을위한 것입니다!

+1

'__index'는 키가 테이블에 없을 때만 호출되기 때문에'__index'에서'rawget'을 호출 할 필요가 없습니다. – lhf

+0

@lhf 감사합니다! 내 대답을 바로 잡았어. – Oberon

+0

나는 왜 내가 이미 모듈을 만들었는지 모르겠다. 제안에 감사드립니다! –