回答編集履歴
4
使わなくなってた関数の削除
test
CHANGED
@@ -184,18 +184,6 @@
|
|
184
184
|
}
|
185
185
|
}
|
186
186
|
|
187
|
-
int get_block_item(DROP_BLOCK *drop, int x, int y) {
|
188
|
-
int dx = x - drop->x;
|
189
|
-
int dy = y - drop->y;
|
190
|
-
if(dx < 0 || dy < 0) return 0; //範囲外
|
191
|
-
|
192
|
-
int *b = get_angled_layout(drop->block, drop->angle);
|
193
|
-
for(int i=0; i<N_ITEMS; i++, b+=2) {
|
194
|
-
if(b[0] == dx && b[1] == dy) return 1;
|
195
|
-
}
|
196
|
-
return 0;
|
197
|
-
}
|
198
|
-
|
199
187
|
#define PANEL_X_OFFSET 2
|
200
188
|
|
201
189
|
void print(PANEL *panel, DROP_BLOCK *drop) {
|
3
コードをゲームを模した形に変更
test
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
キー入力のほうは分からないので、 SRS の確認みたいなのだけ [SRS Super Rotation System](https://tetrisch.github.io/main/srs.html) を見て書いてみました。
|
2
|
-
とりあえず凸状態の T ミノが一番下に移動した直後に右回転したらというテストをハードコードしています。(これしか試してないですが^^;)
|
2
|
+
~~とりあえず凸状態の T ミノが一番下に移動した直後に右回転したらというテストをハードコードしています。(これしか試してないですが^^;)~~
|
3
|
+
ゲーム画面を模して操作出来るようにしてみました。
|
4
|
+
カーソルキーで上下左右に移動・スペースで右回転・ 1 ~ 7 で 7 つの形を選べます(選ぶと位置が上に戻ります)。終わりは ESC キーです。
|
3
5
|
全く質問のコードが入って無いので、参考にさえなるかどうか。
|
4
6
|
```c
|
5
|
-
#include <std
|
7
|
+
#include <unistd.h>
|
6
|
-
|
7
|
-
|
8
|
+
#include <ncurses.h>
|
9
|
+
|
10
|
+
#ifndef KEY_ESC
|
11
|
+
#define KEY_ESC (0x1b)
|
12
|
+
#endif
|
8
13
|
|
9
14
|
//Super Rotate System パターン
|
10
15
|
int SRS_3x3_R[] = { //3x3,右回転(回転前の角度の順にすること)
|
@@ -191,90 +196,81 @@
|
|
191
196
|
return 0;
|
192
197
|
}
|
193
198
|
|
199
|
+
#define PANEL_X_OFFSET 2
|
200
|
+
|
194
|
-
void print(
|
201
|
+
void print(PANEL *panel, DROP_BLOCK *drop) {
|
195
|
-
|
202
|
+
clear();
|
196
|
-
printf("軸: x=%d, y=%d, angle=%d\n", drop->x, drop->y, drop->angle);
|
197
|
-
for(int y=0; y<panel->height; y++) {
|
203
|
+
for(int y=0; y<=panel->height; y++) {
|
204
|
+
int xx = 0;
|
205
|
+
mvprintw(y, xx, "<!");
|
206
|
+
xx += PANEL_X_OFFSET;
|
198
|
-
for(int x=0; x<panel->width; x++) {
|
207
|
+
for(int x=0; x<panel->width; x++, xx+=2) {
|
199
|
-
int b = get_block_item(drop, x, y);
|
200
|
-
print
|
208
|
+
mvprintw(y, xx, y==panel->height?"==":get_panel_item(panel,x,y)?"[]":" ");
|
201
|
-
}
|
209
|
+
}
|
202
|
-
print
|
210
|
+
mvprintw(y, xx, "!>");
|
203
|
-
}
|
211
|
+
}
|
212
|
+
int *b = get_angled_layout(drop->block, drop->angle);
|
213
|
+
for(int i=0; i<N_ITEMS; i++, b+=2) {
|
214
|
+
mvprintw(drop->y+b[1], (drop->x+b[0])*2+PANEL_X_OFFSET, "[]");
|
215
|
+
}
|
216
|
+
refresh();
|
204
217
|
}
|
205
218
|
|
206
219
|
int main(void) {
|
207
220
|
PANEL panel = {
|
208
|
-
|
221
|
+
10, 12, 2,
|
209
|
-
(int[]){ //空き位置は 0, 障害物は
|
222
|
+
(int[]){ //空き位置は 0, 障害物は !0
|
210
|
-
|
223
|
+
0,0,0,0,0,0,0,0,0,0,
|
211
|
-
|
224
|
+
0,0,0,0,0,0,0,0,0,0,
|
212
|
-
|
225
|
+
0,0,0,0,0,0,0,0,0,0,
|
213
|
-
|
226
|
+
0,0,0,0,0,0,0,0,0,0,
|
214
|
-
|
227
|
+
0,0,0,0,0,0,0,0,0,0,
|
215
|
-
|
228
|
+
0,0,0,0,0,0,0,0,0,0,
|
216
|
-
|
229
|
+
0,0,0,0,0,0,0,0,0,0,
|
230
|
+
0,0,0,0,0,0,0,0,0,0,
|
231
|
+
0,0,0,0,1,0,0,0,0,1,
|
232
|
+
1,0,0,0,1,1,1,0,0,1,
|
233
|
+
1,1,0,1,1,0,0,0,0,1,
|
217
|
-
|
234
|
+
1,0,0,1,1,0,0,0,0,1 }
|
218
235
|
};
|
236
|
+
|
237
|
+
initscr();
|
238
|
+
noecho(); //入力表示無し
|
239
|
+
curs_set(0); //カーソル非表示
|
240
|
+
cbreak(); //入力バッファ無し
|
241
|
+
keypad(stdscr, 1); //カーソルキー入力
|
242
|
+
timeout(100); //入力待ち時間[ms]
|
219
243
|
|
220
244
|
//初期(これは正常に置けるものとする)
|
221
245
|
DROP_BLOCK drop;
|
222
|
-
drop.x =
|
246
|
+
drop.x = 4;
|
223
|
-
drop.y =
|
247
|
+
drop.y = 0;
|
224
248
|
drop.angle = ANGLE_A;
|
225
249
|
drop.block = &BLOCKS[BLOCK_T];
|
250
|
+
|
251
|
+
for(int ch; (ch=getch())!=KEY_ESC; ) {
|
252
|
+
if(ch == KEY_LEFT || ch == KEY_RIGHT || ch == KEY_UP || ch == KEY_DOWN) { //移動
|
253
|
+
int dx = ch == KEY_LEFT ? -1 : ch == KEY_RIGHT ? 1 : 0;
|
254
|
+
int dy = ch == KEY_UP ? -1 : ch == KEY_DOWN ? 1 : 0;
|
255
|
+
if(is_placeable(drop.block, drop.angle, drop.x+dx, drop.y+dy, &panel)) {
|
256
|
+
drop.x += dx;
|
257
|
+
drop.y += dy;
|
258
|
+
}
|
259
|
+
}
|
226
|
-
|
260
|
+
if(ch == ' ') { //回転
|
227
|
-
|
228
|
-
rotate_block(&drop, DIR_RIGHT, &panel);
|
261
|
+
rotate_block(&drop, DIR_RIGHT, &panel);
|
262
|
+
}
|
263
|
+
if('1' <= ch && ch < '1'+N_BLOCK_TYPES) { //切り替え
|
264
|
+
drop.x = 4;
|
265
|
+
drop.y = 0;
|
266
|
+
drop.angle = ANGLE_A;
|
267
|
+
drop.block = &BLOCKS[ch - '1'];
|
268
|
+
}
|
269
|
+
|
229
|
-
print(
|
270
|
+
print(&panel, &drop);
|
230
|
-
|
231
|
-
|
271
|
+
}
|
272
|
+
|
232
|
-
|
273
|
+
endwin();
|
233
|
-
|
234
|
-
rotate_block(&drop, DIR_RIGHT, &panel); //回転
|
235
|
-
print("さらにさらに右回転後", &panel, &drop);
|
236
274
|
}
|
237
275
|
```
|
238
|
-
実行結果
|
239
|
-
```
|
240
|
-
-- 回転前
|
241
|
-
|
276
|
+
![Cygwinスクリーンショット](https://ddjkaamml8q8x.cloudfront.net/questions/2024-06-21/9605ef96-83cc-4d3f-ab4b-b2d92730390c.png)
|
242
|
-
9 9 0 0 0 0 0 0
|
243
|
-
9 9 0 0 0 0 0 0
|
244
|
-
9 9 0 0 0 0 0 0
|
245
|
-
9 9 0 0 0 0 0 0
|
246
|
-
9 9 0 1 0 0 0 0
|
247
|
-
9 9 1 1 1 0 0 0
|
248
|
-
9 9 9 9 9 9 9 9
|
249
|
-
9 9 9 9 9 9 9 9
|
250
|
-
-- 右回転後
|
251
|
-
軸: x=1, y=3, angle=1
|
252
|
-
9 9 0 0 0 0 0 0
|
253
|
-
9 9 0 0 0 0 0 0
|
254
|
-
9 9 0 0 0 0 0 0
|
255
|
-
9 9 1 0 0 0 0 0
|
256
|
-
9 9 1 1 0 0 0 0
|
257
|
-
9 9 1 0 0 0 0 0
|
258
|
-
9 9 9 9 9 9 9 9
|
259
|
-
9 9 9 9 9 9 9 9
|
260
|
-
-- さらに右回転後
|
261
|
-
軸: x=2, y=3, angle=2
|
262
|
-
9 9 0 0 0 0 0 0
|
263
|
-
9 9 0 0 0 0 0 0
|
264
|
-
9 9 0 0 0 0 0 0
|
265
|
-
9 9 0 0 0 0 0 0
|
266
|
-
9 9 1 1 1 0 0 0
|
267
|
-
9 9 0 1 0 0 0 0
|
268
|
-
9 9 9 9 9 9 9 9
|
269
|
-
9 9 9 9 9 9 9 9
|
270
|
-
-- さらにさらに右回転後
|
271
|
-
軸: x=2, y=3, angle=3
|
272
|
-
9 9 0 0 0 0 0 0
|
273
|
-
9 9 0 0 0 0 0 0
|
274
|
-
9 9 0 0 0 0 0 0
|
275
|
-
9 9 0 1 0 0 0 0
|
276
|
-
9 9 1 1 0 0 0 0
|
277
|
-
9 9 0 1 0 0 0 0
|
278
|
-
9 9 9 9 9 9 9 9
|
279
|
-
9 9 9 9 9 9 9 9
|
280
|
-
```
|
2
画面系を LAYOUT 構造体から PANEL 構造体に変更とか
test
CHANGED
@@ -32,10 +32,14 @@
|
|
32
32
|
1,0, -2,0, -2, 1, 1,-2 //D→C: 1.右1 2.左2 3.左2下1 4.右1上2
|
33
33
|
};
|
34
34
|
|
35
|
-
//ミノ種類
|
35
|
+
//ミノ種類 (=BLOCKS のインデックス)
|
36
36
|
typedef enum {
|
37
|
-
BLOCK_O=0, BLOCK_T, BLOCK_S, BLOCK_Z, BLOCK_L, BLOCK_J, BLOCK_I
|
37
|
+
BLOCK_O=0, BLOCK_T, BLOCK_S, BLOCK_Z, BLOCK_L, BLOCK_J, BLOCK_I, N_BLOCK_TYPES
|
38
38
|
} BLOCK_TYPE;
|
39
|
+
|
40
|
+
//ミノを構成する要素数
|
41
|
+
#define N_ITEMS 4
|
42
|
+
#define N_LEN (N_ITEMS*2) //xy の組数
|
39
43
|
|
40
44
|
//ミノ
|
41
45
|
typedef struct {
|
@@ -50,7 +54,7 @@
|
|
50
54
|
NULL, NULL
|
51
55
|
},
|
52
56
|
{ //T
|
53
|
-
1,
|
57
|
+
1, //回転有り
|
54
58
|
(int[]){
|
55
59
|
1,0, 0,1, 1,1, 2,1, //A
|
56
60
|
1,0, 1,1, 2,1, 1,2, //B
|
@@ -110,31 +114,36 @@
|
|
110
114
|
} DIR;
|
111
115
|
|
112
116
|
typedef enum {
|
113
|
-
ANGLE_A=0, ANGLE_B, ANGLE_C, ANGLE_D
|
117
|
+
ANGLE_A=0, ANGLE_B, ANGLE_C, ANGLE_D, N_ANGLES
|
114
118
|
} ANGLE;
|
115
119
|
|
116
120
|
ANGLE rotate_angle(ANGLE old, DIR dir) {
|
117
|
-
return (old +
|
121
|
+
return (old + N_ANGLES + dir) % N_ANGLES;
|
118
122
|
}
|
119
123
|
|
120
124
|
int *get_angled_layout(BLOCK *block, int angle) {
|
121
|
-
return block->layout + (block->rotate ?
|
125
|
+
return block->layout + (block->rotate ? N_LEN*angle : 0);
|
122
|
-
}
|
126
|
+
}
|
123
|
-
|
124
|
-
#define WIDTH 4
|
125
|
-
#define HEIGHT 4
|
126
|
-
#define PADDING 2
|
127
|
-
#define AREA_WIDTH (WIDTH+PADDING*2)
|
128
|
-
#define AREA_HEIGHT (HEIGHT+PADDING*2)
|
129
127
|
|
130
128
|
typedef struct {
|
131
|
-
int a
|
129
|
+
int width, height, outer_value;
|
130
|
+
int *items;
|
132
|
-
} L
|
131
|
+
} PANEL;
|
132
|
+
|
133
|
-
|
133
|
+
int get_panel_item(PANEL *panel, int x, int y) {
|
134
|
+
if(x < 0 || panel->width <= x || y < 0 || panel->height <= y) return panel->outer_value;
|
135
|
+
return panel->items[panel->width * y + x];
|
136
|
+
}
|
137
|
+
|
138
|
+
void set_panel_item(PANEL *panel, int x, int y, int value) {
|
139
|
+
if(x < 0 || panel->width <= x || y < 0 || panel->height <= y) return;
|
140
|
+
panel->items[panel->width * y + x] = value;
|
141
|
+
}
|
142
|
+
|
134
|
-
int is_placeable(BLOCK *block, int angle, int x, int y, L
|
143
|
+
int is_placeable(BLOCK *block, int angle, int x, int y, PANEL *panel) {
|
135
144
|
int *b = get_angled_layout(block, angle);
|
136
|
-
for(int i=0; i<
|
145
|
+
for(int i=0; i<N_ITEMS; i++, b+=2) {
|
137
|
-
if(l
|
146
|
+
if(get_panel_item(panel, x+b[0], y+b[1])) return 0; //false
|
138
147
|
}
|
139
148
|
return 1; //true
|
140
149
|
}
|
@@ -145,11 +154,11 @@
|
|
145
154
|
ANGLE angle;
|
146
155
|
} DROP_BLOCK;
|
147
156
|
|
148
|
-
void rotate_block(DROP_BLOCK *drop, DIR dir, L
|
157
|
+
void rotate_block(DROP_BLOCK *drop, DIR dir, PANEL *panel) {
|
149
158
|
if(!drop->block->rotate) return; //回転処理は無い
|
150
159
|
|
151
160
|
int new_angle = rotate_angle(drop->angle, dir);
|
152
|
-
if(is_placeable(drop->block, new_angle, drop->x, drop->y, l
|
161
|
+
if(is_placeable(drop->block, new_angle, drop->x, drop->y, panel)) {
|
153
162
|
drop->angle = new_angle;
|
154
163
|
return;
|
155
164
|
}
|
@@ -157,10 +166,11 @@
|
|
157
166
|
int *srs = dir==DIR_RIGHT ? drop->block->srs_r : dir==DIR_LEFT ? drop->block->srs_l : NULL;
|
158
167
|
if(!srs) return; //SRS が無い
|
159
168
|
|
169
|
+
int *p = &srs[drop->angle * 4*2];
|
160
|
-
for(int i=0
|
170
|
+
for(int i=0; i<4; i++) { //srsのデータは dx,dy の組が 4 件固定
|
161
|
-
int new_x = drop->x + p
|
171
|
+
int new_x = drop->x + *p++;
|
162
|
-
int new_y = drop->y + p
|
172
|
+
int new_y = drop->y + *p++;
|
163
|
-
if(is_placeable(drop->block, new_angle, new_x, new_y, l
|
173
|
+
if(is_placeable(drop->block, new_angle, new_x, new_y, panel)) { //軸を移動させれば置けるなら
|
164
174
|
drop->x = new_x; //軸を移動
|
165
175
|
drop->y = new_y;
|
166
176
|
drop->angle = new_angle;
|
@@ -169,40 +179,42 @@
|
|
169
179
|
}
|
170
180
|
}
|
171
181
|
|
172
|
-
int get_block_e
|
182
|
+
int get_block_item(DROP_BLOCK *drop, int x, int y) {
|
173
|
-
x
|
183
|
+
int dx = x - drop->x;
|
174
|
-
y
|
184
|
+
int dy = y - drop->y;
|
175
|
-
if(x < 0 || y < 0) return 0; //範囲外
|
185
|
+
if(dx < 0 || dy < 0) return 0; //範囲外
|
176
186
|
|
177
187
|
int *b = get_angled_layout(drop->block, drop->angle);
|
178
|
-
for(int i=0; i<
|
188
|
+
for(int i=0; i<N_ITEMS; i++, b+=2) {
|
179
|
-
if(b[0] == x && b[1] == y) return 1;
|
189
|
+
if(b[0] == dx && b[1] == dy) return 1;
|
180
190
|
}
|
181
191
|
return 0;
|
182
192
|
}
|
183
193
|
|
184
|
-
void print(L
|
194
|
+
void print(char *title, PANEL *panel, DROP_BLOCK *drop) {
|
195
|
+
printf("-- %s\n", title);
|
185
196
|
printf("軸: x=%d, y=%d, angle=%d\n", drop->x, drop->y, drop->angle);
|
186
|
-
for(int y=0
|
197
|
+
for(int y=0; y<panel->height; y++) {
|
187
|
-
for(int x=0; x<
|
198
|
+
for(int x=0; x<panel->width; x++) {
|
188
|
-
int b = get_block_e
|
199
|
+
int b = get_block_item(drop, x, y);
|
189
|
-
printf(" %d", b?b:l
|
200
|
+
printf(" %d", b?b:get_panel_item(panel,x,y));
|
190
201
|
}
|
191
202
|
printf("\n");
|
192
203
|
}
|
193
204
|
}
|
194
205
|
|
195
206
|
int main(void) {
|
196
|
-
L
|
207
|
+
PANEL panel = {
|
208
|
+
8, 8, 9,
|
197
|
-
|
209
|
+
(int[]){ //空き位置は 0, 障害物は 9
|
198
|
-
|
210
|
+
9,9,0,0,0,0,0,0,
|
199
|
-
|
211
|
+
9,9,0,0,0,0,0,0,
|
200
|
-
|
212
|
+
9,9,0,0,0,0,0,0,
|
201
|
-
|
213
|
+
9,9,0,0,0,0,0,0,
|
202
|
-
|
214
|
+
9,9,0,0,0,0,0,0,
|
203
|
-
|
215
|
+
9,9,0,0,0,0,0,0,
|
216
|
+
9,9,9,9,9,9,9,9,
|
204
|
-
|
217
|
+
9,9,9,9,9,9,9,9 }
|
205
|
-
{ 9,9,9,9,9,9,9,9 } }
|
206
218
|
};
|
207
219
|
|
208
220
|
//初期(これは正常に置けるものとする)
|
@@ -211,24 +223,16 @@
|
|
211
223
|
drop.y = 4;
|
212
224
|
drop.angle = ANGLE_A;
|
213
225
|
drop.block = &BLOCKS[BLOCK_T];
|
214
|
-
|
215
|
-
printf("-- 回転前\n");
|
216
|
-
print(&l
|
226
|
+
print("回転前", &panel, &drop);
|
217
|
-
|
227
|
+
|
218
|
-
rotate_block(&drop, DIR_RIGHT, &l
|
228
|
+
rotate_block(&drop, DIR_RIGHT, &panel); //回転
|
219
|
-
|
220
|
-
printf("-- 右回転後\n");
|
221
|
-
print(&l
|
229
|
+
print("右回転後", &panel, &drop);
|
222
|
-
|
230
|
+
|
223
|
-
rotate_block(&drop, DIR_RIGHT, &l
|
231
|
+
rotate_block(&drop, DIR_RIGHT, &panel); //回転
|
224
|
-
|
225
|
-
printf("-- さらに右回転後\n");
|
226
|
-
print(&l
|
232
|
+
print("さらに右回転後", &panel, &drop);
|
227
|
-
|
233
|
+
|
228
|
-
rotate_block(&drop, DIR_RIGHT, &l
|
234
|
+
rotate_block(&drop, DIR_RIGHT, &panel); //回転
|
229
|
-
|
230
|
-
print
|
235
|
+
print("さらにさらに右回転後", &panel, &drop);
|
231
|
-
print(&layout, &drop);
|
232
236
|
}
|
233
237
|
```
|
234
238
|
実行結果
|
1
もちょっと分かり易そうにしてみた
test
CHANGED
@@ -39,69 +39,68 @@
|
|
39
39
|
|
40
40
|
//ミノ
|
41
41
|
typedef struct {
|
42
|
-
int size; //縦横サイズ
|
43
42
|
int rotate; //回転パターン有無 1=有, 0=無
|
44
|
-
int *layout; //図形パターン
|
43
|
+
int *layout; //図形パターン, xy の組が 4 つ. rotate=1 なら追加で右 90/180/270 度回転パターン
|
45
44
|
int *srs_r, *srs_l; //SRSパターン
|
46
45
|
} BLOCK;
|
47
46
|
BLOCK BLOCKS[] = {
|
48
47
|
{ //O
|
49
|
-
|
48
|
+
0, //回転無し
|
50
|
-
|
49
|
+
(int[]){ 0,0, 0,1, 1,0, 1,1 }, //A
|
51
50
|
NULL, NULL
|
52
51
|
},
|
53
52
|
{ //T
|
54
|
-
|
53
|
+
1,
|
55
|
-
|
54
|
+
(int[]){
|
56
|
-
|
55
|
+
1,0, 0,1, 1,1, 2,1, //A
|
57
|
-
|
56
|
+
1,0, 1,1, 2,1, 1,2, //B
|
58
|
-
0,
|
57
|
+
0,1, 1,1, 2,1, 1,2, //C
|
59
|
-
|
58
|
+
1,0, 0,1, 1,1, 1,2 },//D
|
60
59
|
SRS_3x3_R, SRS_3x3_L
|
61
60
|
},
|
62
61
|
{ //S
|
63
|
-
|
62
|
+
1,
|
64
|
-
|
63
|
+
(int[]){
|
65
|
-
0,1,1, 1,1,0, 0,0,0,
|
66
|
-
0,
|
64
|
+
1,0, 2,0, 0,1, 1,1,
|
65
|
+
1,0, 1,1, 2,1, 2,2,
|
66
|
+
1,1, 2,1, 0,2, 1,2,
|
67
|
-
0,0,
|
67
|
+
0,0, 0,1, 1,1, 1,2 },
|
68
|
-
1,0,0, 1,1,0, 0,1,0 },
|
69
68
|
SRS_3x3_R, SRS_3x3_L
|
70
69
|
},
|
71
70
|
{ //Z
|
72
|
-
|
71
|
+
1,
|
73
|
-
|
72
|
+
(int[]){
|
74
|
-
1,1,0, 0,1,1, 0,0,0,
|
75
|
-
0,0,1,
|
73
|
+
0,0, 1,0, 1,1, 2,1,
|
76
|
-
|
74
|
+
2,0, 1,1, 2,1, 1,2,
|
75
|
+
0,1, 1,1, 1,2, 2,2,
|
77
|
-
|
76
|
+
1,0, 0,1, 1,1, 0,2 },
|
78
77
|
SRS_3x3_R, SRS_3x3_L
|
79
78
|
},
|
80
79
|
{ //L
|
81
|
-
|
80
|
+
1,
|
82
|
-
|
81
|
+
(int[]){
|
82
|
+
2,0, 0,1, 1,1, 2,1,
|
83
|
+
1,0, 1,1, 1,2, 2,2,
|
84
|
+
0,1, 1,1, 2,1, 0,2,
|
83
|
-
0,0,1,
|
85
|
+
0,0, 1,0, 1,1, 1,2 },
|
84
|
-
0,1,0, 0,1,0, 0,1,1,
|
85
|
-
0,0,0, 1,1,1, 1,0,0,
|
86
|
-
1,1,0, 0,1,0, 0,1,0 },
|
87
86
|
SRS_3x3_R, SRS_3x3_L
|
88
87
|
},
|
89
88
|
{ //J
|
90
|
-
|
89
|
+
1,
|
91
|
-
|
90
|
+
(int[]){
|
92
|
-
1,0,0, 1,1,1, 0,0,0,
|
93
|
-
0,1,1, 0,1,0, 0,1,0,
|
94
|
-
0,0,0,
|
91
|
+
0,0, 0,1, 1,1, 2,1,
|
92
|
+
1,0, 2,0, 1,1, 1,2,
|
93
|
+
0,1, 1,1, 2,1, 2,2,
|
95
|
-
|
94
|
+
1,0, 1,1, 0,2, 1,2 },
|
96
95
|
SRS_3x3_R, SRS_3x3_L
|
97
96
|
},
|
98
97
|
{ //I
|
99
|
-
|
98
|
+
1,
|
100
|
-
|
99
|
+
(int[]){
|
101
|
-
0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0,
|
102
|
-
0,
|
100
|
+
0,1, 1,1, 2,1, 3,1,
|
103
|
-
|
101
|
+
2,0, 2,1, 2,2, 2,3,
|
102
|
+
0,2, 1,2, 2,2, 3,2,
|
104
|
-
|
103
|
+
1,0, 1,1, 1,2, 1,3 },
|
105
104
|
SRS_I_R, SRS_I_L
|
106
105
|
}
|
107
106
|
};
|
@@ -119,105 +118,159 @@
|
|
119
118
|
}
|
120
119
|
|
121
120
|
int *get_angled_layout(BLOCK *block, int angle) {
|
122
|
-
return block->layout + (block->rotate ?
|
121
|
+
return block->layout + (block->rotate ? 4*2*angle : 0);
|
123
|
-
}
|
122
|
+
}
|
123
|
+
|
124
|
-
|
124
|
+
#define WIDTH 4
|
125
|
+
#define HEIGHT 4
|
126
|
+
#define PADDING 2
|
127
|
+
#define AREA_WIDTH (WIDTH+PADDING*2)
|
128
|
+
#define AREA_HEIGHT (HEIGHT+PADDING*2)
|
129
|
+
|
130
|
+
typedef struct {
|
131
|
+
int area[AREA_HEIGHT][AREA_WIDTH];
|
132
|
+
} LAYOUT;
|
133
|
+
|
125
|
-
int is_placeable(BLOCK *block, int angle, int x, int y,
|
134
|
+
int is_placeable(BLOCK *block, int angle, int x, int y, LAYOUT *layout) {
|
126
|
-
int *start = &layout[layout_size * y + x];
|
127
135
|
int *b = get_angled_layout(block, angle);
|
128
|
-
for(int
|
136
|
+
for(int i=0; i<4; i++, b+=2) {
|
129
|
-
for(int xx=0, *p=start; xx<block->size; xx++, p++, b++) {
|
130
|
-
|
137
|
+
if(layout->area[y+b[1]][x+b[0]]) return 0; //false
|
138
|
+
}
|
139
|
+
return 1; //true
|
140
|
+
}
|
141
|
+
|
142
|
+
typedef struct {
|
143
|
+
BLOCK *block;
|
144
|
+
int x, y;
|
145
|
+
ANGLE angle;
|
146
|
+
} DROP_BLOCK;
|
147
|
+
|
148
|
+
void rotate_block(DROP_BLOCK *drop, DIR dir, LAYOUT *layout) {
|
149
|
+
if(!drop->block->rotate) return; //回転処理は無い
|
150
|
+
|
151
|
+
int new_angle = rotate_angle(drop->angle, dir);
|
152
|
+
if(is_placeable(drop->block, new_angle, drop->x, drop->y, layout)) {
|
153
|
+
drop->angle = new_angle;
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
|
157
|
+
int *srs = dir==DIR_RIGHT ? drop->block->srs_r : dir==DIR_LEFT ? drop->block->srs_l : NULL;
|
158
|
+
if(!srs) return; //SRS が無い
|
159
|
+
|
160
|
+
for(int i=0, *p=&srs[drop->angle*8]; i<4; i++, p+=2) { //srsのデータは dx,dy の組が 4 件固定
|
161
|
+
int new_x = drop->x + p[0];
|
162
|
+
int new_y = drop->y + p[1];
|
163
|
+
if(is_placeable(drop->block, new_angle, new_x, new_y, layout)) { //軸を移動させれば置けるなら
|
131
|
-
|
164
|
+
drop->x = new_x; //軸を移動
|
165
|
+
drop->y = new_y;
|
166
|
+
drop->angle = new_angle;
|
167
|
+
return;
|
132
168
|
}
|
133
169
|
}
|
134
|
-
return 1; //true
|
135
|
-
}
|
170
|
+
}
|
136
|
-
|
171
|
+
|
137
|
-
|
172
|
+
int get_block_element(DROP_BLOCK *drop, int x, int y) {
|
173
|
+
x -= drop->x;
|
174
|
+
y -= drop->y;
|
138
|
-
i
|
175
|
+
if(x < 0 || y < 0) return 0; //範囲外
|
176
|
+
|
139
|
-
int *b = get_angled_layout(block, angle);
|
177
|
+
int *b = get_angled_layout(drop->block, drop->angle);
|
140
|
-
for(int
|
178
|
+
for(int i=0; i<4; i++, b+=2) {
|
141
|
-
f
|
179
|
+
if(b[0] == x && b[1] == y) return 1;
|
142
|
-
if(*b) *p = v;
|
143
|
-
|
180
|
+
}
|
181
|
+
return 0;
|
144
|
-
|
182
|
+
}
|
145
|
-
|
183
|
+
|
146
|
-
|
147
|
-
void print(
|
184
|
+
void print(LAYOUT *layout, DROP_BLOCK *drop) {
|
185
|
+
printf("軸: x=%d, y=%d, angle=%d\n", drop->x, drop->y, drop->angle);
|
148
|
-
for(int y=0, i=0; y<
|
186
|
+
for(int y=0, i=0; y<AREA_HEIGHT; y++) {
|
149
|
-
for(int x=0; x<
|
187
|
+
for(int x=0; x<AREA_WIDTH; x++, i++) {
|
188
|
+
int b = get_block_element(drop, x, y);
|
150
|
-
printf(" %d", layout[
|
189
|
+
printf(" %d", b?b:layout->area[y][x]);
|
151
190
|
}
|
152
191
|
printf("\n");
|
153
192
|
}
|
154
193
|
}
|
155
194
|
|
156
|
-
|
195
|
+
int main(void) {
|
196
|
+
LAYOUT layout = {
|
157
|
-
|
197
|
+
{ //空き位置は 0, 障害物は 9
|
158
|
-
|
198
|
+
{ 9,9,0,0,0,0,0,0 },
|
159
|
-
|
199
|
+
{ 9,9,0,0,0,0,0,0 },
|
160
|
-
|
200
|
+
{ 9,9,0,0,0,0,0,0 },
|
161
|
-
|
201
|
+
{ 9,9,0,0,0,0,0,0 },
|
202
|
+
{ 9,9,0,0,0,0,0,0 },
|
203
|
+
{ 9,9,0,0,0,0,0,0 },
|
162
|
-
9,9,9,9,9,9,9,9,
|
204
|
+
{ 9,9,9,9,9,9,9,9 },
|
163
|
-
|
205
|
+
{ 9,9,9,9,9,9,9,9 } }
|
164
|
-
0,9,0,0,0,0,0,0,
|
165
|
-
0,9,0,0,0,0,0,0
|
166
206
|
};
|
167
|
-
int layout_size = 8;
|
168
207
|
|
169
208
|
//初期(これは正常に置けるものとする)
|
209
|
+
DROP_BLOCK drop;
|
210
|
+
drop.x = 2;
|
211
|
+
drop.y = 4;
|
212
|
+
drop.angle = ANGLE_A;
|
170
|
-
|
213
|
+
drop.block = &BLOCKS[BLOCK_T];
|
171
|
-
|
214
|
+
|
172
|
-
int old_angle = ANGLE_A;
|
173
|
-
|
174
|
-
printf("--
|
215
|
+
printf("-- 回転前\n");
|
175
|
-
set_pattern(block, old_angle, x, y, 1, layout, layout_size); //'1'として表示
|
176
|
-
print(
|
216
|
+
print(&layout, &drop);
|
177
|
-
|
178
|
-
|
217
|
+
|
179
|
-
int dir = DIR_RIGHT;
|
180
|
-
int new_angle = rotate_angle(old_angle, dir);
|
181
|
-
|
182
|
-
if(block->rotate) {
|
183
|
-
|
218
|
+
rotate_block(&drop, DIR_RIGHT, &layout); //回転
|
184
|
-
|
219
|
+
|
185
|
-
if(!placeable && srs) { //回転したら障害物に引っ掛かるけれども SRS のパターンがあるなら
|
186
|
-
for(int i=0, *p=&srs[old_angle*8]; i<4; i++, p+=2) { //srsのデータは x,y の組が 4 件固定
|
187
|
-
placeable = is_placeable(block, new_angle, x+p[0], y+p[1], layout, layout_size);
|
188
|
-
if(placeable) { //軸を移動させれば置けるってことで
|
189
|
-
x += p[0]; //軸を移動
|
190
|
-
y += p[1];
|
191
|
-
break;
|
192
|
-
}
|
193
|
-
}
|
194
|
-
}
|
195
|
-
if(!placeable) new_angle = old_angle; //やっぱ置けないので回転をキャンセル
|
196
|
-
}
|
197
|
-
|
198
|
-
printf("--
|
220
|
+
printf("-- 右回転後\n");
|
199
|
-
set_pattern(block, new_angle, x, y, 2, layout, layout_size); //'2'として表示
|
200
|
-
print(
|
221
|
+
print(&layout, &drop);
|
222
|
+
|
223
|
+
rotate_block(&drop, DIR_RIGHT, &layout); //回転
|
224
|
+
|
225
|
+
printf("-- さらに右回転後\n");
|
226
|
+
print(&layout, &drop);
|
227
|
+
|
228
|
+
rotate_block(&drop, DIR_RIGHT, &layout); //回転
|
229
|
+
|
230
|
+
printf("-- さらにさらに右回転後\n");
|
231
|
+
print(&layout, &drop);
|
201
232
|
}
|
202
233
|
```
|
203
234
|
実行結果
|
204
235
|
```
|
205
|
-
--
|
236
|
+
-- 回転前
|
237
|
+
軸: x=2, y=4, angle=0
|
206
|
-
|
238
|
+
9 9 0 0 0 0 0 0
|
207
|
-
|
239
|
+
9 9 0 0 0 0 0 0
|
240
|
+
9 9 0 0 0 0 0 0
|
241
|
+
9 9 0 0 0 0 0 0
|
208
|
-
|
242
|
+
9 9 0 1 0 0 0 0
|
209
|
-
|
243
|
+
9 9 1 1 1 0 0 0
|
210
|
-
9 9 9 9 9 9 9 9
|
244
|
+
9 9 9 9 9 9 9 9
|
211
|
-
0 9 0 0 0 0 0 0
|
212
|
-
0 9 0 0 0 0 0 0
|
213
|
-
0 9 0 0 0 0 0 0
|
214
|
-
---回転後
|
215
|
-
0 9 0 0 0 0 0 0
|
216
|
-
0 9 2 0 0 0 0 0
|
217
|
-
0 9 2 2 0 0 0 0
|
218
|
-
0 9 2 1 1 0 0 0
|
219
|
-
9 9 9 9 9 9 9 9
|
245
|
+
9 9 9 9 9 9 9 9
|
246
|
+
-- 右回転後
|
247
|
+
軸: x=1, y=3, angle=1
|
220
|
-
|
248
|
+
9 9 0 0 0 0 0 0
|
221
|
-
|
249
|
+
9 9 0 0 0 0 0 0
|
222
|
-
|
250
|
+
9 9 0 0 0 0 0 0
|
251
|
+
9 9 1 0 0 0 0 0
|
252
|
+
9 9 1 1 0 0 0 0
|
253
|
+
9 9 1 0 0 0 0 0
|
254
|
+
9 9 9 9 9 9 9 9
|
255
|
+
9 9 9 9 9 9 9 9
|
256
|
+
-- さらに右回転後
|
257
|
+
軸: x=2, y=3, angle=2
|
258
|
+
9 9 0 0 0 0 0 0
|
259
|
+
9 9 0 0 0 0 0 0
|
260
|
+
9 9 0 0 0 0 0 0
|
261
|
+
9 9 0 0 0 0 0 0
|
262
|
+
9 9 1 1 1 0 0 0
|
263
|
+
9 9 0 1 0 0 0 0
|
264
|
+
9 9 9 9 9 9 9 9
|
265
|
+
9 9 9 9 9 9 9 9
|
266
|
+
-- さらにさらに右回転後
|
267
|
+
軸: x=2, y=3, angle=3
|
268
|
+
9 9 0 0 0 0 0 0
|
269
|
+
9 9 0 0 0 0 0 0
|
270
|
+
9 9 0 0 0 0 0 0
|
271
|
+
9 9 0 1 0 0 0 0
|
272
|
+
9 9 1 1 0 0 0 0
|
273
|
+
9 9 0 1 0 0 0 0
|
274
|
+
9 9 9 9 9 9 9 9
|
275
|
+
9 9 9 9 9 9 9 9
|
223
276
|
```
|