質問編集履歴

3

微調整

2016/11/22 14:18

投稿

mightyMask
mightyMask

スコア143

test CHANGED
File without changes
test CHANGED
@@ -78,7 +78,7 @@
78
78
 
79
79
  ###ソースコード
80
80
 
81
- ```TetKind.java
81
+ ```java
82
82
 
83
83
  public enum TetKind
84
84
 

2

ソースコードを載せた

2016/11/22 14:18

投稿

mightyMask
mightyMask

スコア143

test CHANGED
File without changes
test CHANGED
@@ -73,3 +73,867 @@
73
73
 
74
74
 
75
75
  4.フィールドクラスは外部のクラス( GUIを担当しているクラス等 )の属性として持つものとして設計するのが良いと思いますが、ミノを置いたという事や列を消去したという事、その際t-spin等特殊な条件を満たしているかどうかという事を外部のクラスへ通知しなくてはなりません。この場合どのような方法を用いるのが適切でしょうか。
76
+
77
+
78
+
79
+ ###ソースコード
80
+
81
+ ```TetKind.java
82
+
83
+ public enum TetKind
84
+
85
+ {
86
+
87
+ Empty,
88
+
89
+ Ghost,
90
+
91
+ Z,
92
+
93
+ L,
94
+
95
+ O,
96
+
97
+ S,
98
+
99
+ I,
100
+
101
+ J,
102
+
103
+ T;
104
+
105
+
106
+
107
+ public static int cnt = 7;
108
+
109
+ }
110
+
111
+ ```
112
+
113
+ ```java
114
+
115
+ public class Mino
116
+
117
+ {
118
+
119
+ // 属性
120
+
121
+ TetKind type;
122
+
123
+ private int x, y; // 左上の座標
124
+
125
+ private boolean[][] shape;
126
+
127
+
128
+
129
+ // コンストラクタ
130
+
131
+ Mino( TetKind type )
132
+
133
+ {
134
+
135
+ this.type = type;
136
+
137
+
138
+
139
+ switch( type )
140
+
141
+ {
142
+
143
+ case Z:
144
+
145
+ x = 3; y = 1;
146
+
147
+ shape = new boolean[][]
148
+
149
+ { { true , true , false }, // ■■□
150
+
151
+ { false, true , true }, // □■■
152
+
153
+ { false, false, false } }; // □□□
154
+
155
+ break;
156
+
157
+
158
+
159
+ case L:
160
+
161
+ x = 3; y = 1;
162
+
163
+ shape = new boolean[][]
164
+
165
+ { { false, false, true }, // □□■
166
+
167
+ { true , true , true }, // ■■■
168
+
169
+ { false, false, false } }; // □□□
170
+
171
+ break;
172
+
173
+
174
+
175
+ case O:
176
+
177
+ x = 4; y = 1;
178
+
179
+ shape = new boolean[][]
180
+
181
+ { { true , true }, // ■■
182
+
183
+ { true , true } }; // ■■
184
+
185
+ break;
186
+
187
+
188
+
189
+ case S:
190
+
191
+ x = 3; y = 1;
192
+
193
+ shape = new boolean[][]
194
+
195
+ { { false, true , true }, // □■■
196
+
197
+ { true , true , false }, // ■■□
198
+
199
+ { false, false, false } }; // □□□
200
+
201
+ break;
202
+
203
+
204
+
205
+ case I:
206
+
207
+ x = 3; y = 1;
208
+
209
+ shape = new boolean[][]
210
+
211
+ { { false, false, false, false }, // □□□□
212
+
213
+ { true , true , true , true }, // ■■■■
214
+
215
+ { false, false, false, false }, // □□□□
216
+
217
+ { false, false, false, false } }; // □□□□
218
+
219
+ break;
220
+
221
+
222
+
223
+ case J:
224
+
225
+ x = 3; y = 1;
226
+
227
+ shape = new boolean[][]
228
+
229
+ { { true , false, false }, // ■□□
230
+
231
+ { true , true , true }, // ■■■
232
+
233
+ { false, false, false } }; // □□□
234
+
235
+ break;
236
+
237
+
238
+
239
+ case T:
240
+
241
+ x = 3; y = 1;
242
+
243
+ shape = new boolean[][]
244
+
245
+ { { false, true , false }, // □■□
246
+
247
+ { true , true , true }, // ■■■
248
+
249
+ { false, false, false } }; // □□□
250
+
251
+ break;
252
+
253
+ }
254
+
255
+ }
256
+
257
+
258
+
259
+ // メソッド
260
+
261
+ public Mino copy()
262
+
263
+ {
264
+
265
+ Mino ret = new Mino( this.type );
266
+
267
+ ret.shape = copy( this.shape );
268
+
269
+ ret.x = this.x;
270
+
271
+ ret.y = this.y;
272
+
273
+
274
+
275
+ return ret;
276
+
277
+ }
278
+
279
+
280
+
281
+ private boolean[][] copy( boolean[][] args )
282
+
283
+ {
284
+
285
+ boolean[][] ret = new boolean[args.length][args[0].length];
286
+
287
+
288
+
289
+ for( int x=0 ; x< args .length ; x++ ){
290
+
291
+ for( int y=0 ; y< args[0].length ; y++ ){
292
+
293
+ ret[y][x] = args[y][x];
294
+
295
+ }
296
+
297
+ }
298
+
299
+
300
+
301
+ return ret;
302
+
303
+ }
304
+
305
+
306
+
307
+ // 引数の座標にミノがあるか
308
+
309
+ boolean isExistMino( int x, int y )
310
+
311
+ {
312
+
313
+ if( x < this.x || x >= this.x + shape.length ||
314
+
315
+ y < this.y || y >= this.y + shape.length ){
316
+
317
+ return false;
318
+
319
+ }else{
320
+
321
+ return shape[ y - this.y ][ x - this.x ];
322
+
323
+ }
324
+
325
+ }
326
+
327
+
328
+
329
+ // 右回転(変形)
330
+
331
+ void rotateRight()
332
+
333
+ {
334
+
335
+ boolean[][] temp = copy( shape );
336
+
337
+ for( int x = 0 ; x < shape.length ; x++ ){
338
+
339
+ for( int y = 0 ; y < shape.length ; y++ ){
340
+
341
+ shape[y][x] = temp[shape.length -x -1][y];
342
+
343
+ }
344
+
345
+ }
346
+
347
+ }
348
+
349
+
350
+
351
+ // 左回転(変形)
352
+
353
+ void rotateLeft()
354
+
355
+ {
356
+
357
+ boolean[][] temp = copy( shape );
358
+
359
+ for( int x = 0 ; x < shape.length ; x++ ){
360
+
361
+ for( int y = 0 ; y < shape.length ; y++ ){
362
+
363
+ shape[y][x] = temp[x][shape.length -y -1];
364
+
365
+ }
366
+
367
+ }
368
+
369
+ }
370
+
371
+
372
+
373
+ void moveRight()
374
+
375
+ {
376
+
377
+ x++;
378
+
379
+ }
380
+
381
+
382
+
383
+ void moveLeft()
384
+
385
+ {
386
+
387
+ x--;
388
+
389
+ }
390
+
391
+
392
+
393
+ void moveUp()
394
+
395
+ {
396
+
397
+ y--;
398
+
399
+ }
400
+
401
+
402
+
403
+ void moveDown()
404
+
405
+ {
406
+
407
+ y++;
408
+
409
+ }
410
+
411
+ }
412
+
413
+ ```
414
+
415
+ ```java
416
+
417
+ public class Field extends Thread
418
+
419
+ {
420
+
421
+ // 定数
422
+
423
+ final public static int ROW = 22;
424
+
425
+ final public static int COL = 10;
426
+
427
+
428
+
429
+ // 属性
430
+
431
+ private TetKind[][] map = new TetKind[ROW][COL];
432
+
433
+
434
+
435
+ private Mino mino;
436
+
437
+ private Mino ghost;
438
+
439
+
440
+
441
+ private TetKind[] order = { TetKind.Z, TetKind.L, TetKind.O, TetKind.S, TetKind.I, TetKind.J, TetKind.T };
442
+
443
+ private int orderNow = 0; // orderのカウンタ変数
444
+
445
+
446
+
447
+ private TetKind[] next = new TetKind[ TetKind.cnt ];
448
+
449
+ private TetKind hold = TetKind.Empty;
450
+
451
+ private boolean holdFlag;
452
+
453
+
454
+
455
+ public long rate = 1000;
456
+
457
+
458
+
459
+ // コンストラクタ
460
+
461
+ public Field()
462
+
463
+ {
464
+
465
+ // フィールドを全て空にする
466
+
467
+ for( int y=0 ; y< ROW ; y++ ){
468
+
469
+ for( int x=0 ; x< COL ; x++ ){
470
+
471
+ map[y][x] = TetKind.Empty;
472
+
473
+ }
474
+
475
+ }
476
+
477
+
478
+
479
+ orderShuffle();
480
+
481
+ for( int i=0 ; i< TetKind.cnt ; i++ ){
482
+
483
+ next[i] = order[i];
484
+
485
+ }
486
+
487
+
488
+
489
+ spawn();
490
+
491
+ start();
492
+
493
+ }
494
+
495
+
496
+
497
+ // publicメソッド
498
+
499
+ public void rotateRight()
500
+
501
+ {
502
+
503
+ mino.rotateRight();
504
+
505
+ if( !canExistMino( mino ) ){
506
+
507
+ mino.rotateLeft();
508
+
509
+ }
510
+
511
+
512
+
513
+ updateGhost();
514
+
515
+ }
516
+
517
+
518
+
519
+ public void rotateLeft()
520
+
521
+ {
522
+
523
+ mino.rotateLeft();
524
+
525
+ if( !canExistMino( mino ) ){
526
+
527
+ mino.rotateRight();
528
+
529
+ }
530
+
531
+
532
+
533
+ updateGhost();
534
+
535
+ }
536
+
537
+
538
+
539
+ public void moveRight()
540
+
541
+ {
542
+
543
+ mino.moveRight();
544
+
545
+ if( !canExistMino( mino ) ){
546
+
547
+ mino.moveLeft();
548
+
549
+ }
550
+
551
+
552
+
553
+ updateGhost();
554
+
555
+ }
556
+
557
+
558
+
559
+ public void moveLeft()
560
+
561
+ {
562
+
563
+ mino.moveLeft();
564
+
565
+ if( !canExistMino( mino ) ){
566
+
567
+ mino.moveRight();
568
+
569
+ }
570
+
571
+
572
+
573
+ updateGhost();
574
+
575
+ }
576
+
577
+
578
+
579
+ public void softDrop()
580
+
581
+ {
582
+
583
+ mino.moveDown();
584
+
585
+ if( !canExistMino( mino ) ){
586
+
587
+ mino.moveUp();
588
+
589
+ putBlock();
590
+
591
+ }
592
+
593
+ }
594
+
595
+
596
+
597
+ public void hardDrop()
598
+
599
+ {
600
+
601
+ for( int y=0 ; y< ROW ; y++ ){
602
+
603
+ for( int x=0 ; x< COL ; x++ ){
604
+
605
+ if( ghost.isExistMino(x, y) ){
606
+
607
+ map[y][x] = mino.type;
608
+
609
+ }
610
+
611
+ }
612
+
613
+ }
614
+
615
+ deleteLine();
616
+
617
+ spawn();
618
+
619
+ }
620
+
621
+
622
+
623
+ public void hold()
624
+
625
+ {
626
+
627
+ if( !holdFlag ){
628
+
629
+ return;
630
+
631
+ }
632
+
633
+
634
+
635
+ if( hold == TetKind.Empty ){
636
+
637
+ hold = mino.type;
638
+
639
+ spawn();
640
+
641
+ }else{
642
+
643
+ TetKind temp = hold;
644
+
645
+ hold = mino.type;
646
+
647
+ mino = new Mino( temp );
648
+
649
+ }
650
+
651
+
652
+
653
+ holdFlag = false;
654
+
655
+ updateGhost();
656
+
657
+ }
658
+
659
+
660
+
661
+ // 引数の座標のブロックの種類を得る
662
+
663
+ public TetKind getMap( int x, int y )
664
+
665
+ {
666
+
667
+ if( mino.isExistMino(x, y) ){
668
+
669
+ return mino.type;
670
+
671
+ }
672
+
673
+ else if( ghost.isExistMino(x, y) ){
674
+
675
+ return TetKind.Ghost;
676
+
677
+ }
678
+
679
+ else{
680
+
681
+ return map[y][x];
682
+
683
+ }
684
+
685
+ }
686
+
687
+
688
+
689
+ // ホールドのブロックの種類を得る
690
+
691
+ public TetKind getHold()
692
+
693
+ {
694
+
695
+ return hold;
696
+
697
+ }
698
+
699
+
700
+
701
+ // ネクストのブロックの種類を得る
702
+
703
+ public TetKind getNext( int n )
704
+
705
+ {
706
+
707
+ return next[n];
708
+
709
+ }
710
+
711
+
712
+
713
+ // privateメソッド
714
+
715
+ @Override public void run()
716
+
717
+ {
718
+
719
+ while( true ){
720
+
721
+ try{ sleep( rate ); }catch( Exception e ){}
722
+
723
+ softDrop();
724
+
725
+ }
726
+
727
+ }
728
+
729
+
730
+
731
+ private void orderShuffle()
732
+
733
+ {
734
+
735
+ java.util.Random r = new java.util.Random();
736
+
737
+ for( int i=0 ; i< order.length ; i++ ){
738
+
739
+ int rand = r.nextInt( order.length );
740
+
741
+ TetKind temp = order[rand];
742
+
743
+ order[rand] = order[i];
744
+
745
+ order[i] = temp;
746
+
747
+ }
748
+
749
+ }
750
+
751
+
752
+
753
+ private void spawn()
754
+
755
+ {
756
+
757
+ // 最後まで行ったら最初から
758
+
759
+ if( orderNow == order.length ){
760
+
761
+ orderNow = 0;
762
+
763
+ orderShuffle();
764
+
765
+ }
766
+
767
+
768
+
769
+ mino = new Mino( next[0] );
770
+
771
+
772
+
773
+ // ネクストを更新
774
+
775
+ for( int i=0 ; i< TetKind.cnt -1 ; i++ ){
776
+
777
+ next[i] = next[i+1];
778
+
779
+ }
780
+
781
+ next[TetKind.cnt -1] = order[orderNow];
782
+
783
+
784
+
785
+ orderNow++;
786
+
787
+ updateGhost();
788
+
789
+ holdFlag = true;
790
+
791
+ }
792
+
793
+
794
+
795
+ // ブロックを設置する
796
+
797
+ private void putBlock()
798
+
799
+ {
800
+
801
+ for( int y=0 ; y< ROW ; y++ ){
802
+
803
+ for( int x=0 ; x< COL ; x++ ){
804
+
805
+ if( mino.isExistMino(x, y) ){
806
+
807
+ map[y][x] = mino.type;
808
+
809
+ }
810
+
811
+ }
812
+
813
+ }
814
+
815
+ deleteLine();
816
+
817
+ spawn();
818
+
819
+ }
820
+
821
+
822
+
823
+ // ブロックが揃った列を消去
824
+
825
+ private void deleteLine()
826
+
827
+ {
828
+
829
+ outside: for( int y = 0 ; y < ROW ; y++ ){
830
+
831
+ // その列が揃ってないなら次の列
832
+
833
+ for( int x=0 ; x < COL ; x++ ){
834
+
835
+ if( map[y][x] == TetKind.Empty ){
836
+
837
+ continue outside;
838
+
839
+ }
840
+
841
+ }
842
+
843
+
844
+
845
+ // それより上の列を落とす
846
+
847
+ for( int ty = y ; ty > 0 ; ty -- ){
848
+
849
+ for( int x=0 ; x < COL ; x++ ){
850
+
851
+ map[ty][x] = map[ty-1][x];
852
+
853
+ }
854
+
855
+ }
856
+
857
+
858
+
859
+ // 一番上の列は全て空
860
+
861
+ for( int x=0 ; x < COL ; x++ ){
862
+
863
+ map[0][x] = TetKind.Empty;
864
+
865
+ }
866
+
867
+ }
868
+
869
+ }
870
+
871
+
872
+
873
+ // ミノがその場所に存在できるかどうか
874
+
875
+ private boolean canExistMino( Mino arg )
876
+
877
+ {
878
+
879
+ int cnt = 0;
880
+
881
+ for( int y= 0 ; y< ROW ; y++ ){
882
+
883
+ for( int x= 0 ; x< COL ; x++ ){
884
+
885
+ if( arg.isExistMino( x, y ) ){
886
+
887
+ // マップ内に存在しているミノの数を数える
888
+
889
+ if( map[y][x] == TetKind.Empty ){
890
+
891
+ cnt++;
892
+
893
+ }
894
+
895
+ // フィールド上のミノと重なっていたらfalse
896
+
897
+ else{
898
+
899
+ return false;
900
+
901
+ }
902
+
903
+ }
904
+
905
+ }
906
+
907
+ }
908
+
909
+
910
+
911
+ // マップ内のミノが4ではない場合、
912
+
913
+ // ミノの一部がフィールド外にはみ出てしまっているためfalse
914
+
915
+ return cnt == 4 ? true : false;
916
+
917
+ }
918
+
919
+
920
+
921
+ private void updateGhost()
922
+
923
+ {
924
+
925
+ ghost = mino.copy();
926
+
927
+ while( canExistMino( ghost ) ){
928
+
929
+ ghost.moveDown();
930
+
931
+ }
932
+
933
+ ghost.moveUp();
934
+
935
+ }
936
+
937
+ }
938
+
939
+ ```

1

微調整

2016/11/22 14:12

投稿

mightyMask
mightyMask

スコア143

test CHANGED
File without changes
test CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  ○ゴーストを表示するかどうかは設定できる。
20
20
 
21
- ○地面に着地してからは、すぐには設置されない(ハードドロップの際を除く)。左右に動かすか、回転することにより、設置されるまでの時間が延長される。ただし、延長できる回数は14回まで。15回目の延長をしようとした場合、強制的にハードドロップされる。
21
+ ○地面に着地してからは、すぐには設置されない(ハードドロップの際を除く)。左右に動かすか、回転することにより、設置されるまでの時間が延長される。ただし、延長できる回数は14回まで。15回目の延長をしようとした場合、強制的に設置される。
22
22
 
23
23
  ○ミノを着地及びラインを消去した際、combo,t-spin等と呼ばれる特殊な条件に当てはまる場合がある。
24
24