I have written a program that will determine the height of a Tetris board after a sequence of moves are made. These inputs are in the form of a comma-delimited list, and look like <piece><position>
. List of pieces:
I
- this is a 1x4 piece lying on its sideQ
- this is a 2x2 square pieceT
- this is a T-shaped pieceZ
- this is a left-facing 2x2 offsetS
- this is a right-facing 2x2 offsetL
- this is a right-facing LJ
- this is a left-facing L
Image (source) of the pieces. Pieces are always in the same orientation as below.
I've diagrammed them out below as well. Rotation is not in scope for this problem (e.g. a vertical I
is out of scope).
I - xxxx
Q - xx
xx
T - xxx
x
Z - xx
xx
S - xx
xx
L - x
x
xx
J - x
x
xx
Positions are 0-indexed, and represent a location from the left side of the board (the board is 10-wide).
Example 1:
Input: I0,Q4
Output: 2
Board:
bbbbQQbbbb
IIIIQQbbbb
(b
represents a blank space, and the blank lines above this are left out)
Example 2
Input: Q0,Q2,Q4,Q6,Q8
Output: 0
Board (intentionally left blank):
Explanation: Using normal Tetris rules, a row is removed whenever every block in a row is filled. This sequence would place 5 square cubes evenly spaced along the bottom, which then removes those two rows.
class Tetris:
def __init__(self):
self.board =[]
self.pieces = {
'I' : [[1,1,1,1]],
'Q' : [[1,1],
[1,1]],
'T': [[1,1,1],
[0,1,0]],
'Z':[[1,1,0],
[0,1,1]],
'S':[[0,1,1],
[1,1,0]],
'L':[[1,0],
[1,0],
[1,1]],
'J':[[0,1],
[0,1],
[1,1]]}
def newRow(self):
return [0 for _ in range(10)]
def doesThePieceFit(self,row,pieceName,pos):
#checks to see if a piece fits on the row at given position
#check bottom to the top
piece = self.pieces[pieceName]
for i in range(len(piece)):
pieceRow = piece[-1*(1+i)]
if i+row == len(self.board): return True
boardRow = self.board[i+row]
for j in range(len(pieceRow)):
if pieceRow[j] and boardRow[pos+j]: return False
return True
def removeFullRows(self,startRow,numRows):
#removes full rows from the board
#only checks rows between startRow and startRow+numRows
fullRows = [i+startRow
for i in range(numRows)
if all(self.board[i+startRow])]
for fullRow in sorted(fullRows,reverse=True):
del self.board[fullRow]
def addPieceAt(self,row,pieceName,pos):
#Adds piece at this row.
piece = self.pieces[pieceName]
for i in range(len(piece)):
pieceRow = piece[-1*(1+i)]
if i+row == len(self.board):
self.board+=self.newRow(),
boardRow = self.board[i+row]
for j in range(len(pieceRow)):
if pieceRow[j]:
boardRow[pos+j] = pieceRow[j]
self.removeFullRows(row,len(piece))
def addPiece(self,pieceName,pos):
#1.find the first row where piece is blocked
#2.Add the piece at the row above it
blockedByRow = None
for row in range(len(self.board)-1,-1,-1):
if not self.doesThePieceFit(row,pieceName,pos):
blockedByRow = row
break
targetRow = 0 if blockedByRow == None else blockedByRow+1
self.addPieceAt(targetRow,pieceName,pos)
def addPieces(self,pieces):
for piece in pieces.split(','):
self.addPiece(piece[0],int(piece[1]))
return len(self.board)