A friend and I try to write a mine sweeper program in Lua using the Löve framework. So far the code needs to see if a box (a cell) is checked and then draw it. We are new to Lua, the program now has the flaw that it only works on the lower right box.
UPDATE: Looking at it now I see that the values of the initialized GameBoard all have the same value (i.e., GameBoard[1]
till GameBoard[150]
are all identical cells).
Here's the code:
conf.lua
has some global variables defined:
function love.conf(t)
-- Global variables.
CELL_SIZE = 40
NUM_ROWS = 15
NUM_COLS = 10
STATS_HEIGHT = 100
AMOUNT_OF_CELLS = NUM_ROWS * NUM_COLS
GRID_WIDTH = 400
GRID_HEIGHT = 700
end
Here's the relevant failing code in main.lua
(it goes wrong in the load method where the GameBoard
is filled with Cell
s.
-- The Cell table is used for every individual square on
-- the gameboard
Cell = {}
-- The Gameboard (150 Cell objects)
GameBoard = {}
-- The function new belongs to Cell and spawns a new object (a table)
-- with the same attributes as Cell.
function Cell:new(i, j)
-- each cell knows:
-- its x- and y-coordinates.
self.x_min = (i-1) * CELL_SIZE
self.x_max = (CELL_SIZE-1) + (i-1) * CELL_SIZE
self.y_min = STATS_HEIGHT + (j-1) * CELL_SIZE
self.y_max = STATS_HEIGHT + (CELL_SIZE-1) + (j-1) * CELL_SIZE
-- if it is a mine (determined with random number generator)
isMine = (math.random(1, 8) % 8 == 0) -- Roughly 0.15 (1/7) times true (is a mine)
self.isMine = isMine
-- do not check the mine initially
self.checked = false
-- return the cell object
return self;
end
-- love.load is a love-function that is called once when the game
-- starts.
function love.load()
-- The index of the cell on the GameBoard (ranging from 1 to 150)
local index = 1
-- Build a two dimensional table of Cell-objects
for i = 1, NUM_COLS, 1 do
for j = 1, NUM_ROWS, 1 do
GameBoard[ index ] = Cell:new( i, j )
index = index + 1
end
end
end
The result is that all boxes have the values of the lower box with index 150 (the latest since NUM_ROWS * NUM_COLS
= 150). All elements (Cells
) of the table (Gameboard
) have the same the x and y values set in the Cell:new
method.
It would be appreciated if someone could tell us how to properly initialize and access a table of tables.
In the function Cell:new
, self
is the table Cell
itself, so you are returning the same table every time.
A simple fix is to create a new table instead:
function Cell:new(i, j)
local t = {}
t.x_min = (i-1) * CELL_SIZE
--omit the rest
return t;
end
For future improvement, you may be interested in another way, which implements prototype:
function Cell:new(i, j)
local o = {}
setmetatable(o, self)
self.__index = self
self.x_min = (i-1) * CELL_SIZE
--omits rest
return o;
end
Read PiL: Object-Oriented Programming for further information.