1. 程式人生 > >CCF程式設計練習:俄羅斯方塊(Java)

CCF程式設計練習:俄羅斯方塊(Java)

CCF程式設計練習:俄羅斯方塊(Java)

問題描述

俄羅斯方塊是俄羅斯人阿列克謝·帕基特諾夫發明的一款休閒遊戲。 遊戲在一個15行10列的方格圖上進行,方格圖上的每一個格子可能已經放置了方塊,或者沒有放置方塊。每一輪,都會有一個新的由4個小方塊組成的板塊從方格圖的上方落下,玩家可以操作板塊左右移動放到合適的位置,當板塊中某一個方塊的下邊緣與方格圖上的方塊上邊緣重合或者達到下邊界時,板塊不再移動,如果此時方格圖的某一行全放滿了方塊,則該行被消除並得分。 在這個問題中,你需要寫一個程式來模擬板塊下落,你不需要處理玩家的操作,也不需要處理消行和得分。
具體的,給定一個初始的方格圖,以及一個板塊的形狀和它下落的初始位置,你要給出最終的方格圖。 輸入格式    輸入的前15行包含初始的方格圖,每行包含10個數字,相鄰的數字用空格分隔。如果一個數字是0,表示對應的方格中沒有方塊,如果數字是1,則表示初始的時候有方塊。輸入保證前4行中的數字都是0。
  輸入的第16至第19行包含新加入的板塊的形狀,每行包含4個數字,組成了板塊圖案,同樣0表示沒方塊,1表示有方塊。輸入保證板塊的圖案中正好包含4個方塊,且4個方塊是連在一起的(準確的說,4個方塊是四連通的,即給定的板塊是俄羅斯方塊的標準板塊)。
  第20行包含一個1到7之間的整數,表示板塊圖案最左邊開始的時候是在方格圖的哪一列中。注意,這裡的板塊圖案指的是16至19行所輸入的板塊圖案,如果板塊圖案的最左邊一列全是0,則它的左邊和實際所表示的板塊的左邊是不一致的(見樣例)
輸出格式    輸出15行,每行10個數字,相鄰的數字之間用一個空格分隔,表示板塊下落後的方格圖。注意,你不需要處理最終的消行。 樣例輸入 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 0
3 樣例輸出 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0
解題思路:
用陣列box[15][10]來表示遊戲介面,down[4][4]來表示下降版塊,用index_i來表示下降版塊的移動。需要注意的是,down自身是並沒有移動的,所以在計算down中的當前行數時需要加上index_i; 在下降的過程中,需要實時判斷是否到達底部和是否下面有障礙。需要先判斷是否到底,不然會報越界錯誤。 在更新box時,也需要考慮下降版塊的底部是否已經超出了介面box的底部。
滿分程式碼如下:
import java.util.Scanner;

public class Main {
	public static void main(String[] args){
		Scanner input=new Scanner(System.in);
		int[][] box=new int[15][10];
		int[][] down=new int[4][4];
	
		for(int i=0;i<15;i++)
			for(int j=0;j<10;j++)
				box[i][j]=input.nextInt();//除錯時可以用下面的註釋程式碼來替代輸入,方便除錯
		/*
		for(int i=0;i<15;i++)
			for(int j=0;j<10;j++)
				box[i][j]=0;
		box[14][4]=1;
		box[13][0]=box[13][1]=box[13][2]=box[13][6]=box[13][7]=box[13][8]=box[13][9]=1;
		box[12][6]=box[11][6]=box[10][7]=1;
	    */
		for(int i=0;i<4;i++)
			for(int j=0;j<4;j++)
				down[i][j]=input.nextInt();//輸入下降的版塊
		
		int n=input.nextInt();
		
		int index_i=0,index_j=n-1;//index_i表示當前下降版塊第一行所在位置
		boolean fall=true;
		while(fall){
			if(index_i>=15)//判斷是否已經下到了底部
				fall=false;
			
			for(int m=3;m>=0;m--)//從下降版塊的最後一行開始檢視
				for(int h=0;h<4;h++){
					if(down[m][h]==1&&m+index_i==14){//如果當前值為1,則先檢視是否到了底
						fall=false;
						break;
					}
					if(down[m][h]==1&&box[m+index_i+1][h+n-1]==1){//再檢視是否下一行有阻礙
						fall=false;
						break;
					}
				}
			index_i++;//下降一行
		}
	
		index_i--;
		if(index_i>11){//下降版塊的底部已經超出了box的底部
			for(int i=0;i<15-index_i;i++)
				for(int j=0;j<4;j++)
					if(down[i][j]==1)
						box[i+index_i][j+n-1]=1;//更新box
		}
		else{//下降版塊的底部沒有超出box的底部
			for(int i=0;i<4;i++)
				for(int j=0;j<4;j++)
					if(down[i][j]==1)
						box[i+index_i][j+n-1]=1;
		}
		
		for(int i=0;i<15;i++){
			for(int j=0;j<10;j++)
				System.out.print(box[i][j]+" ");
			System.out.println();
		}
		
	}
}