-
Notifications
You must be signed in to change notification settings - Fork 1
/
tetris_package.vhd
179 lines (127 loc) · 5.29 KB
/
tetris_package.vhd
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package TETRIS_PACKAGE is
constant BOARD_WIDTH : INTEGER := 10;
constant BOARD_HEIGHT : INTEGER := 20;
type SHAPE_TYPE is (SHAPE_T, SHAPE_SQUARE, SHAPE_LINE, SHAPE_L_LEFT, SHAPE_L_RIGHT, SHAPE_Z_LEFT, SHAPE_Z_RIGHT);
-- BOARD
type BOARD_TILE_TYPE is record
shape : SHAPE_TYPE;
state : STD_LOGIC;
end record;
type BOARD_TILE_MATRIX is array(NATURAL range <>, NATURAL range <>) of BOARD_TILE_TYPE;
subtype BOARD_TYPE is BOARD_TILE_MATRIX(0 to (BOARD_WIDTH - 1), 0 to (BOARD_HEIGHT - 1));
-- TETRIMINO
type TILE_COOR_TYPE is record
x : INTEGER range 0 to (BOARD_WIDTH - 1);
y : INTEGER range 0 to (BOARD_HEIGHT - 1);
end record;
type TILE_COOR_ARRAY is array(NATURAL range <>) of TILE_COOR_TYPE;
type TETRIMINO_TYPE is record
shape : SHAPE_TYPE;
tiles : TILE_COOR_ARRAY(0 to 3);
end record;
--TETRIMINO DEFINITIONS
constant TETRIMINO_T : TETRIMINO_TYPE :=
(
shape => SHAPE_T,
tiles => ((x => 1, y => 1), (x => 0, y =>1), (x => 1, y => 0), (x => 2, y => 1))
);
constant TETRIMINO_SQUARE : TETRIMINO_TYPE :=
(
shape => SHAPE_SQUARE,
tiles => ((x => 1, y => 1), (x => 1, y => 0), (x => 2, y => 0), (x => 2, y => 1))
);
constant TETRIMINO_LINE : TETRIMINO_TYPE :=
(
shape => SHAPE_LINE,
tiles => ((x => 1, y => 0), (x => 0, y => 0), (x => 2, y => 0), (x => 3, y => 0))
);
constant TETRIMINO_L_LEFT : TETRIMINO_TYPE :=
(
shape => SHAPE_L_LEFT,
tiles => ((x => 1, y => 1), (x => 0, y => 1), (x => 0, y => 0), (x => 2, y => 1))
);
constant TETRIMINO_L_RIGHT : TETRIMINO_TYPE :=
(
shape => SHAPE_L_RIGHT,
tiles => ((x => 1, y => 1), (x => 0, y => 1), (x => 2, y => 1), (x => 2, y => 0))
);
constant TETRIMINO_Z_LEFT : TETRIMINO_TYPE :=
(
shape => SHAPE_Z_LEFT,
tiles => ((x => 1, y => 1), (x => 1, y => 0), (x => 0, y => 0), (x => 2, y => 1))
);
constant TETRIMINO_Z_RIGHT : TETRIMINO_TYPE :=
(
shape => SHAPE_Z_RIGHT,
tiles => ((x => 1, y => 1), (x => 0, y => 1), (x => 1, y => 0), (x => 2, y => 0))
);
-- FUNCTIONS
function rotate_function (tetrimino : TETRIMINO_TYPE) return TETRIMINO_TYPE;
function rotate_border_function (tetrimino : TETRIMINO_TYPE) return BOOLEAN;
function shape_to_tetrimino (shape : SHAPE_TYPE) return TETRIMINO_TYPE;
end package;
package body TETRIS_PACKAGE is
function rotate_function (tetrimino : TETRIMINO_TYPE) return TETRIMINO_TYPE is
variable rotated_tetrimino : TETRIMINO_TYPE := TETRIMINO_SQUARE;
variable deltaX : INTEGER := 0;
variable deltaY : INTEGER := 0;
begin
if tetrimino.shape = SHAPE_SQUARE then
return tetrimino;
end if;
rotated_tetrimino.shape := tetrimino.shape;
rotated_tetrimino.tiles(0) := tetrimino.tiles(0);
for i in 1 to 3 loop
deltaX := tetrimino.tiles(i).x - tetrimino.tiles(0).x;
deltaY := tetrimino.tiles(i).y - tetrimino.tiles(0).y;
rotated_tetrimino.tiles(i).x := -deltaY + tetrimino.tiles(0).x;
rotated_tetrimino.tiles(i).y := deltaX + tetrimino.tiles(0).y;
end loop;
return rotated_tetrimino;
end function;
function rotate_border_function (tetrimino : TETRIMINO_TYPE) return BOOLEAN is
variable deltaX : INTEGER := 0;
variable deltaY : INTEGER := 0;
variable rotatedX : INTEGER := 0;
variable rotatedY : INTEGER := 0;
begin
if tetrimino.shape = SHAPE_SQUARE then
return FALSE;
end if;
for i in 1 to 3 loop
deltaX := tetrimino.tiles(i).x - tetrimino.tiles(0).x;
deltaY := tetrimino.tiles(i).y - tetrimino.tiles(0).y;
rotatedX := -deltaY + tetrimino.tiles(0).x;
rotatedY := deltaX + tetrimino.tiles(0).y;
if (rotatedX < 0) or (rotatedX >= BOARD_WIDTH) then
return TRUE;
end if;
if (rotatedY < 0) or (rotatedY >= BOARD_HEIGHT) then
return TRUE;
end if;
end loop;
return FALSE;
end function;
function shape_to_tetrimino (shape : SHAPE_TYPE) return TETRIMINO_TYPE is
variable tetrimino : TETRIMINO_TYPE := TETRIMINO_SQUARE;
begin
if shape = SHAPE_T then
tetrimino := TETRIMINO_T;
elsif shape = SHAPE_SQUARE then
tetrimino := TETRIMINO_SQUARE;
elsif shape = SHAPE_LINE then
tetrimino := TETRIMINO_LINE;
elsif shape = SHAPE_L_LEFT then
tetrimino := TETRIMINO_L_LEFT;
elsif shape = SHAPE_L_RIGHT then
tetrimino := TETRIMINO_L_RIGHT;
elsif shape = SHAPE_Z_LEFT then
tetrimino := TETRIMINO_Z_LEFT;
else --SHAPE_Z_RIGHT
tetrimino := TETRIMINO_Z_RIGHT;
end if;
return tetrimino;
end function;
end package body;