summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorheav <hheav3@gmail.com>2023-03-26 10:33:29 +0000
committerheav <hheav3@gmail.com>2023-03-26 10:33:29 +0000
commit9ee7aa26f4e1a9f7cbc29b43fbfd0e698061bd6e (patch)
tree90b42a0fe1bc1d03bdcac0498f28b41f658e57bc
parent269a8f2fe621ed281b4115eed963db9815eb1eef (diff)
add hold
-rw-r--r--game/gfx.lua68
-rw-r--r--game/init.lua23
-rw-r--r--game/polyomino.lua16
-rw-r--r--heav_optimal_shapes.lua32
4 files changed, 119 insertions, 20 deletions
diff --git a/game/gfx.lua b/game/gfx.lua
index e3db203..0f64ddc 100644
--- a/game/gfx.lua
+++ b/game/gfx.lua
@@ -1,5 +1,6 @@
local evloop = require "evloop"
local viewport = require "viewport"
+local tetrominoes = require "game/tetrominoes"
local M = {}
M.__index = M
@@ -11,12 +12,12 @@ end
local colors = {
["tetr.Z"] = {1, 0.2, 0.2},
- ["tetr.I"] = {1, 0.7, 0.2},
- ["tetr.J"] = {1, 1, 0.2},
- ["tetr.L"] = {0.2, 1, 0.2},
- ["tetr.O"] = {0.2, 0.2, 1},
- ["tetr.S"] = {0.5, 0.2, 0.7},
- ["tetr.T"] = {0.7, 0.2, 1},
+ ["tetr.I"] = {0.2, 1, 1},
+ ["tetr.J"] = {0.2, 0.2, 1},
+ ["tetr.L"] = {1, 0.5, 0.2},
+ ["tetr.O"] = {1, 1, 0.2},
+ ["tetr.S"] = {0.2, 1, 0.2},
+ ["tetr.T"] = {1, 0.2, 1},
}
function M:field_dimensions()
@@ -40,20 +41,62 @@ function M:field_dimensions()
return block_size, x, y, w, h
end
+function M:draw_square(block, x, y, block_size)
+ if colors[block] then
+ love.graphics.setColor(unpack(colors[block]))
+ else
+ love.graphics.setColor(1, 1, 1)
+ end
+ love.graphics.rectangle("fill", x, y, block_size, block_size)
+end
+
function M:draw_block(block, line, column)
local block_size, field_x, field_y, _, field_h = self:field_dimensions()
local x = field_x + (column - 1) * block_size
local y = field_y + field_h - line * block_size
- if block then
- if colors[block] then
- love.graphics.setColor(unpack(colors[block]))
- else
- love.graphics.setColor(1, 1, 1)
+ if block then self:draw_square(block, x, y, block_size) end
+end
+
+function M:draw_tetromino(tetromino, x, y, block_size, trim_margins)
+ for yy, line in pairs(tetromino.cells) do
+ for xx, cell in pairs(line) do
+ local xxx = xx
+ local yyy = yy
+ yyy = tetromino.size - yyy + 1
+ if trim_margins then
+ xxx = xxx - tetromino.left_side + 1
+ yyy = yyy - (tetromino.size-tetromino.top)
+ end
+ M:draw_square(cell, x + (xxx-1)*block_size, y + (yyy-1)*block_size, block_size)
end
- love.graphics.rectangle("fill", x, y, block_size, block_size)
end
end
+local function debug_mark(x,y,...)
+ love.graphics.setColor(...)
+ love.graphics.rectangle("fill",x-1,y-1,3,3)
+end
+
+function M:draw_hold()
+ local block_size, field_x, field_y, field_w, field_h = self:field_dimensions()
+ local hold_x = field_x + field_w + block_size
+ local hold_y = field_y
+ local margin = block_size/2
+ love.graphics.setColor(0, 0, 0)
+ love.graphics.rectangle("fill", hold_x, hold_y, block_size*1.5 + margin, block_size*1.5 + margin)
+ if not self.game.can_hold then
+ love.graphics.setColor(0.5, 0.5, 0.5, 0.5)
+ love.graphics.rectangle("fill", hold_x, hold_y, block_size*1.5 + margin, block_size*1.5 + margin)
+ end
+ if not self.game.hold then return end
+ local piece = self.game.hold
+ local piece_dim = math.max(piece.width, piece.height)
+ local piece_scale = 3/math.max(piece_dim, 3)
+ local piece_x = hold_x + margin/2 + (3-piece.width*piece_scale)/2 * block_size/2
+ local piece_y = hold_y + margin/2 + (3-piece.height*piece_scale)/2 * block_size/2
+ self:draw_tetromino(self.game.hold, piece_x, piece_y, piece_scale * block_size/2, true)
+end
+
function M:draw_piece()
local piece = self.game.piece
if not piece then return end
@@ -86,6 +129,7 @@ function M:draw(dt)
love.graphics.rectangle("fill", 0, 0, 1920, 1080)
self:draw_field()
self:draw_piece()
+ self:draw_hold()
end
function M:loop()
diff --git a/game/init.lua b/game/init.lua
index ca071d1..4fb9928 100644
--- a/game/init.lua
+++ b/game/init.lua
@@ -10,6 +10,8 @@ function M.new(params)
local new = setmetatable({}, M)
new.params = params
new.field = playfield.new(params.lines or 20, params.columns or 10)
+ new.hold = false
+ new.can_hold = true
new.gfx = gfx.new(new)
new.gravity_delay = 0.5
return new
@@ -36,6 +38,19 @@ function M:input_loop()
elseif key == "space" then
repeat until not self.piece:move(-1, 0)
self.piece:place()
+ elseif key == "c" then
+ if not self.can_hold then goto bypass end
+ if not self.hold then
+ self.hold = self.piece.poly
+ self:next_piece()
+ else
+ local tmp = self.hold
+ self.hold = self.piece.poly
+ self.piece = tmp:drop(self.field)
+
+ end
+ self.can_hold = false
+ ::bypass::
end
end
@@ -45,18 +60,22 @@ function M:input_loop()
end
local pieces = {
- tetrominoes.i,
+ --[[tetrominoes.i,
tetrominoes.j,
tetrominoes.l,
tetrominoes.o,
tetrominoes.s,
tetrominoes.t,
- tetrominoes.z,
+ tetrominoes.z,]]
+ tetrominoes.i,
+ tetrominoes.o,
+ tetrominoes.j
}
function M:next_piece()
-- TODO: interface with configurable random system (it should implement
-- seeds, bags)
+ self.can_hold = true
self.piece = pieces[love.math.random(#pieces)]:drop(self.field)
return self.piece and true or false
end
diff --git a/game/polyomino.lua b/game/polyomino.lua
index 933a4fd..4294c7f 100644
--- a/game/polyomino.lua
+++ b/game/polyomino.lua
@@ -20,18 +20,22 @@ function M.def(name, shape)
end
table.insert(new.cells, 1, line)
end
-
+ new.bottom = new.size
+ new.top = 1
+ new.left_side = new.size
+ new.right_side = 1
for line = 1, new.size do
for column = 1, new.size do
if new.cells[line][column] then
- new.bottom = line
+ if new.bottom > line then new.bottom = line end
+ if new.right_side < column then new.right_side = column end
+ if new.top < line then new.top = line end
+ if new.left_side > column then new.left_side = column end
end
end
- if new.bottom then
- break
- end
end
-
+ new.height = new.top - new.bottom + 1
+ new.width = new.right_side - new.left_side + 1
return new
end
diff --git a/heav_optimal_shapes.lua b/heav_optimal_shapes.lua
new file mode 100644
index 0000000..784ba8e
--- /dev/null
+++ b/heav_optimal_shapes.lua
@@ -0,0 +1,32 @@
+local poly = require "polyomino"
+
+local M = {}
+M.__index = M
+
+M.spite_shape = poly.def("heav.spite_shape", [[
+ #.#
+ .#.#
+ #.#.
+ .#.#
+]])
+
+M.heav = poly.def("heav.heav", [[
+ .#..
+ .###
+ ###.
+ ..#.
+]])
+
+M.colon = poly.def("heav.colon", [[
+ .#.
+ ...
+ .#.
+]])
+
+M.semicolon = poly.def("heav.semicolon", [[
+ .#.
+ ...
+ ##.
+]])
+
+return M