From ef232bae518301e39a15c8b8965f190e15bcd5e5 Mon Sep 17 00:00:00 2001 From: Ishaan Bhardwaj <59454579+SashLilac@users.noreply.github.com> Date: Fri, 27 Nov 2020 22:00:43 -0500 Subject: [PATCH 1/3] DTET code cleanup --- tetris/rulesets/dtet.lua | 81 +++++++++------------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) diff --git a/tetris/rulesets/dtet.lua b/tetris/rulesets/dtet.lua index 60549ce..c54fe7e 100644 --- a/tetris/rulesets/dtet.lua +++ b/tetris/rulesets/dtet.lua @@ -32,22 +32,22 @@ DTET.big_spawn_positions = { DTET.block_offsets = { I={ - { {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} }, - { {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=0, y=1} }, { {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} }, { {x=-1, y=-1}, {x=-1, y=-2}, {x=-1, y=0}, {x=-1, y=1} }, + { {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} }, + { {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=0, y=1} }, }, J={ - { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} }, - { {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} }, { {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} }, { {x=0, y=-1}, {x=1, y=-2}, {x=0, y=-2}, {x=0, y=0} }, + { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=1, y=0} }, + { {x=0, y=-1}, {x=0, y=-2}, {x=0, y=0}, {x=-1, y=0} }, }, L={ - { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} }, - { {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} }, { {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} }, { {x=0, y=-2}, {x=0, y=-1}, {x=1, y=0}, {x=0, y=0} }, + { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=-1, y=0} }, + { {x=0, y=-1}, {x=-1, y=-2}, {x=0, y=-2}, {x=0, y=0} }, }, O={ { {x=0, y=0}, {x=-1, y=0}, {x=-1, y=-1}, {x=0, y=-1} }, @@ -62,10 +62,10 @@ DTET.block_offsets = { { {x=1, y=0}, {x=1, y=-1}, {x=0, y=-1}, {x=0, y=-2} }, }, T={ - { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} }, - { {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} }, { {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} }, { {x=0, y=-1}, {x=0, y=0}, {x=1, y=-1}, {x=0, y=-2} }, + { {x=0, y=-1}, {x=-1, y=-1}, {x=1, y=-1}, {x=0, y=0} }, + { {x=0, y=-1}, {x=0, y=0}, {x=-1, y=-1}, {x=0, y=-2} }, }, Z={ { {x=1, y=0}, {x=0, y=0}, {x=0, y=-1}, {x=-1, y=-1} }, @@ -75,64 +75,18 @@ DTET.block_offsets = { } } --- clockwise kicks: {{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, --- counterclockwise kicks: {{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - -DTET.wallkicks_3x3 = { - [0]={ - [1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, - [1]={ - [0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, - [2]={ - [0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [3]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - }, - [3]={ - [0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, -}; - -DTET.wallkicks_line = { - [0]={ - [1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, - [1]={ - [0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [2]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, - [2]={ - [0]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [1]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [3]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, - [3]={ - [0]={{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}}, - [1]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - [2]={{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}}, - }, -}; +DTET.wallkicks_cw = {{x=1, y=0}, {x=-1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=-1, y=1}} +DTET.wallkicks_ccw = {{x=-1, y=0}, {x=1, y=0}, {x=0, y=1}, {x=-1, y=1}, {x=1, y=1}} function DTET:attemptWallkicks(piece, new_piece, rot_dir, grid) - + local kicks - if piece.shape == "O" then + if piece.shape == "O" then return - elseif piece.shape == "I" then - kicks = DTET.wallkicks_line[piece.rotation][new_piece.rotation] + elseif rot_dir == 1 then + kicks = DTET.wallkicks_cw else - kicks = DTET.wallkicks_3x3[piece.rotation][new_piece.rotation] + kicks = DTET.wallkicks_ccw end assert(piece.rotation ~= new_piece.rotation) @@ -146,12 +100,13 @@ function DTET:attemptWallkicks(piece, new_piece, rot_dir, grid) return end end + end function DTET:onPieceDrop(piece, grid) piece.lock_delay = 0 -- step reset end -function DTET:getDefaultOrientation() return 1 end +function DTET:getDefaultOrientation() return 3 end -return DTET \ No newline at end of file +return DTET From 52ee433e7f9ce63b392bc51d90629f4374c33c72 Mon Sep 17 00:00:00 2001 From: nathyong Date: Thu, 3 Dec 2020 11:51:20 +1100 Subject: [PATCH 2/3] Add the Tetra Legends Tetra-X randomizer This randomizer is a slightly cleaned up version of Dr Ocelot's JavaScript variant[1], including the 1000-piece selection mechanism. [1]: https://github.com/Dr-Ocelot/tetralegends/blob/8d57a703224cc5aa5260e13160e973755c7551d9/script/game/modules/randomizers.js --- tetris/randomizers/tetra.lua | 71 ++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 tetris/randomizers/tetra.lua diff --git a/tetris/randomizers/tetra.lua b/tetris/randomizers/tetra.lua new file mode 100644 index 0000000..4b3f682 --- /dev/null +++ b/tetris/randomizers/tetra.lua @@ -0,0 +1,71 @@ +-- A randomizer based on Tetra Legends' "Tetra-X" game mode +-- There are two main rules: +-- * if piece hasn't been generated for 13+ pieces, force it +-- * if piece has been generated in the last two pieces, don't give it out +-- +-- The official implementation also has self-balancing functionality (bias +-- towards pieces that have appeared less often). + +local Randomizer = require 'tetris.randomizers.randomizer' + +local TetraXRandomizer = Randomizer:extend() + +function TetraXRandomizer:initialize() + local pieces = {"I", "J", "L", "O", "S", "T", "Z"} + + self.count = {} + self.lastseen = {} + self.totalcount = 0 + self.pieceselection = pieces + + for _, piece in ipairs(pieces) do + self.count[piece] = 0 + self.lastseen[piece] = -1 -- use -1 as magic value for "not seen" + end + +end + +function TetraXRandomizer:generatePiece() + local generated = nil + while true do + generated = self.pieceselection[math.random(#self.pieceselection)] + if not (self.lastseen[generated] == 0 or self.lastseen[generated] == 1) then + break + end + end + + -- piece has not been generated in the last 13+ + for piece, val in pairs(self.lastseen) do + if val >= 13 then + generated = piece + break + end + end + + for piece, val in pairs(self.lastseen) do + if piece == generated then + self.lastseen[piece] = 0 + else + if val ~= -1 then + self.lastseen[piece] = val + 1 + end + end + end + + self.count[generated] = self.count[generated] + 1 + self.totalcount = self.totalcount + 1 + + -- shuffle the piece selection for the next time + self.pieceselection = {} + for piece, count in pairs(self.count) do + local probability = (self.totalcount - count) / (self.totalcount * 6) + local chances = math.floor(probability * 1000 + 0.5) -- simulated "round" + for _ = 1, chances do + table.insert(self.pieceselection, piece) + end + end + + return generated +end + +return TetraXRandomizer From a4c650922272b38e9f5504e85119f1a2a577698c Mon Sep 17 00:00:00 2001 From: nathyong Date: Thu, 3 Dec 2020 12:56:02 +1100 Subject: [PATCH 3/3] Document magic value in Tetra-X randomizer --- tetris/randomizers/tetra.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/tetris/randomizers/tetra.lua b/tetris/randomizers/tetra.lua index 4b3f682..7dcea7e 100644 --- a/tetris/randomizers/tetra.lua +++ b/tetris/randomizers/tetra.lua @@ -58,6 +58,7 @@ function TetraXRandomizer:generatePiece() -- shuffle the piece selection for the next time self.pieceselection = {} for piece, count in pairs(self.count) do + -- in this case 6 = #piece types - 1, so all probabilities sum to 1 local probability = (self.totalcount - count) / (self.totalcount * 6) local chances = math.floor(probability * 1000 + 0.5) -- simulated "round" for _ = 1, chances do