tetris

66
PEMROGRAMAN GAME MOBILE GAME TETRIS Oleh : Kelompok 5 Michael Nugraha (1104505055) Fajar Firmansyah (1104505061) I Putu Agus Andryatna (1104505062) I Putu Ade Ambara Putra (1104505064) Kresnantara (1104505100)

Upload: krezna-watanabe

Post on 22-Jul-2016

214 views

Category:

Documents


0 download

DESCRIPTION

tugas

TRANSCRIPT

Page 1: Tetris

PEMROGRAMAN GAME MOBILE GAME TETRIS

Oleh :

Kelompok 5

Michael Nugraha (1104505055)

Fajar Firmansyah (1104505061)

I Putu Agus Andryatna (1104505062)

I Putu Ade Ambara Putra (1104505064)

Kresnantara (1104505100)

UNIVERSITAS UDAYANA

BUKIT JIMBARAN

2014

Page 2: Tetris

Sejarah Tetris

Tetris adalah permainan teka-teki bangunan yang pertama kalinya didesain oleh Alexey

Pajitnov pada bulan Juni 1985, saat itu, ia masih bekerja di Pusat Komputer Dorodnicyn di

Akademi Sains Uni Soviet di Moskow, nama tetris sendiri diambil dari bahasa numerik yunani,

yaitu tetra yang artinya empat. Empat sendiri adalah jumah susunan balok yang bisa diubah-ubah

ke dalam berbagai bentuk untuk selanjutnya disusun oleh si pemain untuk dapat saling terkunci.

Pada dasarnya, ada 7 jenis formasi balok yang ada di dalam game tetris, yaitu balok I, J,

L, O, S, T, dan Z. balok-balok tersebut diberi nama demikian karena memang bentuknya mirip

dengan hurup tersebut, untuk lebih jelasnya, silahkan lihat gambar di bawah ini.

Gambar 1 Balok Tetris

Permainan tetris ini sukses setelah dirilis oleh gameboy pada tahun 1989, setelah itu,

permainan ini mulai dirilis ulang oleh berbagai perusahaan game dunia seperti nintendo,

playstation, office game, dan perusahaan-perusahaan game ternama lainya. walaupun sudah

berusia sangat lama, tapi permainan ini tetap menjadi primadona di mata gamers dunia, menurut

mereka, game ini adalah game yang banyak menguras otak dan mengasah cara pandang ruang

otak seseorang. makin lama, pola permainan game ini makin beragam, jika pada versi awalnya,

game ini hanya menggunakan sistem penilaian berdasarkan bangun ruang yang disusun, tapi

lama kelamaan, mulai banyak versi tetris yang juga menggunakan penilaian berdasarkan

keserasian warna.

Page 3: Tetris

Percobaan Tetris For Android Pada Emulator

Kali ini penulis mencoba membuat sebuah game tetris dengan platform Android dan

menggunakan game engine AndEngine. Percobaan pertama mencoba dengan menggunakan

emulator BlueStacks

Gambar 2. Instalasi game tetris pada Emulator BlueStacks

Page 4: Tetris

Setelah teristal, penulis mencoba menjalankan game tetris. Berikut tampilan awal dari Game Tetris.

Gambar 3 Tampilan awal Game Tetris

Kemudian mencoba permainan dengan memilih menu New Game. Berikut tampilan saat dalam permainan.

Gambar 4 in-game pada game tetris

Page 5: Tetris

Percobaan Tetris For Android pada Device

Game tetris ini akan diuji dengan menggunakan device secara langsung. Device yang dipakan adalah Samsung Galaxy Tab 2 7.0 P3100. Berikut hasil percobaan pada device.

Tampilan Awal Game

Berikut ini adalah tampilan awan dari Game Tetris yang diuji coba pada perangkat Android Galaxy Tab 2

7.0.

Gambar 5. Tampilan awal game pada device

Page 6: Tetris

Tampilan in-game Game Tetris

Sama halnya pada emulator, in-game game ini dapat berjalan dengan normal tanpa

kendala. Pada tampilan ini, terlihat beberapa element terlihat pada in-game seperti board untuk

bermain, tombol navigasi, tampilan piece, score, dan tombol pause/resume.

Gambar 6. Tampilan in-game pada device

Page 7: Tetris

Apabila Piece pertama masuk ke dalam Board, Piece selanjutnya akan tampil pada box

yang berada pada ujung kanan pada permainan. Piece yang tampil pada kotak akan ditampilkan

secara acak dan setelah piece berada pada bagian terbawah board, piece yang akan tampil pada

board selanjutnya adalah piece acak yang tampil pada box dan seterusnya hingga game selesai

atau game over.

Gambar 7. Tampilan piece ke-2 setelah piece pertama

Page 8: Tetris

Permainan ini menyediakan tombol navigasi untuk mengubah posisi gerak dan rotasi

piece. Terdapat 3 tombol untuk mengubah posisi gerak piece, yaitu tombol left, down, dan right.

Tombol-tobol ini berfungsi untuk mengubah posisi pergerakan piece pada saat piece berada pada

board. Dan terdapat 2 tombol rotasi untuk memutar piece yang berada pada board, yaitu tombol

rotate left dan rotate right. Fungsinya untuk memutar piece yang bergerak pada board.

Gambar 8. Merubah posisi piece L Biru

Page 9: Tetris

Gambar 9. merubah rotasi piece

Fungsi tombol pause adalah untuk menghentikan gerak atau permainan untuk sementara

waktu. Tombol pause pada game ini telah dapat berfungsi dengan baik sebagaimana mestinya.

Gambar 10. Tombol pause

Page 10: Tetris

Ketika satu deret horisontal penuh dengan piece yang telah dikumpulkan, maka piece

pada satu deret horizontal akan menghilang dan menghasilkan score. Penilaian score

berdasarkan banyaknya deret horizontal yang terjadi pada game ini. Apabila hal ini terjadi

secara beruntun maka score streak akan terus bertambah hingga kelipatan 16.

Gambar 11 scoring

Score tertinggi dalam suatu permainan akan tercatat dalam menu High Score. Dalam

menu High Score akan terdapat 3 catatan score tertinggi. Urutan High Score ini berdasarkan nilai

tertinggi pertama hingga nilai tertinggi ketiga. Apabila dalam satu permainan, satu pemain tidak

dapat melewati catatan high score, maka score yang dimiliki pemain tersebut tidak akan masuk

ke dalam catatan high score

Page 11: Tetris

Gambar 12 Tampilan High Score

Page 12: Tetris

About.java

package android.tetris;

import android.app.Activity;import android.os.Bundle;import android.view.Window;

public class About extends Activity {/** Called when the activity is first created. */

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.about); }}

BoardView.java

package android.tetris;

import android.content.Context;import android.graphics.Canvas;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;

//The game boardpublic class BoardView extends View{

public Drawable[][] block = new Drawable[20][10];public Drawable[] wall = new Drawable[102];Context context;Canvas c;

public BoardView(Context cont, AttributeSet attrs) {super(cont, attrs);context = cont;

}

//Defines a position in the board for a boxpublic void initialize(int i, int j, int left, int top, int side){

block[i][j] = context.getResources().getDrawable(R.drawable.alpha); block[i][j].setBounds(left, top, left + side, top + side);

}

//A method to draw the walls. Needs the top and the left of the first box and the side of each box

public void createWall(int left, int top, int side){int i = 0, x, y;x = left - side / 2;y = top;

Page 13: Tetris

//The left wallwhile (i < 40){

wall[i] = context.getResources().getDrawable(R.drawable.brick);

wall[i].setBounds(x, y, x + side / 2, y + side / 2);y = y + side / 2;i = i + 1;

}x = left + side * 10;y = top;//The right wallwhile (i < 80){

wall[i] = context.getResources().getDrawable(R.drawable.brick);

wall[i].setBounds(x, y, x + side / 2, y + side / 2);y = y + side / 2;i = i + 1;

}x = left - side / 2;//The floorwhile (i < 102){

wall[i] = context.getResources().getDrawable(R.drawable.brick);

wall[i].setBounds(x, y, x + side / 2, y + side / 2);x = x + side / 2;i = i + 1;

}}

@Override protected void onDraw(Canvas canvas) {

c = canvas; super.onDraw(canvas); for (int i = 0; i < 102; i++) wall[i].draw(c); for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++){ //Log.e("i, j", Integer.toString(i) + ", " + Integer.toString(j)); block[i][j].draw(canvas); } invalidate(); }

public Canvas getCanvas(){ return c;

}

//Color a box (coordinates [i][j]public void setColor(int i, int j, byte c){

Rect rect;rect = block[i][j].getBounds();switch (c){

case Values.COLOR_NONE:block[i][j] =

context.getResources().getDrawable(R.drawable.alpha);;break;

Page 14: Tetris

case Values.COLOR_RED:block[i][j] =

context.getResources().getDrawable(R.drawable.block_red);break;

case Values.COLOR_GREEN:block[i][j] =

context.getResources().getDrawable(R.drawable.block_green);break;

case Values.COLOR_BLUE:block[i][j] =

context.getResources().getDrawable(R.drawable.block_blue);break;

case Values.COLOR_YELLOW:block[i][j] =

context.getResources().getDrawable(R.drawable.block_yellow);break;

case Values.COLOR_PINK:block[i][j] =

context.getResources().getDrawable(R.drawable.block_pink);break;

case Values.COLOR_PURPLE:block[i][j] =

context.getResources().getDrawable(R.drawable.block_purple);break;

case Values.COLOR_WHITE:block[i][j] =

context.getResources().getDrawable(R.drawable.block_white);break;

}block[i][j].setBounds(rect);

}}

Box.java

package android.tetris;

import android.graphics.drawable.Drawable;

//A box is each one of the positions in the board (200)public class Box {

private int top, left, side, color;Drawable img;

//The color, is also indicates if the box is free (color 0 means it's free)

public int getColor() {return color;

}

public void setColor(int color) {this.color = color;

}

//Getters for the positionpublic int getTop() {

Page 15: Tetris

return top;}

public int getLeft() {return left;

}

public int getSide() {return side;

}

public Box(int _top, int _left, int _side){top = _top;left = _left;side = _side;color = Values.COLOR_NONE;

}}

Game.java

package android.tetris;

import java.util.Calendar;import java.util.Date;import android.app.Activity;import android.content.Context;import android.content.SharedPreferences;import android.os.Bundle;import android.os.CountDownTimer;import android.os.Vibrator;import android.view.Display;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;

public class Game extends Activity {

BoardView gameBoard;int d; // The side of a boxpublic Box[][] box;int x, y;BoardView boardView;Display display;CountDownTimer timer;Piece currentPiece;Piece nextPiece;boolean pieceOnGame;Button btnMoveRight, btnMoveLeft, btnMoveDown, btnRotateRight,

btnRotateLeft, btnPause;ImageView nextPieceImg;//Score and combo

Page 16: Tetris

TextView textScore;ImageView imageCombo;int score = 0;int combo = 1;Vibrator vibrator;//The pause indicatorboolean game;

/** Called when the activity is first created. */ @Override

public void onCreate(Bundle savedInstanceState) { //Assign layouts super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.game); //Assign buttons btnMoveRight = (Button) findViewById(R.id.ButtonMoveR); btnMoveLeft = (Button) findViewById(R.id.ButtonMoveL); btnMoveDown = (Button) findViewById(R.id.ButtonMoveD); btnRotateRight = (Button) findViewById(R.id.buttonRotateR); btnRotateLeft = (Button) findViewById(R.id.ButtonRotateL); btnPause = (Button) findViewById(R.id.buttonPause); //Get measures for the board display = getWindowManager().getDefaultDisplay(); int width = (int) (display.getWidth() * 0.7); int height = (int) (display.getHeight() * 0.9); gameBoard = (BoardView) findViewById(R.id.GameView); d = (int) (width * 0.85 / 10); //Asign score and combo resources textScore = (TextView) findViewById(R.id.TextViewScore); imageCombo = (ImageView) findViewById(R.id.imageViewCombo); //Initialize boxes and draw the wall box = new Box[20][10]; x = (int) (width * 0.05); y = (int) (height * 0.05); gameBoard.createWall(x, y, d); for (int i = 0; i < 20; i++){ x = (int) (width * 0.05); for (int j = 0; j < 10; j++){ box[i][j] = new Box(x + d * j, y + d * i, d); gameBoard.initialize(i, j, x, y, d); x = x + d; } y = y + d; }; //initialize vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); //Initialize pieces currentPiece = new Piece(); nextPiece = new Piece();

Page 17: Tetris

nextPieceImg = (ImageView) findViewById(R.id.imageViewNext); //Start the time bucle game = true; timer = new CountDownTimer(150000, 1000) {

public void onTick(long millisUntilFinished) { gameAction(); }

public void onFinish() { gameAction(); start(); } }.start();

//Assign buttons action btnMoveRight.setOnClickListener(new OnClickListener(){ public void onClick(View v) { unDraw(); currentPiece.moveRight(); vibrator.vibrate(30); reDraw();

} }); btnMoveLeft.setOnClickListener(new OnClickListener(){ public void onClick(View v) { unDraw(); currentPiece.moveLeft(); vibrator.vibrate(30); reDraw();

} }); //TODO: On long click btnMoveDown.setOnClickListener(new OnClickListener(){ public void onClick(View v) { unDraw(); currentPiece.moveDown(); vibrator.vibrate(30); reDraw();

} }); btnRotateRight.setOnClickListener(new OnClickListener(){ public void onClick(View v) { unDraw(); currentPiece.rotateRight(); vibrator.vibrate(30); reDraw();

} }); btnRotateLeft.setOnClickListener(new OnClickListener(){ public void onClick(View v) { unDraw(); currentPiece.rotateLeft(); vibrator.vibrate(30); reDraw();

} });

Page 18: Tetris

btnPause.setOnClickListener(new OnClickListener(){ public void onClick(View v) { if (game == true){ game = false; btnPause.setText(R.string.resume); } else{ game = true; btnPause.setText(R.string.pause); } vibrator.vibrate(30);

} }); //Start the game textScore.setText("0"); currentPiece.start(); //Set image for next piece //Has to be done here, or there is no next piece image at the

begginingswitch(nextPiece.type){case Values.PIECE_0:

nextPieceImg.setImageResource(R.drawable.piece0);break;

case Values.PIECE_1:nextPieceImg.setImageResource(R.drawable.piece1);break;

case Values.PIECE_2:nextPieceImg.setImageResource(R.drawable.piece2);break;

case Values.PIECE_3:nextPieceImg.setImageResource(R.drawable.piece3);break;

case Values.PIECE_4:nextPieceImg.setImageResource(R.drawable.piece4);break;

case Values.PIECE_5:nextPieceImg.setImageResource(R.drawable.piece5);break;

case Values.PIECE_6:nextPieceImg.setImageResource(R.drawable.piece6);break;

} } //The time bucle public void gameAction(){ if (game == true){

//Undraw the current piece unDraw(); //Try to move down.

if (currentPiece.moveDown() == false){//If couldnt move fix the blocks currently

occupied...for (int i = 0; i < 20; i++)

Page 19: Tetris

for (int j = 0; j < 10; j++){ if (currentPiece.box[i][j] == true){ box[i]

[j].setColor(currentPiece.getColor()); gameBoard.setColor(i, j,

currentPiece.getColor()); } }

/// ...check if there is any full row...if (lookForRows() == false){

combo = 1; //If nothing has been removed, set combo to 1

imageCombo.setImageResource(R.drawable.alpha);}//... check if the game is loose... if (gameLoose() == true)

finish();// ... and start a new piececurrentPiece = nextPiece;currentPiece.start();nextPiece = new Piece();

//Set the next piece imageswitch(nextPiece.type){

case Values.PIECE_0:

nextPieceImg.setImageResource(R.drawable.piece0);break;

case Values.PIECE_1:

nextPieceImg.setImageResource(R.drawable.piece1);break;

case Values.PIECE_2:

nextPieceImg.setImageResource(R.drawable.piece2);break;

case Values.PIECE_3:

nextPieceImg.setImageResource(R.drawable.piece3);break;

case Values.PIECE_4:

nextPieceImg.setImageResource(R.drawable.piece4);break;

case Values.PIECE_5:

nextPieceImg.setImageResource(R.drawable.piece5);break;

case Values.PIECE_6:

nextPieceImg.setImageResource(R.drawable.piece6);break;

}}//Copy the board info to the piece

currentPiece.readBoard(box); reDraw();

Page 20: Tetris

} } //If there is something in the two first rows before starting a new piece, the game is loose private boolean gameLoose() { int hScore1, hScore2, hScore3, aux; String hScore1Date, hScore2Date, hScore3Date, auxDate; boolean loose = false;

for (int j = 0; j < 10; j++)if (box[1][j].getColor() != Values.COLOR_NONE)

loose = true;if (loose == false)

return false;//What to do on game over?//Notify the user TODO: (Maybe deactivate buttons?)game = false;vibrator.vibrate(1000);//Add high scores if neededSharedPreferences highScores =

getSharedPreferences("highScores", 0);hScore1 = highScores.getInt("hScore1", 0);hScore2 = highScores.getInt("hScore2", 0);hScore3 = highScores.getInt("hScore3", 0);hScore1Date = highScores.getString("hScore1Date", "0");hScore2Date = highScores.getString("hScore2Date", "0");hScore3Date = highScores.getString("hScore3Date", "0");Calendar currentDate = Calendar.getInstance();Date dateNow = currentDate.getTime();if(score > hScore3){

hScore3 = score;hScore3Date = dateNow.toString();

}if(hScore3 > hScore2){

aux = hScore2;auxDate = hScore2Date;hScore2 = hScore3;hScore2Date = hScore3Date;hScore3 = aux;hScore3Date = auxDate;

}if(hScore2 > hScore1){

aux = hScore1;auxDate = hScore1Date;hScore1 = hScore2;hScore1Date = hScore2Date;hScore2 = aux;hScore2Date = auxDate;

}SharedPreferences.Editor editor = highScores.edit();editor.putInt("hScore1", hScore1);editor.putInt("hScore2", hScore2);editor.putInt("hScore3", hScore3);editor.putString("hScore1Date", hScore1Date);editor.putString("hScore2Date", hScore1Date);editor.putString("hScore3Date", hScore1Date);editor.commit();

Page 21: Tetris

return true;}

//Look for complete rows public boolean lookForRows(){ boolean somethingRemoved = false; //To determine if some row has been removed to keep the combo boolean full = true; for (int i = 1; i < 20; i++){ full = true; for (int j = 0; j < 10; j++){ if (box[i][j].getColor() == Values.COLOR_NONE) full = false; } if (full == true){ somethingRemoved = true; removeRow(i); } } return somethingRemoved; } //Remove row and score public void removeRow(int row){ score = score + Values.SCORE_PER_ROW * combo; textScore.setText(Integer.toString(score)); //Setcombo multiplier combo = combo * 2; if (combo == 32) combo = 16; switch (combo){ case 2: imageCombo.setImageResource(R.drawable.x2); break; case 4: imageCombo.setImageResource(R.drawable.x4); break; case 8: imageCombo.setImageResource(R.drawable.x8); break; case 16: imageCombo.setImageResource(R.drawable.x16); break; } for (int i = row; i > 1; i--) for (int j = 0; j < 10; j++){ box[i][j].setColor(box[i - 1][j].getColor()); gameBoard.setColor(i, j, (byte) box[i - 1][j].getColor()); } } //Redraw the screen public void reDraw(){ //Read where the piece is and colorize for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++){ if (currentPiece.box[i][j] == true){

Page 22: Tetris

box[i][j].setColor(currentPiece.getColor()); gameBoard.setColor(i, j, currentPiece.getColor()); } } } //Undraw the current piece before moving public void unDraw(){ for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++){ if (currentPiece.box[i][j] == true){ box[i][j].setColor(0); gameBoard.setColor(i, j, (byte) 0); } } }}

HighScore.java

package android.tetris;

import android.app.Activity;import android.content.SharedPreferences;import android.os.Bundle;import android.view.Window;import android.widget.TextView;

public class HighScores extends Activity{

public void onCreate(Bundle savedInstanceState) {

//TextViewsTextView hs1, hs2, hs3, hs1d, hs2d, hs3d;

//Saved valuesSharedPreferences highScores;

//Assign layouts super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.highscores); //Assign textViews hs1 = (TextView) findViewById(R.id.textViewHighScore1); hs2 = (TextView) findViewById(R.id.textViewHighScore2); hs3 = (TextView) findViewById(R.id.textViewHighScore3); hs1d = (TextView) findViewById(R.id.textViewHighScore1Date); hs2d = (TextView) findViewById(R.id.textViewHighScore2Date); hs3d = (TextView) findViewById(R.id.textViewHighScore3Date); //Load high scores highScores = getSharedPreferences("highScores", 0);

if (highScores.getInt("hScore1", 0) > 0){hs1.setText(getResources().getString(R.string.first) + ":

" + Integer.toString(highScores.getInt("hScore1", 0)));

Page 23: Tetris

hs1d.setText(highScores.getString("hScore1Date", " "));}if (highScores.getInt("hScore2", 0) > 0){

hs2.setText(getResources().getString(R.string.second) + ": " + Integer.toString(highScores.getInt("hScore2", 0)));

hs2d.setText(highScores.getString("hScore2Date", " "));}if (highScores.getInt("hScore3", 0) > 0){

hs3.setText(getResources().getString(R.string.third) + ": " + Integer.toString(highScores.getInt("hScore3", 0)));

hs3d.setText(highScores.getString("hScore3Date", " "));}

}}

Piece.java

package android.tetris;

import java.util.Random;

public class Piece {

Random generator;byte type;byte color;boolean[][] box;boolean board[][];boolean[][] aux;byte rotation; //Rotation state of the piece: 0->1->2->3->0

public byte getColor(){return color;

}

Piece(){generator = new Random();type = (byte) generator.nextInt(7);//type = 2;//TESTING, change to be all the same piece color = (byte) (type + 1);rotation = 0;box = new boolean[20][10];board = new boolean[20][10];for (int i = 0; i < 20; i++)

for (int j = 0; j < 10; j++) box[i][j] = false;

}

//Puts the piece in the top of the boardpublic void start(){

switch (type){//In the Values class there is a "graphical description"

of each piececase Values.PIECE_0: //The bar

box[0][3] = true;box[0][4] = true;

Page 24: Tetris

box[0][5] = true;box[0][6] = true;break;

case Values.PIECE_1: //The 'L'-shapedbox[0][4] = true;box[1][4] = true;box[1][5] = true;box[1][6] = true;break;

case Values.PIECE_2: //The inverted 'L'-shapedbox[0][5] = true;box[1][3] = true;box[1][4] = true;box[1][5] = true;break;

case Values.PIECE_3: //The cubebox[0][4] = true;box[0][5] = true;box[1][4] = true;box[1][5] = true;break;

case Values.PIECE_4: //The inverted 'Z'-shapedbox[0][4] = true;box[0][5] = true;box[1][3] = true;box[1][4] = true;break;

case Values.PIECE_5: //The 'Z'-shapedbox[0][4] = true;box[0][5] = true;box[1][5] = true;box[1][6] = true;break;

case Values.PIECE_6: //The inverted 'T'box[0][4] = true;box[1][3] = true;box[1][4] = true;box[1][5] = true;break;

}}

//This method receives the array of boxes from the Game class, so the piece have info about the state of the board

//Probably there is a better way to do thatpublic void readBoard(Box a[][]){

for (int i = 0; i < 20; i++) for (int j = 0; j < 10; j++) if (a[i][j].getColor() == Values.COLOR_NONE) board[i][j] = false; else board[i][j] = true;

}

//Called when a piece is going to be moved. Also checks if the piece can be moved. Returns true (and moves the piece) if it's possible

Page 25: Tetris

public boolean moveDown(){aux = new boolean[20][10]; //New array. In

the end, if everything is OK, it will be copied to the piece arrayfor (int j = 0; j < 10; j++)

if (box[19][j] == true) //If any box conforming the piece is in the 19th row...

return false; //... don't move

for (int i = 0; i < 19; i++) //Examine all the boxes, one by one for (int j = 0; j < 10; j++){ if (box[i][j] == true){ //If the piece is occupying a box if (board[i + 1][j] == true)//If the box below is already occupied... return false; //... don't move aux[i + 1][j] = true; //If the box below is free, mark as true in the auxiliary array } else aux[i + 1][j] = false; //If the box is not occupied by the piece, set to false in the auxiliary array }

for (int i = 0; i < 20; i++) //Copy the auxiliary array to the piece array for (int j = 0; j < 10; j++) box[i][j] = aux[i][j];

return true; //Piece moved!

}

//Called when a piece is going to be moved. Also checks if the piece can be moved. Returns true (and moves the piece) if it's possible

public boolean moveLeft(){aux = new boolean[20][10]; //New array. In

the end, if everything is OK, it will be copied to the piece arrayfor (int i = 0; i < 20; i++) //Examine all the

boxes, one by one for (int j = 0; j < 10; j++){ if (box[i][j] == true){ //If the piece is occupying a box if (j == 0) //If this box is behind the left wall... return false; //... don't move if (board[i][j - 1] == true)//If the box in the left is already occupied... return false; //... don't move aux[i][j - 1] = true; //If the box in the left is free and it's not a wall, mark as true in the auxiliary array } else aux[i][j] = false; //If the box is not occupied by the piece, set to false in the auxiliary array }

for (int i = 0; i < 20; i++) //Copy the auxiliary array to the piece array for (int j = 0; j < 10; j++)

Page 26: Tetris

box[i][j] = aux[i][j];return true; //Piece

moved!}

//Called when a piece is going to be moved. Also checks if the piece can be moved. Returns true (and moves the piece) if it's possible

public boolean moveRight(){aux = new boolean[20][10]; //New array. In

the end, if everything is OK, it will be copied to the piece arrayfor (int i = 19; i >= 0; i--) //Examine all the

boxes, one by one for (int j = 9; j >= 0; j--){ if (box[i][j] == true){ //If the piece is occupying a box if (j == 9) //If this box is behind the right wall... return false; //... don't move if (board[i][j + 1] == true)//If the box in the right is already occupied... return false; //... don't move aux[i][j + 1] = true; //If the box in the left is free and it's not a wall, mark as true in the auxiliary array } else aux[i][j] = false; //If the box is not occupied by the piece, set to false in the auxiliary array }

for (int i = 0; i < 20; i++) //Copy the auxiliary array to the piece array for (int j = 0; j < 10; j++) box[i][j] = aux[i][j];

return true; //Piece moved!

}

//Called when a piece is going to be rotated. Also checks if the piece can be moved. Returns true (and moves the piece) if it's possible

//DISCLAIMER://Very confusing code. VERY VERY confusing//The next two methods are a succession of nested switch() that,

first, identify the piece, and, next, rotates from it's previous position//Each case is treated separately, as I haven't found any common

method. Each case is shortly commented, but it's not very clear.//Sorry about thatpublic boolean rotateRight(){

int i = 0;int j = 0;switch (type){

case Values.PIECE_0://Switch next rotation stateswitch (rotation + 1){

case 1: //From horizontal to vertical//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

Page 27: Tetris

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (i == 0)

return false;if (board[i - 1][j + 2] == true)

return false;if (board[i + 1][j + 2] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i - 1][j + 2] = true;box[i + 1][j + 2] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;box[i][j + 3] = false;break;

case 2: //From vertical to horizontal//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If is behind the left wall, try to

move right twice, on no oneif (j == 0){

if (moveRight() == false)return false;

if (moveRight() == false){moveLeft();return false;

}j = j + 2;

}//If is 1 distance the left wall, try to

move right twice, on no oneif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//If is behind the right wall, try to

move leftif (j == 9){

if (moveLeft() == false)return false;

Page 28: Tetris

j = j - 1;}//Check availabilityif (board[i + 1][j - 2] == true)

return false;if (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j - 2] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = true;box[i][j] = false;box[i + 2][j] = false;box[i + 3][j] = false;break;

case 3: //From horizontal to vertical//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (i == 0)

return false;if (board[i - 1][j + 2] == true)

return false;if (board[i + 1][j + 2] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i - 1][j + 2] = true;box[i + 1][j + 2] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;box[i][j + 3] = false;break;

case 4: //From vertical to horizontal//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If is behind the left wall, try to

Page 29: Tetris

move right twice, on no oneif (j == 0){

if (moveRight() == false)return false;

if (moveRight() == false){moveLeft();return false;

}j = j + 2;

}//If is 1 distance the left wall, try to

move right twice, on no oneif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//If is behind the right wall, try to

move leftif (j == 9){

if (moveLeft() == false)return false;

j = j - 1;}//Check availabilityif (board[i + 1][j - 2] == true)

return false;if (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j - 2] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = true;box[i][j] = false;box[i + 2][j] = false;box[i + 3][j] = false;break;

}break;

case Values.PIECE_1://Switch new rotation stateswitch (rotation + 1){

case 1: //From horizontal left-side-up to vertical top-side-right

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;

Page 30: Tetris

if (i == 19)return false;

if (board[i][j + 1] == true)return false;

if (board[i][j + 2] == true)return false;

if (board[i + 2][j + 1] == true)return false;

//Perform transformationbox[i][j + 1] = true;box[i][j + 2] = true;box[i + 2][j + 1] = true;box[i][j] = false;box[i + 1][j] = false;box[i + 1][j + 2] = false;break;

case 2: //From vertical top-side-right to horizontal right-side-down

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If is behind the left wall, try to

move rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i + 1][j + 1] = true;box[i + 1][j] = false;box[i + 2][j] = false;break;

case 3: //From horizontal left-side-down to vertical down-side-left

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;

Page 31: Tetris

if (i == 19)return false;

if (board[i + 2][j + 1] == true)return false;

if (board[i + 2][j + 2] == true)return false;

//Perform transformationbox[i + 2][j + 1] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;break;

case 4: //From vertical down-side-left to horizontal left-side-up

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If is behind the left wall, try to

move rightif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 2] == true)

return false;if (board[i + 1][j - 2] == true)

return false;if (board[i + 1][j - 1] == true)

return false;//Perform transformationbox[i][j - 2] = true;box[i + 1][j - 2] = true;box[i + 1][j - 1] = true;box[i][j] = false;box[i + 2][j - 1] = false;box[i + 2][j] = false;break;

}break;

case Values.PIECE_2://Switch new rotation stateswitch (rotation + 1){

case 1: //From horizontal right-side-up to vertical low-side-right

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

Page 32: Tetris

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i][j - 1] == true)

return false;if (board[i + 2][j - 1] == true)

return false;if (board[i + 2][j] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i + 2][j - 1] = true;box[i + 2][j] = true;box[i][j] = false;box[i + 1][j - 2] = false;box[i + 1][j] = false;break;

case 2: //From vertical bottom-side-right to horizontal left-side-down

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

lrightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 1] == true)

return false;if (board[i][j + 1] == true)

return false;if (board[i + 1][j - 1] == true)

return false;

//Perform transformationbox[i][j - 1] = true;box[i][j + 1] = true;box[i + 1][j - 1] = true;box[i + 1][j] = false;box[i + 2][j] = false;box[i + 2][j + 1] = false;break;

case 3: //From horizontal right-side-down to vertical top-side-left

//Find the first occupied box

Page 33: Tetris

while (box[i][j] == false){j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i + i][j + 2] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i + 1][j + 2] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i + 1][j] = false;break;

case 4: //From vertical top-side-left to horizontal right-side-up

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j] == true)

return false;//Perform transformationbox[i + 1][j - 1] = true;box[i + 1][j] = true;box[i][j] = false;box[i + 2][j + 1] = false;break;

}break;

case Values.PIECE_3://Is the cube, so, do nothing!break;

case Values.PIECE_4: // inverted 'Z'- shaped//Switch new rotation state

Page 34: Tetris

switch (rotation + 1){case 1: //From upleft & downright to leftup &

rghtdown//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i][j + 1] = false;box[i + 1][j - 1] = false;break;

case 2: //From leftup & rightdown to upleft & downright

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j + 1] == true)

return false;if (board[1 + 1][j - 1] == true)

return false;//Perform transformationbox[i][j + 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = false;box[i + 2][j + 1] = false;break;

case 3: //From upleft & downright to leftup & rghtdown: Same as case 1

//Find the first occupied boxwhile (box[i][j] == false){

j++;

Page 35: Tetris

if (j == 9){j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i][j + 1] = false;box[i + 1][j - 1] = false;break;

case 4: //From leftup & rightdown to upleft & downright // Same as case 2

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j + 1] == true)

return false;if (board[1 + 1][j - 1] == true)

return false;//Perform transformationbox[i][j + 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = false;box[i + 2][j + 1] = false;break;

}break;

case Values.PIECE_5: // 'Z'- shaped//Switch new rotation stateswitch (rotation + 1){

case 1: //From downleft & upright to rightup & leftdown

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

Page 36: Tetris

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i][j + 2] == true)

return false;//Perform transformationbox[i + 2][j + 1] = true;box[i][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;break;

case 2: //From rightup & leftdown to downleft & upright

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j -2] == true)

return false;if (board[1][j - 1] == true)

return false;//Perform transformationbox[i][j - 2] = true;box[i][j - 1] = true;box[i][j] = false;box[i + 2][j - 1] = false;break;

case 3: //From downleft & upright to rightup & leftdown: Same as case 1

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

Page 37: Tetris

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i][j + 2] == true)

return false;//Perform transformationbox[i + 2][j + 1] = true;box[i][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;break;

case 4: //From rightup & leftdown to downleft & upright: SAme as case 2

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j -2] == true)

return false;if (board[1][j - 1] == true)

return false;//Perform transformationbox[i][j - 2] = true;box[i][j - 1] = true;box[i][j] = false;box[i + 2][j - 1] = false;break;

}break;

case Values.PIECE_6: // 'T'- shaped//Switch new rotation stateswitch (rotation + 1){

case 1: //From top faced to right faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 2][j] == true)

Page 38: Tetris

return false;//Perform transformationbox[i + 2][j] = true;box[i + 1][j - 1] = false;break;

case 2: //From right faced to bottom faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i + 1][j - 1] == true)

return false;//Perform transformationbox[i + 1][j - 1] = true;box[i][j] = false;break;

case 3: //From bottom faced to left faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 0)

return false;if (board[i - 1][j + 1] == true)

return false;//Perform transformationbox[i - 1][j + 1] = true;box[i][j + 2] = false;break;

case 4: //From left faced to top faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If its behind a wall, try to move leftif (j == 9){

Page 39: Tetris

if (moveLeft() == false)return false;

j = j - 1;}//Check availabilityif (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j] = false;break;

}break;

}//Change rotation staterotation++;if (rotation == 4)

rotation = 0;return true;

}

public boolean rotateLeft(){int i = 0;int j = 0;switch (type){

case Values.PIECE_0://Switch next rotation stateswitch (rotation - 1){

case -1: //From horizontal to vertical//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (i == 0)

return false;if (board[i - 1][j + 2] == true)

return false;if (board[i + 1][j + 2] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i - 1][j + 2] = true;box[i + 1][j + 2] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;box[i][j + 3] = false;

Page 40: Tetris

break;case 0: //From vertical to horizontal

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If is behind the left wall, try to

move right twice, on no oneif (j == 0){

if (moveRight() == false)return false;

if (moveRight() == false){moveLeft();return false;

}j = j + 2;

}//If is 1 distance the left wall, try to

move right twice, on no oneif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//If is behind the right wall, try to

move leftif (j == 9){

if (moveLeft() == false)return false;

j = j - 1;}//Check availabilityif (board[i + 1][j - 2] == true)

return false;if (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j - 2] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = true;box[i][j] = false;box[i + 2][j] = false;box[i + 3][j] = false;break;

case 1: //From horizontal to vertical//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

Page 41: Tetris

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (i == 0)

return false;if (board[i - 1][j + 2] == true)

return false;if (board[i + 1][j + 2] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i - 1][j + 2] = true;box[i + 1][j + 2] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;box[i][j + 3] = false;break;

case 2: //From vertical to horizontal//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If is behind the left wall, try to

move right twice, on no oneif (j == 0){

if (moveRight() == false)return false;

if (moveRight() == false){moveLeft();return false;

}j = j + 2;

}//If is 1 distance the left wall, try to

move right twice, on no oneif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//If is behind the right wall, try to

move leftif (j == 9){

if (moveLeft() == false)return false;

j = j - 1;}

Page 42: Tetris

//Check availabilityif (board[i + 1][j - 2] == true)

return false;if (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j - 2] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = true;box[i][j] = false;box[i + 2][j] = false;box[i + 3][j] = false;break;

}break;

case Values.PIECE_1://Switch new rotation stateswitch (rotation - 1){

case -1: //From horizontal left-side-up to vertical low-side-left

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i][j + 2] == true)

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i][j + 2] = true;box[i + 2][j + 1] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i + 1][j] = false;box[i + 1][j + 1] = false;break;

case 0: //From vertical top-side-right to horizontal left-side-up

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

Page 43: Tetris

}}//If is behind the left wall, try to

move rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 1] == true)

return false;if (board[i + 1][j - 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = true;box[i][j] = false;box[i][j + 1] = false;box[i + 2][j] = false;break;

case 1: //From horizontal right-side-down to vertical low-side-right

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i][j] = false;box[i + 1][j + 2] = false;break;

case 2: //From vertical top-side-right to horizontal left-side-down

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

Page 44: Tetris

}}//If is behind the left wall, try to

move rightif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 1] == true)

return false;if (board[i][j - 2] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i][j - 2] = true;box[i + 2][j] = false;box[i + 2][j - 1] = false;break;

}break;

case Values.PIECE_2://Switch new rotation stateswitch (rotation - 1){

case -1: //From horizontal right-side-up to vertical top-side-left

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i][j - 1] == true)

return false;if (board[i + 2][j] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i + 2][j] = true;box[i + 1][j - 1] = false;box[i + 1][j - 2] = false;break;

case 0: //From vertical bottom-side-right to horizontal right-side-up

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;

Page 45: Tetris

i++;}

}//If its behind a wall, try to move

lrightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j + 1] == true)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 1][j - 1] == true)

return false;//Perform transformationbox[i][j + 1] = true;box[i + 1][j + 1] = true;box[i + 1][j - 1] = true;box[i][j] = false;box[i + 2][j] = false;box[i + 2][j + 1] = false;break;

case 1: //From horizontal left-side-down to vertical low-side-right

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (i == 19)

return false;if (board[i + i][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i + 2][j + 2] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i + 2][j + 2] = true;box[i][j] = false;box[i + 1][j] = false;box[i][j + 2] = false;break;

case 2: //From vertical top-side-left to horizontal left-side-down

//Find the first occupied box

Page 46: Tetris

while (box[i][j] == false){j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j - 1] == true)

return false;if (board[i + 1][j - 1] == true)

return false;//Perform transformationbox[i][j - 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = false;box[i + 2][j + 1] = false;break;

}break;

case Values.PIECE_3://Is the cube, so, do nothing!break;

case Values.PIECE_4: // inverted 'Z'- shaped//Switch new rotation stateswitch (rotation - 1){

case -1: //From upleft & downright to leftup & rghtdown

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i][j + 1] = false;box[i + 1][j - 1] = false;break;

case 0: //From leftup & rightdown to upleft &

Page 47: Tetris

downright //Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j + 1] == true)

return false;if (board[1 + 1][j - 1] == true)

return false;//Perform transformationbox[i][j + 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = false;box[i + 2][j + 1] = false;break;

case 1: //From upleft & downright to leftup & rghtdown: Same as case 1

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 1][j + 1] == true)

return false;if (board[i + 2][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i + 2][j + 1] = true;box[i][j + 1] = false;box[i + 1][j - 1] = false;break;

case 2: //From leftup & rightdown to upleft & downright // Same as case 2

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;

Page 48: Tetris

i++;}

}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j + 1] == true)

return false;if (board[1 + 1][j - 1] == true)

return false;//Perform transformationbox[i][j + 1] = true;box[i + 1][j - 1] = true;box[i + 1][j + 1] = false;box[i + 2][j + 1] = false;break;

}break;

case Values.PIECE_5: // 'Z'- shaped//Switch new rotation stateswitch (rotation - 1){

case -1: //From downleft & upright to rightup & leftdown

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i][j + 2] == true)

return false;//Perform transformationbox[i + 2][j + 1] = true;box[i][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;break;

case 0: //From rightup & leftdown to downleft & upright

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

Page 49: Tetris

}}//If its behind a wall, try to move

rightif (j == 1){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i][j -2] == true)

return false;if (board[1][j - 1] == true)

return false;//Perform transformationbox[i][j - 2] = true;box[i][j - 1] = true;box[i][j] = false;box[i + 2][j - 1] = false;break;

case 1: //From downleft & upright to rightup & leftdown: Same as case 1

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 2][j + 1] == true)

return false;if (board[i][j + 2] == true)

return false;//Perform transformationbox[i + 2][j + 1] = true;box[i][j + 2] = true;box[i][j] = false;box[i][j + 1] = false;break;

case 2: //From rightup & leftdown to downleft & upright: SAme as case 2

//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 1){

if (moveRight() == false)

Page 50: Tetris

return false;j = j + 1;

}//Check availabilityif (board[i][j -2] == true)

return false;if (board[1][j - 1] == true)

return false;//Perform transformationbox[i][j - 2] = true;box[i][j - 1] = true;box[i][j] = false;box[i + 2][j - 1] = false;break;

}break;

case Values.PIECE_6: // 'T'- shaped//Switch new rotation stateswitch (rotation - 1){

case -1: //From top faced to right faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 18)

return false;if (board[i + 2][j] == true)

return false;//Perform transformationbox[i + 2][j] = true;box[i + 1][j + 1] = false;break;

case 0: //From right faced to bottom faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//If its behind a wall, try to move

rightif (j == 0){

if (moveRight() == false)return false;

j = j + 1;}//Check availabilityif (board[i + 1][j - 1] == true)

return false;//Perform transformation

Page 51: Tetris

box[i + 1][j - 1] = true;box[i + 2][j] = false;break;

case 1: //From bottom faced to left faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 9){

j = 0;i++;

}}//Check availabilityif (i == 0)

return false;if (board[i - 1][j + 1] == true)

return false;//Perform transformationbox[i - 1][j + 1] = true;box[i][j] = false;break;

case 2: //From left faced to top faced//Find the first occupied boxwhile (box[i][j] == false){

j++;if (j == 10){

j = 0;i++;

}}//If its behind a wall, try to move leftif (j == 9){

if (moveLeft() == false)return false;

j = j - 1;}//Check availabilityif (board[i + 1][j + 1] == true)

return false;//Perform transformationbox[i + 1][j + 1] = true;box[i][j] = false;break;

}break;

}//Change rotation staterotation--;if (rotation == -1)

rotation = 3;return true;

}}

Tetris.java

Page 52: Tetris

package android.tetris;

import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.widget.Button;

public class Tetris extends Activity {

private Button btnNewGame, btnHighScores, btnAbout, btnExit;

/** Called when the activity is first created. */ @Override

public void onCreate(Bundle savedInstanceState) { //Assign layouts super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.main); //Find and assign buttons btnNewGame = (Button) findViewById(R.id.buttonNewGame); btnNewGame.setOnClickListener(new OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(Tetris.this, Game.class); startActivity(intent);

} }); btnHighScores = (Button) findViewById(R.id.buttonHighScores); btnHighScores.setOnClickListener(new OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(Tetris.this, HighScores.class); startActivity(intent);

} });

btnAbout = (Button) findViewById(R.id.buttonAbout); //btnResumeGame.setEnabled(false); //Disabled (unimplemented feature) btnAbout.setOnClickListener(new OnClickListener(){ public void onClick(View v) { Intent intent = new Intent(Tetris.this, About.class); startActivity(intent);

} });

btnExit = (Button) findViewById(R.id.buttonExit); btnExit.setOnClickListener(new OnClickListener(){ public void onClick(View v) { finish();

} }); }

Page 53: Tetris

}

Values.java

package android.tetris;

public final class Values {

//Score codespublic static final int SCORE_PER_ROW = 1000;

//Color codespublic static final byte COLOR_NONE = 0;public static final byte COLOR_RED = 1;public static final byte COLOR_GREEN = 2;public static final byte COLOR_BLUE = 3;public static final byte COLOR_YELLOW = 4;public static final byte COLOR_PINK = 5;public static final byte COLOR_PURPLE = 6;public static final byte COLOR_WHITE = 7;

//Piece codes//0000//0000//1111//0000public static final byte PIECE_0 = 0;//0000//0100//0111//0000public static final byte PIECE_1 = 1;//0000//0001//0111//0000public static final byte PIECE_2 = 2;//0000//0110//0110//0000public static final byte PIECE_3 = 3;//0000//0011//0110//0000public static final byte PIECE_4 = 4;//0000//0110//0011//0000public static final byte PIECE_5 = 5;//0000//0010//0111

Page 54: Tetris

//0000public static final byte PIECE_6 = 6;

}

BuildConfig.java

/** Automatically generated file. DO NOT MODIFY */package android.tetris;

public final class BuildConfig { public final static boolean DEBUG = true;}