8 local tetris = QGraphicsView.new()
9 local game = QGraphicsScene.new()
10 tetris:setScene(qt.pass(game))
13 tetris:setViewportUpdateMode'NoViewportUpdate'
16 local tetris
= QTextEdit
.new()
17 tetris
:setFont(QFont
.new('Monospace', 20))
19 tetris
:setReadOnly(true)
20 tetris
:setFixedSize(200,400)
27 --X1 = { cw='X2', ccw='X2', desc = {}, },
28 --X2 = { cw='X1', ccw='X1', desc = {}, },
29 H1
= { cw
='H2', ccw
='H2', desc
= {}, },
30 H2
= { cw
='H1', ccw
='H1', desc
= {}, },
31 Z1
= { cw
='Z2', ccw
='Z2', desc
= {}, },
32 Z2
= { cw
='Z1', ccw
='Z1', desc
= {}, },
33 S1
= { cw
='S2', ccw
='S2', desc
= {}, },
34 S2
= { cw
='S1', ccw
='S1', desc
= {}, },
35 L1
= { cw
='L2', ccw
='L4', desc
= {}, },
36 L2
= { cw
='L3', ccw
='L1', desc
= {}, },
37 L3
= { cw
='L4', ccw
='L2', desc
= {}, },
38 L4
= { cw
='L1', ccw
='L3', desc
= {}, },
39 T1
= { cw
='T2', ccw
='T4', desc
= {}, },
40 T2
= { cw
='T3', ccw
='T1', desc
= {}, },
41 T3
= { cw
='T4', ccw
='T2', desc
= {}, },
42 T4
= { cw
='T1', ccw
='T3', desc
= {}, },
46 local function put_box(t
, i
, j
)
47 if not t
.desc
[i
] then t
.desc
[i
] = {} end
51 --put_box(pieces.X1, 0, 0)
52 --put_box(pieces.X1, 0, 1)
53 --put_box(pieces.X2, 0, 0)
54 --put_box(pieces.X2, 1, 0)
56 put_box(pieces
.H1
, 0, -1)
57 put_box(pieces
.H1
, 0, 0)
58 put_box(pieces
.H1
, 0, 1)
59 put_box(pieces
.H1
, 0, 2)
60 put_box(pieces
.H2
, -1, 0)
61 put_box(pieces
.H2
, 0, 0)
62 put_box(pieces
.H2
, 1, 0)
63 put_box(pieces
.H2
, 2, 0)
65 put_box(pieces
.Z1
, 0, -1)
66 put_box(pieces
.Z1
, 0, 0)
67 put_box(pieces
.Z1
, 1, 0)
68 put_box(pieces
.Z1
, 1, 1)
69 put_box(pieces
.Z2
, -1, 0)
70 put_box(pieces
.Z2
, 0, 0)
71 put_box(pieces
.Z2
, 0, -1)
72 put_box(pieces
.Z2
, 1, -1)
74 put_box(pieces
.S1
, 0, 1)
75 put_box(pieces
.S1
, 0, 0)
76 put_box(pieces
.S1
, 1, 0)
77 put_box(pieces
.S1
, 1, -1)
78 put_box(pieces
.S2
, -1, 0)
79 put_box(pieces
.S2
, 0, 0)
80 put_box(pieces
.S2
, 0, 1)
81 put_box(pieces
.S2
, 1, 1)
83 put_box(pieces
.L1
, 0, -1)
84 put_box(pieces
.L1
, 0, 0)
85 put_box(pieces
.L1
, 0, 1)
86 put_box(pieces
.L1
, -1, 1)
87 put_box(pieces
.L2
, -1, 0)
88 put_box(pieces
.L2
, 0, 0)
89 put_box(pieces
.L2
, 1, 0)
90 put_box(pieces
.L2
, 1, 1)
91 put_box(pieces
.L3
, 0, -1)
92 put_box(pieces
.L3
, 0, 0)
93 put_box(pieces
.L3
, 0, 1)
94 put_box(pieces
.L3
, 1, -1)
95 put_box(pieces
.L4
, -1, 0)
96 put_box(pieces
.L4
, 0, 0)
97 put_box(pieces
.L4
, 1, 0)
98 put_box(pieces
.L4
, -1, -1)
100 put_box(pieces
.T1
, 0, -1)
101 put_box(pieces
.T1
, 0, 0)
102 put_box(pieces
.T1
, 0, 1)
103 put_box(pieces
.T1
, 1, 1)
104 put_box(pieces
.T2
, -1, 0)
105 put_box(pieces
.T2
, 0, 0)
106 put_box(pieces
.T2
, 1, 0)
107 put_box(pieces
.T2
, 1, -1)
108 put_box(pieces
.T3
, 0, -1)
109 put_box(pieces
.T3
, 0, 0)
110 put_box(pieces
.T3
, 0, 1)
111 put_box(pieces
.T3
, -1, -1)
112 put_box(pieces
.T4
, -1, 0)
113 put_box(pieces
.T4
, 0, 0)
114 put_box(pieces
.T4
, 1, 0)
115 put_box(pieces
.T4
, -1, 1)
117 put_box(pieces
.B
, 0, 0)
118 put_box(pieces
.B
, 0, 1)
119 put_box(pieces
.B
, 1, 0)
120 put_box(pieces
.B
, 1, 1)
124 local null_piece
= function(t
, k
) return {} end
125 for _
, t
in pairs(pieces
) do
126 setmetatable(t
.desc
, {__index
= null_piece
})
130 setmetatable(tetris
.piece
, {
131 __index
= function(t
, i
)
134 __index
= function(s
, j
)
135 return pieces
[t
.piece_type
].desc
[i
-t
.position
.y
][j
-t
.position
.x
] and string.sub(t
.piece_type
, 1, 1) or nil
144 local function drawGame()
146 for i
= 1,10 do for j
= 1,10 do
147 t
[i
] = (t
[i
] or '|')..(tetris
.lines
[i
][j
] or tetris
.piece
[i
][j
] or ' ')
149 tetris
:setText(table.concat(t
, '|\n')..'|\n\\==========/')
150 --print(tetris:toPlainText())
153 local function isLegal()
156 if (tetris
.piece
[i
][j
]) and ((i
>10) or (j
>10) or (j
<1)) then return false end
157 if tetris
.piece
[i
][j
] and tetris
.lines
[i
][j
] then return false end
163 local function checkLines()
165 local completed
= true
167 if not tetris
.lines
[i
][j
] then completed
=nil end
170 --print('completed line', i)
171 for k
= i
,2,-1 do tetris
.lines
[k
] = tetris
.lines
[k
-1] end
178 local function placePiece()
180 local n
= math
.random(15)
183 for _
=1,n
do t
= next(pieces
, t
) end
185 tetris
.piece
.piece_type
= t
186 tetris
.piece
.position
= { x
=5, y
=1 }
189 local function pieceDown()
192 tetris
.piece
.position
.y
= tetris
.piece
.position
.y
+1
193 local cannot
= not isLegal()
196 tetris
.piece
.position
.y
= tetris
.piece
.position
.y
-1
197 for i
= 1,10 do for j
= 1,10 do
198 tetris
.lines
[i
][j
] = tetris
.lines
[i
][j
] or tetris
.piece
[i
][j
]
206 function tetris
.reset()
216 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_Right']), tetris
) qt
.pass(sc
)
217 sc
:connect(qt
.signal
'activated()', qt
.slot(
220 tetris
.piece
.position
.x
= tetris
.piece
.position
.x
+1
221 local cannot
= not isLegal()
223 tetris
.piece
.position
.x
= tetris
.piece
.position
.x
-1
228 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_Left']), tetris
) qt
.pass(sc
)
229 sc
:connect(qt
.signal
'activated()', qt
.slot(
232 tetris
.piece
.position
.x
= tetris
.piece
.position
.x
-1
233 local cannot
= not isLegal()
235 tetris
.piece
.position
.x
= tetris
.piece
.position
.x
+1
241 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_Down']), tetris
) qt
.pass(sc
)
242 sc
:connect(qt
.signal
'activated()', qt
.slot(pieceDown
))
243 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_R']), tetris
) qt
.pass(sc
)
244 sc
:connect(qt
.signal
'activated()', qt
.slot(tetris
.reset
))
246 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_A']), tetris
) qt
.pass(sc
)
247 sc
:connect(qt
.signal
'activated()', qt
.slot(
249 local old
= tetris
.piece
.piece_type
250 if not pieces
[old
].ccw
then return end
251 tetris
.piece
.piece_type
= pieces
[old
].ccw
252 local cannot
= not isLegal()
254 tetris
.piece
.piece_type
= old
259 sc
= QShortcut
.new(QKeySequence
.new(Qt
.Key
['Key_S']), tetris
) qt
.pass(sc
)
260 sc
:connect(qt
.signal
'activated()', qt
.slot(
262 local old
= tetris
.piece
.piece_type
263 if not pieces
[old
].cw
then return end
264 tetris
.piece
.piece_type
= pieces
[old
].cw
265 local cannot
= not isLegal()
267 tetris
.piece
.piece_type
= old
273 timer
= qt
.pass(QTimer
.new(tetris
))
275 timer
:connect(qt
.signal
'timeout()', qt
.slot(pieceDown
))