回答編集履歴

4

使わなくなってた関数の削除

2024/06/22 07:29

投稿

jimbe
jimbe

スコア13168

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

コードをゲームを模した形に変更

2024/06/21 07:03

投稿

jimbe
jimbe

スコア13168

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 <stdio.h>
7
+ #include <unistd.h>
6
-
7
- //https://tetrisch.github.io/main/srs.html より
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(char *title, PANEL *panel, DROP_BLOCK *drop) {
201
+ void print(PANEL *panel, DROP_BLOCK *drop) {
195
- printf("-- %s\n", title);
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
- printf(" %d", b?b:get_panel_item(panel,x,y));
208
+ mvprintw(y, xx, y==panel->height?"==":get_panel_item(panel,x,y)?"[]":" ");
201
- }
209
+ }
202
- printf("\n");
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
- 8, 8, 9,
221
+ 10, 12, 2,
209
- (int[]){ //空き位置は 0, 障害物は 9
222
+ (int[]){ //空き位置は 0, 障害物は !0
210
- 9,9,0,0,0,0,0,0,
223
+ 0,0,0,0,0,0,0,0,0,0,
211
- 9,9,0,0,0,0,0,0,
224
+ 0,0,0,0,0,0,0,0,0,0,
212
- 9,9,0,0,0,0,0,0,
225
+ 0,0,0,0,0,0,0,0,0,0,
213
- 9,9,0,0,0,0,0,0,
226
+ 0,0,0,0,0,0,0,0,0,0,
214
- 9,9,0,0,0,0,0,0,
227
+ 0,0,0,0,0,0,0,0,0,0,
215
- 9,9,0,0,0,0,0,0,
228
+ 0,0,0,0,0,0,0,0,0,0,
216
- 9,9,9,9,9,9,9,9,
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
- 9,9,9,9,9,9,9,9 }
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 = 2;
246
+ drop.x = 4;
223
- drop.y = 4;
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
- print("回転前", &panel, &drop);
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("右回転後", &panel, &drop);
270
+ print(&panel, &drop);
230
-
231
- rotate_block(&drop, DIR_RIGHT, &panel); //回転
271
+ }
272
+
232
- print("さらに右回転後", &panel, &drop);
273
+ endwin();
233
-
234
- rotate_block(&drop, DIR_RIGHT, &panel); //回転
235
- print("さらにさらに右回転後", &panel, &drop);
236
274
  }
237
275
  ```
238
- 実行結果
239
- ```
240
- -- 回転前
241
- : x=2, y=4, angle=0
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 構造体に変更とか

2024/06/19 13:57

投稿

jimbe
jimbe

スコア13168

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 + 4 + dir) % 4;
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 ? 4*2*angle : 0);
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 area[AREA_HEIGHT][AREA_WIDTH];
129
+ int width, height, outer_value;
130
+ int *items;
132
- } LAYOUT;
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, LAYOUT *layout) {
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<4; i++, b+=2) {
145
+ for(int i=0; i<N_ITEMS; i++, b+=2) {
137
- if(layout->area[y+b[1]][x+b[0]]) return 0; //false
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, LAYOUT *layout) {
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, layout)) {
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, *p=&srs[drop->angle*8]; i<4; i++, p+=2) { //srsのデータは dx,dy の組が 4 件固定
170
+ for(int i=0; i<4; i++) { //srsのデータは dx,dy の組が 4 件固定
161
- int new_x = drop->x + p[0];
171
+ int new_x = drop->x + *p++;
162
- int new_y = drop->y + p[1];
172
+ int new_y = drop->y + *p++;
163
- if(is_placeable(drop->block, new_angle, new_x, new_y, layout)) { //軸を移動させれば置けるなら
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_element(DROP_BLOCK *drop, int x, int y) {
182
+ int get_block_item(DROP_BLOCK *drop, int x, int y) {
173
- x -= drop->x;
183
+ int dx = x - drop->x;
174
- y -= drop->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<4; i++, b+=2) {
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(LAYOUT *layout, DROP_BLOCK *drop) {
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, i=0; y<AREA_HEIGHT; y++) {
197
+ for(int y=0; y<panel->height; y++) {
187
- for(int x=0; x<AREA_WIDTH; x++, i++) {
198
+ for(int x=0; x<panel->width; x++) {
188
- int b = get_block_element(drop, x, y);
199
+ int b = get_block_item(drop, x, y);
189
- printf(" %d", b?b:layout->area[y][x]);
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
- LAYOUT layout = {
207
+ PANEL panel = {
208
+ 8, 8, 9,
197
- { //空き位置は 0, 障害物は 9
209
+ (int[]){ //空き位置は 0, 障害物は 9
198
- { 9,9,0,0,0,0,0,0 },
210
+ 9,9,0,0,0,0,0,0,
199
- { 9,9,0,0,0,0,0,0 },
211
+ 9,9,0,0,0,0,0,0,
200
- { 9,9,0,0,0,0,0,0 },
212
+ 9,9,0,0,0,0,0,0,
201
- { 9,9,0,0,0,0,0,0 },
213
+ 9,9,0,0,0,0,0,0,
202
- { 9,9,0,0,0,0,0,0 },
214
+ 9,9,0,0,0,0,0,0,
203
- { 9,9,0,0,0,0,0,0 },
215
+ 9,9,0,0,0,0,0,0,
216
+ 9,9,9,9,9,9,9,9,
204
- { 9,9,9,9,9,9,9,9 },
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(&layout, &drop);
226
+ print("回転前", &panel, &drop);
217
-
227
+
218
- rotate_block(&drop, DIR_RIGHT, &layout); //回転
228
+ rotate_block(&drop, DIR_RIGHT, &panel); //回転
219
-
220
- printf("-- 右回転後\n");
221
- print(&layout, &drop);
229
+ print("右回転後", &panel, &drop);
222
-
230
+
223
- rotate_block(&drop, DIR_RIGHT, &layout); //回転
231
+ rotate_block(&drop, DIR_RIGHT, &panel); //回転
224
-
225
- printf("-- さらに右回転後\n");
226
- print(&layout, &drop);
232
+ print("さらに右回転後", &panel, &drop);
227
-
233
+
228
- rotate_block(&drop, DIR_RIGHT, &layout); //回転
234
+ rotate_block(&drop, DIR_RIGHT, &panel); //回転
229
-
230
- printf("-- さらにさらに右回転後\n");
235
+ print("さらにさらに右回転後", &panel, &drop);
231
- print(&layout, &drop);
232
236
  }
233
237
  ```
234
238
  実行結果

1

もちょっと分かり易そうにしてみた

2024/06/19 08:25

投稿

jimbe
jimbe

スコア13168

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; //図形パターン. size*size 1 パターン, rotate=1 なら追加で右 90/180/270 度回転パターン
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
- 2, 0, //回転無し
48
+ 0, //回転無し
50
- &(int[]){1,1, 1,1}, //A
49
+ (int[]){ 0,0, 0,1, 1,0, 1,1 }, //A
51
50
  NULL, NULL
52
51
  },
53
52
  { //T
54
- 3, 1,
53
+ 1,
55
- &(int[]){
54
+ (int[]){
56
- 0,1,0, 1,1,1, 0,0,0, //A
55
+ 1,0, 0,1, 1,1, 2,1, //A
57
- 0,1,0, 0,1,1, 0,1,0, //B
56
+ 1,0, 1,1, 2,1, 1,2, //B
58
- 0,0,0, 1,1,1, 0,1,0, //C
57
+ 0,1, 1,1, 2,1, 1,2, //C
59
- 0,1,0, 1,1,0, 0,1,0 },//D
58
+ 1,0, 0,1, 1,1, 1,2 },//D
60
59
  SRS_3x3_R, SRS_3x3_L
61
60
  },
62
61
  { //S
63
- 3, 1,
62
+ 1,
64
- &(int[]){
63
+ (int[]){
65
- 0,1,1, 1,1,0, 0,0,0,
66
- 0,1,0, 0,1,1, 0,0,1,
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,0, 0,1,1, 1,1,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
- 3, 1,
71
+ 1,
73
- &(int[]){
72
+ (int[]){
74
- 1,1,0, 0,1,1, 0,0,0,
75
- 0,0,1, 0,1,1, 0,1,0,
73
+ 0,0, 1,0, 1,1, 2,1,
76
- 0,0,0, 1,1,0, 0,1,1,
74
+ 2,0, 1,1, 2,1, 1,2,
75
+ 0,1, 1,1, 1,2, 2,2,
77
- 0,1,0, 1,1,0, 1,0,0 },
76
+ 1,0, 0,1, 1,1, 0,2 },
78
77
  SRS_3x3_R, SRS_3x3_L
79
78
  },
80
79
  { //L
81
- 3, 1,
80
+ 1,
82
- &(int[]){
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, 1,1,1, 0,0,0,
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
- 3, 1,
89
+ 1,
91
- &(int[]){
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, 1,1,1, 0,0,1,
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
- 0,1,0, 0,1,0, 1,1,0 },
94
+ 1,0, 1,1, 0,2, 1,2 },
96
95
  SRS_3x3_R, SRS_3x3_L
97
96
  },
98
97
  { //I
99
- 4, 1,
98
+ 1,
100
- &(int[]){
99
+ (int[]){
101
- 0,0,0,0, 1,1,1,1, 0,0,0,0, 0,0,0,0,
102
- 0,0,1,0, 0,0,1,0, 0,0,1,0, 0,0,1,0,
100
+ 0,1, 1,1, 2,1, 3,1,
103
- 0,0,0,0, 0,0,0,0, 1,1,1,1, 0,0,0,0,
101
+ 2,0, 2,1, 2,2, 2,3,
102
+ 0,2, 1,2, 2,2, 3,2,
104
- 0,1,0,0, 0,1,0,0, 0,1,0,0, 0,1,0,0 },
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 ? block->size*block->size*angle : 0);
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, int *layout, int layout_size) {
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 yy=0; yy<block->size; yy++, start+=layout_size) {
136
+ for(int i=0; i<4; i++, b+=2) {
129
- for(int xx=0, *p=start; xx<block->size; xx++, p++, b++) {
130
- if(*b && *p == 9) return 0; //false
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
- //↑ の *p==9 はテスト用、実際は *p になるはず
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
- void set_pattern(BLOCK *block, int angle, int x, int y, int v, int *layout, int layout_size) {
172
+ int get_block_element(DROP_BLOCK *drop, int x, int y) {
173
+ x -= drop->x;
174
+ y -= drop->y;
138
- int *start = &layout[layout_size * y + x];
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 yy=0; yy<block->size; yy++, start+=layout_size) {
178
+ for(int i=0; i<4; i++, b+=2) {
141
- for(int xx=0, *p=start; xx<block->size; xx++, p++, b++) {
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(int size, int *layout) {
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<size; y++) {
186
+ for(int y=0, i=0; y<AREA_HEIGHT; y++) {
149
- for(int x=0; x<size; x++, i++) {
187
+ for(int x=0; x<AREA_WIDTH; x++, i++) {
188
+ int b = get_block_element(drop, x, y);
150
- printf(" %d", layout[i]);
189
+ printf(" %d", b?b:layout->area[y][x]);
151
190
  }
152
191
  printf("\n");
153
192
  }
154
193
  }
155
194
 
156
- void main(void) {
195
+ int main(void) {
196
+ LAYOUT layout = {
157
- int layout[8*8] = { //空き位置は 0, 障害物は 9
197
+ { //空き位置は 0, 障害物は 9
158
- 0,9,0,0,0,0,0,0,
198
+ { 9,9,0,0,0,0,0,0 },
159
- 0,9,0,0,0,0,0,0,
199
+ { 9,9,0,0,0,0,0,0 },
160
- 0,9,0,0,0,0,0,0,
200
+ { 9,9,0,0,0,0,0,0 },
161
- 0,9,0,0,0,0,0,0,
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
- 0,9,0,0,0,0,0,0,
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
- BLOCK *block = &BLOCKS[BLOCK_T];
213
+ drop.block = &BLOCKS[BLOCK_T];
171
- int x = 2, y = 2;
214
+
172
- int old_angle = ANGLE_A;
173
-
174
- printf("---回転前\n");
215
+ printf("-- 回転前\n");
175
- set_pattern(block, old_angle, x, y, 1, layout, layout_size); //'1'として表示
176
- print(8, layout);
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
- int placeable = is_placeable(block, new_angle, x, y, layout, layout_size);
218
+ rotate_block(&drop, DIR_RIGHT, &layout); //回転
184
- int *srs = dir==DIR_RIGHT ? block->srs_r : dir==DIR_LEFT ? block->srs_l : NULL;
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("---回転後\n");
220
+ printf("--回転後\n");
199
- set_pattern(block, new_angle, x, y, 2, layout, layout_size); //'2'として表示
200
- print(8, layout);
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
- 0 9 0 0 0 0 0 0
238
+ 9 9 0 0 0 0 0 0
207
- 0 9 0 0 0 0 0 0
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
- 0 9 0 1 0 0 0 0
242
+ 9 9 0 1 0 0 0 0
209
- 0 9 1 1 1 0 0 0
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
- 0 9 0 0 0 0 0 0
248
+ 9 9 0 0 0 0 0 0
221
- 0 9 0 0 0 0 0 0
249
+ 9 9 0 0 0 0 0 0
222
- 0 9 0 0 0 0 0 0
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
  ```