Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.73 KB | None | 0 0
  1. #初期設定
  2. $width = 10;
  3. $height = 20;
  4.  
  5. #ブロック定義(*1)
  6. @{$B[0]}=(
  7. [0,0,1,0,0],
  8. [0,0,1,0,0],
  9. [0,0,1,0,0],
  10. [0,0,1,0,0],
  11. [0,0,0,0,0]
  12. );
  13. @{$B[1]}=(
  14. [0,0,0,0,0],
  15. [0,0,1,1,0],
  16. [0,0,1,0,0],
  17. [0,0,1,0,0],
  18. [0,0,0,0,0]
  19. );
  20. @{$B[2]}=(
  21. [0,0,0,0,0],
  22. [0,0,0,1,0],
  23. [0,0,1,1,0],
  24. [0,0,1,0,0],
  25. [0,0,0,0,0]
  26. );
  27. @{$B[3]}=(
  28. [0,0,0,0,0],
  29. [0,0,1,0,0],
  30. [0,0,1,1,0],
  31. [0,0,0,1,0],
  32. [0,0,0,0,0]
  33. );
  34. @{$B[4]}=(
  35. [0,0,0,0,0],
  36. [0,0,1,0,0],
  37. [0,1,1,1,0],
  38. [0,0,0,0,0],
  39. [0,0,0,0,0]
  40. );
  41. @{$B[5]}=(
  42. [0,0,0,0,0],
  43. [0,1,1,0,0],
  44. [0,0,1,0,0],
  45. [0,0,1,0,0],
  46. [0,0,0,0,0]
  47. );
  48. @{$B[6]}=(
  49. [0,0,0,0,0],
  50. [0,0,0,0,0],
  51. [0,0,1,1,0],
  52. [0,0,1,1,0],
  53. [0,0,0,0,0]
  54. );
  55.  
  56.  
  57. #0/1を□■で表示(*8)
  58. sub print_square{
  59. my ($v) = @_;
  60. if( $v == 0 ){
  61. print "--";
  62. }elsif( $v == 1 ){
  63. print "■";
  64. }elsif( $v == -1 ){
  65. print "□";
  66. }else{
  67. print "??";
  68. }
  69. }
  70.  
  71. # 定期ブロック落下(*3)
  72. sub set_interval{
  73. $timer_flag = 0;
  74. $interval = 0.7;
  75. use Time::HiRes qw ( alarm sleep );
  76. $SIG{ALRM} = \&interval_timer;
  77. alarm($interval);
  78. }
  79. sub interval_timer{
  80. $interval = $interval * 0.995;
  81. $timer_flag = 1;
  82. alarm $interval;
  83. }
  84.  
  85. sub debug_block_print2{
  86. my ($n) = @_;
  87. my $a;
  88. my $b;
  89. print "\n";
  90. for($b=0;$b<5;$b++){
  91. for($a=0;$a<5;$a++){
  92. print_square( $B[$n][$b][$a] );
  93. }
  94. print "\n";
  95. }
  96. }
  97.  
  98. #map初期化(*6)
  99. sub map_initialize{
  100. my $x;
  101. my $y;
  102. for($y=0;$y<($height+2);$y++){
  103. for($x=0;$x<($width+2);$x++){
  104. $N[$y][$x] = 0;
  105. }
  106. }
  107. }
  108.  
  109. #map壁生成(*7)
  110. sub map_write_wall{
  111. my $x;
  112. my $y;
  113. for($y=0;$y<($height+2);$y++){
  114. for($x=0;$x<($width+2);$x++){
  115. if($x == 0){
  116. $N[$y][$x] = -1;
  117. }
  118. if($x == ($width+1)){
  119. $N[$y][$x] = -1;
  120. }
  121. if($y == 0){
  122. $N[$y][$x] = -1;
  123. }
  124. }
  125. }
  126. }
  127.  
  128.  
  129. #画面消去(*9-2)
  130. sub clear_screen2{
  131. print "\033[3;0H";
  132. }
  133.  
  134. #残り少ないなら@blocks追加
  135. sub add_blocks{
  136. my $flag = 0;
  137. for(my $i=0;$i<@blocks;$i++){
  138. if($blocks[$i] == -1){
  139. my $num = $i;
  140. $flag = 1;
  141. last;
  142. }
  143. }
  144. if($flag == 0){
  145. my $num = @blocks;
  146. }
  147. if($num <= 7){
  148. my @arr = (0,1,2,3,4,5,6);
  149. my $r, $temp;
  150. for($i=0;$i<7;$i++){
  151. $r = int(rand(7-$i)) + $i;
  152. $temp = $arr[$i];
  153. $arr[$i] = $arr[$r];
  154. $arr[$r] = $temp;
  155. }
  156. for($i=0;$i<7;$i++){
  157. $blocks[$num+$i] = $arr[$i];
  158. }
  159. }
  160. }
  161.  
  162. # 初期化(*2-1)
  163. sub initialize2{
  164. for(my $i=0;$i<24;$i++){ print "\n"; } # 画面消去
  165. @blocks = ();
  166. $hold = -1;
  167. map_initialize();
  168. map_write_wall();
  169. add_blocks();
  170. add_blocks();
  171. print_new_block2();
  172. map_print();
  173. set_interval();
  174. }
  175.  
  176. # 終了(*5)
  177. sub end_game{
  178. print "GAME END\n";
  179. exit;
  180. }
  181.  
  182. #ゲームオーバーを表示して終了する(*15)
  183. sub game_over{
  184. print "GAME OVER\n";
  185. exit;
  186. }
  187.  
  188. #map表示(*10)
  189. sub map_print{
  190. my $x;
  191. my $y;
  192. clear_screen2();
  193. for($y=($height+1);$y>-1;$y=$y-1){
  194. for($x=0;$x<($width+2);$x++){
  195. print_square( $N[$y][$x] );
  196. }
  197. print "\n";
  198. }
  199. }
  200.  
  201. #mapの指定位置にn番ブロックを書き込む(*12)
  202. sub map_write_block{
  203. # x, y, ブロック番号
  204. my ($x,$y,$n) = @_;
  205. for(my $b=0;$b<5;$b++){
  206. for(my $a=0;$a<5;$a++){
  207. if($B[$n][4-$b][$a]>0){
  208. $N[$y+$b][$x+$a] = $N[$y+$b][$x+$a] + $B[$n][4-
  209.  
  210. $b][$a];
  211. }
  212. }
  213. }
  214. }
  215.  
  216.  
  217. #mapの指定位置のn番ブロックを消す(*13)
  218. sub map_clear_block{
  219. # x, y, ブロック番号
  220. my ($x,$y,$n) = @_;
  221. for(my $b=0;$b<5;$b++){
  222. for(my $a=0;$a<5;$a++){
  223. if($B[$n][4-$b][$a]>0){
  224. $N[$y+$b][$x+$a] = $N[$y+$b][$x+$a] - $B[$n][4-
  225.  
  226. $b][$a];
  227. }
  228. }
  229. }
  230. }
  231.  
  232. #n番ブロックを回転(*11)
  233. sub rotate_block_n{
  234. my ($n) = @_; # ブロック番号
  235. my $a;
  236. my $b;
  237. for($b=0;$b<5;$b++){
  238. for($a=0;$a<5;$a++){
  239. $X[$b][$a] = $B[$n][4-$a][$b];
  240. }
  241. }
  242. for($b=0;$b<5;$b++){
  243. for($a=0;$a<5;$a++){
  244. $B[$n][$b][$a] = $X[$b][$a];
  245. }
  246. }
  247. }
  248.  
  249. #現在のブロックを左に移動する。但しぶつかるなら諦める(*18-2)
  250. sub block_move_left2{
  251. map_clear_block($pos_x,$pos_y,$bn);
  252. $flag = map_crash_test_block($pos_x - 1 , $pos_y, $bn);
  253. if( $flag == 0 ){
  254. $pos_x = $pos_x - 1;
  255. }
  256. map_write_block($pos_x,$pos_y,$bn);
  257. map_print();
  258. }
  259.  
  260. #現在のブロックを右に移動する。但しぶつかるなら諦める(*19-2)
  261. sub block_move_right2{
  262. map_clear_block($pos_x,$pos_y,$bn);
  263. $flag = map_crash_test_block($pos_x + 1 , $pos_y, $bn);
  264. if( $flag == 0 ){
  265. $pos_x = $pos_x + 1;
  266. }
  267. map_write_block($pos_x,$pos_y,$bn);
  268. map_print();
  269. }
  270.  
  271. #現在のブロックを回転させる。但しぶつかるなら諦める(*17-2)
  272. sub block_rotate2{
  273. map_clear_block($pos_x,$pos_y,$bn);
  274. rotate_block_n($bn);
  275. $flag = map_crash_test_block($pos_x , $pos_y, $bn);
  276. if( $flag != 0 ){
  277. rotate_block_n($bn);
  278. rotate_block_n($bn);
  279. rotate_block_n($bn);
  280. }
  281. map_write_block($pos_x,$pos_y,$bn);
  282. map_print();
  283. }
  284.  
  285. #現在のブロックを下に移動する。但しぶつかるならライン消し処理を呼ぶ(*20-4)
  286. sub block_move_down4{
  287. map_clear_block($pos_x,$pos_y,$bn);
  288. $flag = map_crash_test_block($pos_x , $pos_y - 1 , $bn);
  289. if( $flag == 0 ){
  290. $pos_y = $pos_y - 1;
  291. map_write_block($pos_x,$pos_y,$bn);
  292. map_print();
  293. }else{
  294. map_write_block($pos_x,$pos_y,$bn);
  295. map_line_process();
  296. print_new_block2();
  297. }
  298. }
  299.  
  300. sub block_hard_drop{
  301. for(;;){
  302. map_clear_block($pos_x,$pos_y,$bn);
  303. $flag = map_crash_test_block($pos_x , $pos_y - 1 , $bn);
  304. if( $flag == 0 ){
  305. $pos_y = $pos_y - 1;
  306. map_write_block($pos_x,$pos_y,$bn);
  307. map_print();
  308. }else{
  309. map_write_block($pos_x,$pos_y,$bn);
  310. map_line_process();
  311. print_new_block2();
  312. last;
  313. }
  314. }
  315. }
  316.  
  317. #mapの指定位置にn番ブロックを置くとぶつかるかどうかを返す(*14)
  318. sub map_crash_test_block{
  319. my ($x,$y,$n) = @_; # x, y, ブロック番号
  320. my $flag = 0;
  321. for(my $b=0;$b<5;$b++){
  322. for(my $a=0;$a<5;$a++){
  323. if( $B[$n][4-$b][$a] != 0 ){
  324. if( $N[$y+$b][$x+$a] != 0 ){
  325. $flag = 1;
  326. }
  327. }
  328. }
  329. }
  330. return($flag);
  331. }
  332.  
  333. #新しいブロックを表示。但し他のブロックにぶつかるならゲームオーバー(*16-2)
  334. sub print_new_block2{
  335. $pos_x = int($width / 2 - 1);
  336. $pos_y = $height - 3;
  337. add_blocks();
  338. $bn = $blocks[0];
  339. for(my $i=0;$i<@blocks-1;$i++){
  340. $blocks[$i] = $blocks[$i+1];
  341. }
  342. $blocks[@blocks-1] = -1;
  343. my $flag = map_crash_test_block($pos_x,$pos_y,$bn);
  344. if($flag == 0){
  345. map_write_block($pos_x,$pos_y,$bn);
  346. map_print();
  347. }else{
  348. game_over();
  349. }
  350. $timer_flag = 0;
  351. }
  352.  
  353. #mapの指定行に空欄があれば0を返す(*22)
  354. sub map_line_chk{
  355. my ($y) = @_;
  356. my $x;
  357. my $flag = 1;
  358. for($x=1;$x<($width+1);$x++){
  359. if( $N[$y][$x] == 0){
  360. $flag = 0;
  361. }
  362. }
  363. if($flag == 1){
  364. return(1);
  365. }else{
  366. return(0);
  367. }
  368. }
  369.  
  370. #mapの指定行を消して上を詰める(*23)
  371. sub map_line_clear{
  372. my ($clear_line) = @_;
  373. my $x;
  374. my $y;
  375. for( $y=$clear_line ; $y<($height+1) ; $y++ ){
  376. for($x=1;$x<($width+1);$x++){
  377. $N[$y][$x] = $N[$y+1][$x]
  378. }
  379. }
  380. for($x=1;$x<$width+1;$x++){
  381. $N[$height+1][$x] = 0;
  382. }
  383. }
  384.  
  385. #ライン消し処理(*21)
  386. sub map_line_process{
  387. my $x;
  388. my $flag;
  389. for($y=21;$y>0;$y--){
  390. $flag = map_line_chk($y);
  391. if( $flag == 1){
  392. map_line_clear($y);
  393. }
  394. }
  395. }
  396.  
  397.  
  398. # キー受付(*4-2)
  399. sub key_input2{
  400. use Term::ReadKey;
  401. $loop=1;
  402. while($loop == 1){
  403. if($timer_flag == 1){
  404. block_move_down4();
  405. $timer_flag = 0;
  406. }
  407. ReadMode "cbreak";
  408. $key = ReadKey -1;
  409. ReadMode "restore";
  410. if( ! defined( $key ) ){
  411. sleep 0.005;
  412. }elsif( $key eq 'q'){
  413. $loop = 0;
  414. }elsif($key eq '2'){
  415. block_move_down4();
  416. }elsif($key eq '4'){
  417. block_move_left2();
  418. }elsif($key eq '6'){
  419. block_move_right2();
  420. }elsif($key eq '5'){
  421. block_rotate2();
  422. }elsif($key eq '8'){
  423. block_hard_drop();
  424. }
  425. }
  426. }
  427.  
  428. #main(*24)
  429. initialize2();
  430. key_input2();
  431. end_game();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement