forked from hiyuzawa/tetris_ai
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtetrimino.py
153 lines (132 loc) · 4.78 KB
/
tetrimino.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from block import Block
class Tetrimino:
""" Tetrimino(テトリスでは各ブロック(全7種)をこう呼ぶらしいを管理するクラス
O(四角)
I(棒)
S
Z
J
L
T
"""
def __init__(self, x, y, r, t):
""" イニシャライザ
初期位置とタイプでインスタンス化する
どのTetriminoもBlockクラス4つの集合(初期ブロックの配置で各々の形をつくる)
:param x: 初期位置 x
:param y: 初期位置 y
:param r: 初期回転 r
:param t: テトリミノのタイプ
"""
self.x = x
self.y = y
self.r = r
self.t = t
self.s = 0
if t == 0:
# 0 (四角)の形のブロック
self.shape = [Block(0, -1, t), Block(0, 0, t), Block(1, 0, t), Block(1, -1, t)]
if t == 1:
# I の形のブロック
self.shape = [Block(-1, -1, t), Block(0, -1, t), Block(1, -1, t), Block(2, -1, t)]
if t == 2:
# S の形のブロック
self.shape = [Block(0, 0, t), Block(1, 0, t), Block(1, -1, t), Block(2, -1, t)]
if t == 3:
# Z の形のブロック
self.shape = [Block(0, -1, t), Block(1, -1, t), Block(1, 0, t), Block(2, 0, t)]
if t == 4:
# J の形のブロック
self.shape = [Block(0, -1, t), Block(0, 0, t), Block(1, -1, t), Block(0, 1, t)]
if t == 5:
# L の形のブロック
self.shape = [Block(2, -1, t), Block(0, -1, t), Block(0, 0, t), Block(1, -1, t)] # L
if t == 6:
# T の形のブロック
self.shape = [Block(1, -1, t), Block(2, -1, t), Block(0, -1, t), Block(1, 0, t)] # T
for _ in range(r%4):
for b in self.shape:
b.rotate()
for b in self.shape:
b.move(x, y)
def __hash__(self):
return (self.x * 23 + self.y) * 4 + self.r % 4
def get_blocks(self):
""" 現在のブロック4つを返す
:return: 4つのBlockインスタンス配列
"""
return self.shape
def get_type(self):
""" タイプを返す
:return: タイプ
"""
return self.t
def collision(self, field):
""" 壁や他のブロックとの接触判定
field(盤面を引数にとり現在位置のBlockでfieldとの障害があれば当たり判定とする
:param field: 盤面
:return: True 当たり判定あり / False なし
"""
for b in self.shape:
x, y = b.get_pos()
if x < 0 or x > 10:
return True
tile = field.get_tile(x, y)
if tile != -1:
return True
return False
def set_score(self, score):
""" スコアをセットする
:param score: スコア値(落下の高さ)
:return:
"""
self.s = score
def get_score(self):
""" スコアを得る
:return: スコア値
"""
return self.s
def draw(self, screen, colors):
""" 画面にブロックを描画する
実際の描画処理はBlock内で行うのでここではそれを呼び出すだけ
:param screen: PyGame Screen オブジェクト
:param colors: PyGame Surface オブジェクト(色ブロックの配列)
:return:
"""
for b in self.shape:
b.draw(screen, colors)
def clone(self, dx=0, dy=0, dr=0):
""" 指定の移動を行った後のクローンを生成する
:param dx: x移動値
:param dy: y移動値
:param dr: r回転値
:return: インスタンスから指定の移動回転を行った後のTetriminoオブジェクト
"""
# 回転動作が含まれるとき
if dr != 0:
if self.t == 0: # O
# 回転しないで返す
dr = 0
elif self.t == 1 or 2 or 3: # I, S, Z
if (self.r + 1) % 4 == 1:
dy -= 1
elif (self.r + 1) % 4 == 2:
dx += 1
elif (self.r + 1) % 4 == 3:
dy += 1
elif (self.r + 1) % 4 == 0:
dx -= 1
elif self.t == 4 or 5 or 6: # J, L, T
if (self.r + 1) % 4 == 1:
dx += 1
dy -= 1
elif (self.r + 1) % 4 == 2:
dx += 1
dy += 1
elif (self.r + 1) % 4 == 3:
dx -= 1
dy += 1
elif (self.r + 1) % 4 == 0:
dx -= 1
dy -= 1
return Tetrimino(self.x+dx, self.y+dy, self.r+dr, self.t)