Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #初期設定
- $width = 10;
- $height = 20;
- #ブロック定義(*1)
- @{$B[0]}=(
- [0,0,1,0,0],
- [0,0,1,0,0],
- [0,0,1,0,0],
- [0,0,1,0,0],
- [0,0,0,0,0]
- );
- @{$B[1]}=(
- [0,0,0,0,0],
- [0,0,1,1,0],
- [0,0,1,0,0],
- [0,0,1,0,0],
- [0,0,0,0,0]
- );
- @{$B[2]}=(
- [0,0,0,0,0],
- [0,0,0,1,0],
- [0,0,1,1,0],
- [0,0,1,0,0],
- [0,0,0,0,0]
- );
- @{$B[3]}=(
- [0,0,0,0,0],
- [0,0,1,0,0],
- [0,0,1,1,0],
- [0,0,0,1,0],
- [0,0,0,0,0]
- );
- @{$B[4]}=(
- [0,0,0,0,0],
- [0,0,1,0,0],
- [0,1,1,1,0],
- [0,0,0,0,0],
- [0,0,0,0,0]
- );
- @{$B[5]}=(
- [0,0,0,0,0],
- [0,1,1,0,0],
- [0,0,1,0,0],
- [0,0,1,0,0],
- [0,0,0,0,0]
- );
- @{$B[6]}=(
- [0,0,0,0,0],
- [0,0,0,0,0],
- [0,0,1,1,0],
- [0,0,1,1,0],
- [0,0,0,0,0]
- );
- #0/1を□■で表示(*8)
- sub print_square{
- my ($v) = @_;
- if( $v == 0 ){
- print "--";
- }elsif( $v == 1 ){
- print "■";
- }elsif( $v == -1 ){
- print "□";
- }else{
- print "??";
- }
- }
- # 定期ブロック落下(*3)
- sub set_interval{
- $timer_flag = 0;
- $interval = 0.7;
- use Time::HiRes qw ( alarm sleep );
- $SIG{ALRM} = \&interval_timer;
- alarm($interval);
- }
- sub interval_timer{
- $interval = $interval * 0.995;
- $timer_flag = 1;
- alarm $interval;
- }
- sub debug_block_print2{
- my ($n) = @_;
- my $a;
- my $b;
- print "\n";
- for($b=0;$b<5;$b++){
- for($a=0;$a<5;$a++){
- print_square( $B[$n][$b][$a] );
- }
- print "\n";
- }
- }
- #map初期化(*6)
- sub map_initialize{
- my $x;
- my $y;
- for($y=0;$y<($height+2);$y++){
- for($x=0;$x<($width+2);$x++){
- $N[$y][$x] = 0;
- }
- }
- }
- #map壁生成(*7)
- sub map_write_wall{
- my $x;
- my $y;
- for($y=0;$y<($height+2);$y++){
- for($x=0;$x<($width+2);$x++){
- if($x == 0){
- $N[$y][$x] = -1;
- }
- if($x == ($width+1)){
- $N[$y][$x] = -1;
- }
- if($y == 0){
- $N[$y][$x] = -1;
- }
- }
- }
- }
- #画面消去(*9-2)
- sub clear_screen2{
- print "\033[3;0H";
- }
- #残り少ないなら@blocks追加
- sub add_blocks{
- my $flag = 0;
- for(my $i=0;$i<@blocks;$i++){
- if($blocks[$i] == -1){
- my $num = $i;
- $flag = 1;
- last;
- }
- }
- if($flag == 0){
- my $num = @blocks;
- }
- if($num <= 7){
- my @arr = (0,1,2,3,4,5,6);
- my $r, $temp;
- for($i=0;$i<7;$i++){
- $r = int(rand(7-$i)) + $i;
- $temp = $arr[$i];
- $arr[$i] = $arr[$r];
- $arr[$r] = $temp;
- }
- for($i=0;$i<7;$i++){
- $blocks[$num+$i] = $arr[$i];
- }
- }
- }
- # 初期化(*2-1)
- sub initialize2{
- for(my $i=0;$i<24;$i++){ print "\n"; } # 画面消去
- @blocks = ();
- $hold = -1;
- map_initialize();
- map_write_wall();
- add_blocks();
- add_blocks();
- print_new_block2();
- map_print();
- set_interval();
- }
- # 終了(*5)
- sub end_game{
- print "GAME END\n";
- exit;
- }
- #ゲームオーバーを表示して終了する(*15)
- sub game_over{
- print "GAME OVER\n";
- exit;
- }
- #map表示(*10)
- sub map_print{
- my $x;
- my $y;
- clear_screen2();
- for($y=($height+1);$y>-1;$y=$y-1){
- for($x=0;$x<($width+2);$x++){
- print_square( $N[$y][$x] );
- }
- print "\n";
- }
- }
- #mapの指定位置にn番ブロックを書き込む(*12)
- sub map_write_block{
- # x, y, ブロック番号
- my ($x,$y,$n) = @_;
- for(my $b=0;$b<5;$b++){
- for(my $a=0;$a<5;$a++){
- if($B[$n][4-$b][$a]>0){
- $N[$y+$b][$x+$a] = $N[$y+$b][$x+$a] + $B[$n][4-
- $b][$a];
- }
- }
- }
- }
- #mapの指定位置のn番ブロックを消す(*13)
- sub map_clear_block{
- # x, y, ブロック番号
- my ($x,$y,$n) = @_;
- for(my $b=0;$b<5;$b++){
- for(my $a=0;$a<5;$a++){
- if($B[$n][4-$b][$a]>0){
- $N[$y+$b][$x+$a] = $N[$y+$b][$x+$a] - $B[$n][4-
- $b][$a];
- }
- }
- }
- }
- #n番ブロックを回転(*11)
- sub rotate_block_n{
- my ($n) = @_; # ブロック番号
- my $a;
- my $b;
- for($b=0;$b<5;$b++){
- for($a=0;$a<5;$a++){
- $X[$b][$a] = $B[$n][4-$a][$b];
- }
- }
- for($b=0;$b<5;$b++){
- for($a=0;$a<5;$a++){
- $B[$n][$b][$a] = $X[$b][$a];
- }
- }
- }
- #現在のブロックを左に移動する。但しぶつかるなら諦める(*18-2)
- sub block_move_left2{
- map_clear_block($pos_x,$pos_y,$bn);
- $flag = map_crash_test_block($pos_x - 1 , $pos_y, $bn);
- if( $flag == 0 ){
- $pos_x = $pos_x - 1;
- }
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }
- #現在のブロックを右に移動する。但しぶつかるなら諦める(*19-2)
- sub block_move_right2{
- map_clear_block($pos_x,$pos_y,$bn);
- $flag = map_crash_test_block($pos_x + 1 , $pos_y, $bn);
- if( $flag == 0 ){
- $pos_x = $pos_x + 1;
- }
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }
- #現在のブロックを回転させる。但しぶつかるなら諦める(*17-2)
- sub block_rotate2{
- map_clear_block($pos_x,$pos_y,$bn);
- rotate_block_n($bn);
- $flag = map_crash_test_block($pos_x , $pos_y, $bn);
- if( $flag != 0 ){
- rotate_block_n($bn);
- rotate_block_n($bn);
- rotate_block_n($bn);
- }
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }
- #現在のブロックを下に移動する。但しぶつかるならライン消し処理を呼ぶ(*20-4)
- sub block_move_down4{
- map_clear_block($pos_x,$pos_y,$bn);
- $flag = map_crash_test_block($pos_x , $pos_y - 1 , $bn);
- if( $flag == 0 ){
- $pos_y = $pos_y - 1;
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }else{
- map_write_block($pos_x,$pos_y,$bn);
- map_line_process();
- print_new_block2();
- }
- }
- sub block_hard_drop{
- for(;;){
- map_clear_block($pos_x,$pos_y,$bn);
- $flag = map_crash_test_block($pos_x , $pos_y - 1 , $bn);
- if( $flag == 0 ){
- $pos_y = $pos_y - 1;
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }else{
- map_write_block($pos_x,$pos_y,$bn);
- map_line_process();
- print_new_block2();
- last;
- }
- }
- }
- #mapの指定位置にn番ブロックを置くとぶつかるかどうかを返す(*14)
- sub map_crash_test_block{
- my ($x,$y,$n) = @_; # x, y, ブロック番号
- my $flag = 0;
- for(my $b=0;$b<5;$b++){
- for(my $a=0;$a<5;$a++){
- if( $B[$n][4-$b][$a] != 0 ){
- if( $N[$y+$b][$x+$a] != 0 ){
- $flag = 1;
- }
- }
- }
- }
- return($flag);
- }
- #新しいブロックを表示。但し他のブロックにぶつかるならゲームオーバー(*16-2)
- sub print_new_block2{
- $pos_x = int($width / 2 - 1);
- $pos_y = $height - 3;
- add_blocks();
- $bn = $blocks[0];
- for(my $i=0;$i<@blocks-1;$i++){
- $blocks[$i] = $blocks[$i+1];
- }
- $blocks[@blocks-1] = -1;
- my $flag = map_crash_test_block($pos_x,$pos_y,$bn);
- if($flag == 0){
- map_write_block($pos_x,$pos_y,$bn);
- map_print();
- }else{
- game_over();
- }
- $timer_flag = 0;
- }
- #mapの指定行に空欄があれば0を返す(*22)
- sub map_line_chk{
- my ($y) = @_;
- my $x;
- my $flag = 1;
- for($x=1;$x<($width+1);$x++){
- if( $N[$y][$x] == 0){
- $flag = 0;
- }
- }
- if($flag == 1){
- return(1);
- }else{
- return(0);
- }
- }
- #mapの指定行を消して上を詰める(*23)
- sub map_line_clear{
- my ($clear_line) = @_;
- my $x;
- my $y;
- for( $y=$clear_line ; $y<($height+1) ; $y++ ){
- for($x=1;$x<($width+1);$x++){
- $N[$y][$x] = $N[$y+1][$x]
- }
- }
- for($x=1;$x<$width+1;$x++){
- $N[$height+1][$x] = 0;
- }
- }
- #ライン消し処理(*21)
- sub map_line_process{
- my $x;
- my $flag;
- for($y=21;$y>0;$y--){
- $flag = map_line_chk($y);
- if( $flag == 1){
- map_line_clear($y);
- }
- }
- }
- # キー受付(*4-2)
- sub key_input2{
- use Term::ReadKey;
- $loop=1;
- while($loop == 1){
- if($timer_flag == 1){
- block_move_down4();
- $timer_flag = 0;
- }
- ReadMode "cbreak";
- $key = ReadKey -1;
- ReadMode "restore";
- if( ! defined( $key ) ){
- sleep 0.005;
- }elsif( $key eq 'q'){
- $loop = 0;
- }elsif($key eq '2'){
- block_move_down4();
- }elsif($key eq '4'){
- block_move_left2();
- }elsif($key eq '6'){
- block_move_right2();
- }elsif($key eq '5'){
- block_rotate2();
- }elsif($key eq '8'){
- block_hard_drop();
- }
- }
- }
- #main(*24)
- initialize2();
- key_input2();
- end_game();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement