Last active
May 13, 2022 00:36
-
-
Save radgeRayden/6f43edcf82b60b883905f4c3542324f1 to your computer and use it in GitHub Desktop.
minesweeper
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
local field = {} | |
local field_width = 10 | |
local field_height = 10 | |
local field_position_x = 100 | |
local field_position_y = 100 | |
local n_mines = 15 | |
local size_square = 30 | |
local start_time = 0 | |
local play_time = 0 | |
local is_game_over = false | |
local function getxy_from_index(index, width, height) | |
if index < 1 or index > width * height then | |
return false | |
end | |
return ((index - 1) % width), (math.floor((index - 1) / height)) | |
end | |
local function get_index_fromxy(x, y, width, height) | |
if x < 0 or y < 0 or x >= width or y >= height then | |
return false | |
end | |
return ((y * width) + x) + 1 | |
end | |
local function square_reveal(self) | |
if self.revealed then return end | |
self.revealed = true | |
if self.has_mine then | |
is_game_over = true | |
elseif self.n_neighbour_mines == 0 then | |
for i, neighbour in ipairs(self.neighbours) do | |
if not neighbour.has_mine and not neighbour.is_flagged then | |
neighbour:reveal() | |
end | |
end | |
end | |
end | |
local function square_flag_toggle(self) | |
self.is_flagged = not self.is_flagged | |
end | |
function love.load() | |
love.window.setTitle("Minefield Game") | |
start_time = love.timer.getTime() | |
is_game_over = false | |
for i=1, field_width * field_height do | |
field[i] = | |
{ | |
has_mine = false, | |
revealed = false, | |
n_neighbour_mines = 0, | |
neighbours = {}, | |
is_flagged = false, | |
toggle_flag = square_flag_toggle, | |
reveal = square_reveal, | |
neighbours = {} | |
} | |
end | |
for i, square in ipairs(field) do | |
local x, y = getxy_from_index(i, field_width, field_height) | |
local neighbour_indexes = | |
{ | |
get_index_fromxy(x - 1, y - 1, field_width, field_height), -- top left | |
get_index_fromxy(x , y - 1, field_width, field_height), -- top center | |
get_index_fromxy(x + 1, y - 1, field_width, field_height), -- top right | |
get_index_fromxy(x - 1, y , field_width, field_height), -- center left | |
get_index_fromxy(x + 1, y , field_width, field_height), -- center right | |
get_index_fromxy(x - 1, y + 1, field_width, field_height), -- bottom left | |
get_index_fromxy(x , y + 1, field_width, field_height), -- bottom center | |
get_index_fromxy(x + 1, y + 1, field_width, field_height) -- bottom right | |
} | |
for _, index in ipairs(neighbour_indexes) do | |
if index then | |
table.insert(square.neighbours, field[index]) | |
end | |
end | |
end | |
for i=1, n_mines do | |
:: retry :: | |
local index = (math.ceil(love.math.random(field_width * field_height))) | |
if not field[index].has_mine then | |
field[index].has_mine = true | |
else | |
goto retry | |
end | |
local x, y = getxy_from_index(i, field_width, field_height) | |
-- add 1 to each neighbour mine counter | |
for i,square in ipairs(field[index].neighbours) do | |
square.n_neighbour_mines = square.n_neighbour_mines + 1 | |
end | |
end | |
love.graphics.setBackgroundColor(0.14, 0.14, 0.14) | |
end | |
function get_square_from_screenpos(x, y) | |
local rel_position_x, rel_position_y = x - field_position_x, y - field_position_y | |
local x, y = math.floor(rel_position_x / size_square), math.floor(rel_position_y / size_square) | |
local index = get_index_fromxy(x, y, field_width, field_height) | |
if not index then return false end | |
return field[index] | |
end | |
function love.draw() | |
if is_game_over then | |
love.graphics.print("Game over! Press 'r' to restart!") | |
end | |
love.graphics.print(tostring(play_time), 10, 10) | |
love.graphics.translate(field_position_x, field_position_y) | |
for i=1, field_width * field_height do | |
local square = field[i] | |
local x, y = getxy_from_index(i, field_width, field_height) | |
if square.revealed then | |
love.graphics.rectangle('fill', x * size_square, y * size_square, size_square, size_square) | |
if square.has_mine then | |
love.graphics.setColor(252/255, 186/255, 3/255) | |
love.graphics.circle('fill', (x * size_square) + (size_square / 2),(y * size_square) + (size_square / 2), size_square / 2) | |
love.graphics.setColor(1,1,1) | |
elseif square.n_neighbour_mines > 0 then | |
love.graphics.setColor(0.14, 0.14, 0.14) | |
love.graphics.print(square.n_neighbour_mines, (x * size_square) + (size_square / 2) - 5, (y * size_square) + (size_square / 2) - 7) | |
love.graphics.setColor(1,1,1) | |
end | |
else | |
love.graphics.rectangle('line', x * size_square, y * size_square, size_square, size_square) | |
if square.is_flagged then | |
love.graphics.push() | |
love.graphics.translate(x * size_square, y * size_square) | |
love.graphics.scale(size_square) | |
-- draw flag | |
love.graphics.setColor(1,0,0) | |
love.graphics.polygon('fill', 0.1, 0.4, 0.8, 0.1, 0.8, 0.4) | |
love.graphics.setColor(0,1,0) | |
love.graphics.setLineWidth(0.1) | |
love.graphics.line(0.8, 0.1, 0.8, 0.9) | |
love.graphics.setColor(1,1,1) | |
love.graphics.pop() | |
end | |
end | |
end | |
end | |
function love.keypressed(key) | |
if key == 'r' then | |
love.load() | |
end | |
end | |
function love.mousereleased(x, y, button) | |
if is_game_over then return end | |
local square = get_square_from_screenpos(x, y) | |
if not square then return end | |
if button == 1 then | |
square:reveal() | |
end | |
if button == 2 then | |
square:toggle_flag() | |
end | |
end | |
function love.update(dt) | |
-- time since start of play session | |
if not is_game_over then | |
play_time = math.floor(love.timer.getTime() - start_time) | |
end | |
local field_complete = true | |
for _,v in ipairs(field) do | |
local revealed = v.revealed or (v.is_flagged and v.has_mine) | |
field_complete = field_complete and revealed | |
end | |
is_game_over = is_game_over or field_complete | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment