246 lines
6.2 KiB
Python
246 lines
6.2 KiB
Python
#!/usr/bin/python
|
|
|
|
class Tetromino():
|
|
|
|
TYPES = ['i','a', 'b', 'c', 'o', 'd', 't', 's', 'z', 'j', 'l']
|
|
|
|
def __init__(self, state, letter):
|
|
# assert that there are rows
|
|
assert len(state) > 0
|
|
# assert rows and columns form a rectangle
|
|
assert len({len(row) for row in state}) == 1
|
|
self.state = state
|
|
self.letter = letter
|
|
|
|
@staticmethod
|
|
def ITetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['I', 'I', 'I', 'I']
|
|
],
|
|
'i'
|
|
)
|
|
|
|
@staticmethod
|
|
def ATetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['A', 'A', 'A']
|
|
],
|
|
'a'
|
|
)
|
|
|
|
@staticmethod
|
|
def BTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['B', 'B',]
|
|
],
|
|
'b'
|
|
)
|
|
|
|
@staticmethod
|
|
def CTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['C']
|
|
],
|
|
'c'
|
|
)
|
|
|
|
@staticmethod
|
|
def OTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['O', 'O'],
|
|
['O', 'O']
|
|
],
|
|
'o'
|
|
)
|
|
|
|
|
|
@staticmethod
|
|
def DTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['D', 'D'],
|
|
[' ', 'D']
|
|
],
|
|
'd'
|
|
)
|
|
|
|
@staticmethod
|
|
def TTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['T', 'T', 'T'],
|
|
[' ', 'T', ' ']
|
|
],
|
|
't'
|
|
)
|
|
|
|
@staticmethod
|
|
def STetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
[' ', 'S', 'S'],
|
|
['S', 'S', ' ']
|
|
],
|
|
's'
|
|
)
|
|
|
|
@staticmethod
|
|
def ZTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['Z', 'Z', ' '],
|
|
[' ', 'Z', 'Z']
|
|
],
|
|
'z'
|
|
)
|
|
|
|
@staticmethod
|
|
def JTetromino(): #ok
|
|
return Tetromino(
|
|
[
|
|
['J', 'J', 'J'],
|
|
[' ', ' ', 'J']
|
|
],
|
|
'j'
|
|
)
|
|
|
|
@staticmethod
|
|
def LTetromino():
|
|
return Tetromino(
|
|
[
|
|
[' ', ' ', 'L'],
|
|
['L', 'L', 'L']
|
|
],
|
|
'l'
|
|
)
|
|
|
|
@staticmethod
|
|
def create(letter):
|
|
assert letter.lower() in Tetromino.TYPES
|
|
return getattr(Tetromino, '{}Tetromino'.format(letter.upper()))()
|
|
|
|
def __str__(self):
|
|
return "\n".join(["".join(x) for x in self.state])
|
|
|
|
def __getitem__(self, key):
|
|
return self.state[key]
|
|
|
|
def copy(self):
|
|
return Tetromino([row[:] for row in self.state], self.letter)
|
|
|
|
def width(self):
|
|
return len(self.state[0])
|
|
|
|
def height(self):
|
|
return len(self.state)
|
|
|
|
def rotate(self, change):
|
|
while change < 0:
|
|
change += 4
|
|
change = (change % 4)
|
|
assert 0 <= change and change <= 3
|
|
if change == 0:
|
|
return None
|
|
elif change == 1:
|
|
self.rotate_right()
|
|
elif change == 2:
|
|
self.flip()
|
|
elif change == 3:
|
|
self.rotate_left()
|
|
else:
|
|
raise Exception('This should never happen!')
|
|
|
|
def rotate_right(self):
|
|
self.state = list(zip(*self.state[::-1]))
|
|
return self
|
|
|
|
def rotate_left(self):
|
|
self.state = list(reversed(list(zip(*self.state))))
|
|
return self
|
|
|
|
def flip(self):
|
|
self.state = [row[::-1] for row in self.state[::-1]]
|
|
return self
|
|
|
|
def get_offset_column(self, rotation, mode):
|
|
if mode == 1:
|
|
offset_map= {
|
|
'i': {0: 8, 1: 9, 2: 8, 3: 9},
|
|
'a': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'b': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'c': {0: 10, 1: 10, 2: 10, 3: 10},
|
|
'o': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'd': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
't': {0: 9, 1: 9, 2: 8, 3: 9},
|
|
's': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'z': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'j': {0: 8, 1: 9, 2: 9, 3: 9},
|
|
'l': {0: 8, 1: 9, 2: 9, 3: 9}
|
|
}
|
|
elif mode == 2:
|
|
offset_map= {
|
|
'i': {0: 9, 1: 8, 2: 9, 3: 8},
|
|
'a': {0: 9, 1: 8, 2: 9, 3: 8},
|
|
'b': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'c': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'o': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'd': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
't': {0: 9, 1: 9, 2: 9, 3: 8},
|
|
's': {0: 9, 1: 8, 2: 9, 3: 8},
|
|
'z': {0: 9, 1: 8, 2: 9, 3: 8},
|
|
'j': {0: 9, 1: 8, 2: 9, 3: 9},
|
|
'l': {0: 9, 1: 8, 2: 9, 3: 9}
|
|
}
|
|
elif mode == 3:
|
|
offset_map= {
|
|
'i': {0: 8, 1: 10, 2: 8, 3: 10},
|
|
'a': {0: 8, 1: 10, 2: 8, 3: 10},
|
|
'b': {0: 9, 1: 10, 2: 9, 3: 10},
|
|
'c': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'o': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'd': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
't': {0: 8, 1: 9, 2: 9, 3: 9},
|
|
's': {0: 8, 1: 9, 2: 8, 3: 9},
|
|
'z': {0: 8, 1: 9, 2: 8, 3: 9},
|
|
'j': {0: 9, 1: 9, 2: 8, 3: 9},
|
|
'l': {0: 9, 1: 9, 2: 8, 3: 9}
|
|
}
|
|
else: #mode == 4:
|
|
offset_map = {
|
|
'i': {0: 10, 1: 8, 2: 8, 3: 10},
|
|
'a': {0: 10, 1: 9, 2: 10, 3: 9},
|
|
'b': {0: 10, 1: 9, 2: 10, 3: 9},
|
|
'c': {0: 10, 1: 10, 2: 10, 3: 10},
|
|
'o': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
'd': {0: 9, 1: 9, 2: 9, 3: 9},
|
|
't': {0: 9, 1: 8, 2: 9, 3: 9},
|
|
's': {0: 9, 1: 9, 2: 8, 3: 9},
|
|
'z': {0: 9, 1: 9, 2: 8, 3: 9},
|
|
'j': {0: 9, 1: 9, 2: 9, 3: 8},
|
|
'l': {0: 9, 1: 9, 2: 9, 3: 8}
|
|
}
|
|
return offset_map.get(self.letter)[rotation]
|
|
|
|
|
|
if __name__ == '__main__':
|
|
t = Tetromino.LTetromino()
|
|
print(t)
|
|
print()
|
|
t.rotate_right()
|
|
print(t)
|
|
print()
|
|
t.rotate_right()
|
|
print(t)
|
|
print()
|
|
t.rotate_left()
|
|
print(t)
|
|
print(t.height())
|
|
print(t.width())
|
|
t.flip()
|
|
print(t)
|