import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
 public class Matrix extends JPanel...{
private JLabel matrix[][];
public static final int ROW = 20;
public static final int COLUMN = 15;
private MatrixModel model;
 public Matrix()...{
this.setLayout(new GridLayout(ROW, COLUMN));
init();
Dimension size = new Dimension(COLUMN*20, ROW*20);
this.setPreferredSize(size);
this.setMinimumSize(size);
this.setMaximumSize(size);
this.addKeyListener(new MyKeyListener());
this.setFocusable(true);
model = new MatrixModel(this);
}
 public void start()...{
model.start();
}
 private void init()...{
matrix = new JLabel[ROW][COLUMN];
JLabel label = null;
 for(int i=0; i<ROW; i++)...{
 for(int j=0; j<COLUMN; j++)...{
label = new JLabel(" ");
label.setBorder(new LineBorder(Color.GRAY));
label.setOpaque(true);
matrix[i][j] = label;
add(matrix[i][j]);
}
}
}
 public void displayState(int[][] state)...{
 for(int i=0; i<state.length; i++)...{
 for(int j=0; j<state[i].length; j++)...{
 if(state[i][j] == 1)...{
matrix[i][j].setBackground(Color.red);
 }else...{
matrix[i][j].setBackground(Color.black);
}
}
}
}
 class MyKeyListener extends KeyAdapter...{
 public void keyPressed(KeyEvent e) ...{
 if(e.getKeyCode() == KeyEvent.VK_LEFT)...{
model.moveLeft();
}
 else if(e.getKeyCode() == KeyEvent.VK_RIGHT)...{
model.moveRight();
 }else if(e.getKeyCode() == KeyEvent.VK_DOWN)...{
model.down();
 }else if(e.getKeyCode() == KeyEvent.VK_UP)...{
model.rotateSharp();
}
}
}
 public static void main(String arg[])...{
JFrame frame = new JFrame();
Matrix matrix = new Matrix();
matrix.start();
frame.add(new JScrollPane(matrix));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
 /**//*
int i[][] = {{10,20}, {11, 21}, {21, 31}};
int j[][] = new int[3][2];
System.arraycopy(i, 0, j, 0, i.length);
for(int x=0; x<j.length; x++){
for(int y=0; y<j[x].length; y++){
System.out.print(j[x][y]+" ");
}
System.out.println();
}*/
}
}
 import java.util.*;
 public class MatrixModel...{
private int model[][];
private int sharp[][];
private int state[][];
private int currentX, currentY;
private Matrix myParent;
private RunThread runThread;
private int currentIndex;
 public MatrixModel(Matrix parent)...{
myParent = parent;
model = new int[Matrix.ROW][Matrix.COLUMN];
state = new int[Matrix.ROW][Matrix.COLUMN];
newSharp();
}
 public void start()...{
runThread = new RunThread();
runThread.start();
}
 private int[][] randomSharp()...{
currentIndex = (int)(MatrixSharp.NUMBER*Math.random());
return MatrixSharp.sharp[currentIndex];
}
 private synchronized boolean isMoveAvaliable(int currentX, int currentY)...{
 if(currentX>Matrix.COLUMN-1)...{
return false;
}
 if(currentX<0)...{
 for(int i=0; i<4; i++)...{
for(int j=0; j<Math.abs(currentX); j++)
 if(sharp[i][j] != 0)...{
return false;
}
}
}
 if(currentY<0 || currentY>Matrix.ROW-1)...{
return false;
}
 for(int x=0; x<4; x++)...{
 for(int y=0; y<4; y++)...{
 if(currentX+x>-1 && currentX+x<Matrix.COLUMN && currentY+y<Matrix.ROW )...{
 if((sharp[y][x] & model[currentY+y][currentX+x]) != 0)...{
return false;
}
 }else...{
 if(currentX+x >= Matrix.COLUMN)...{
 if(sharp[y][x] != 0)...{
return false;
}
}
 else if(currentY+y >= Matrix.ROW)...{
 if(sharp[y][x] != 0)...{
return false;
}
}
}
}
}
return true;
}
 private synchronized void moveTo(int x, int y)...{
 for(int i=0; i<Matrix.ROW; i++)...{
 for(int j=0; j<Matrix.COLUMN; j++)...{
state[i][j] = model[i][j];
}
}
 for(int c=0; c<4; c++)...{
 for(int r=0; r<4; r++)...{
 if(currentX+c>-1 && currentX+c<Matrix.COLUMN && currentY+r<Matrix.ROW)...{
state[currentY+r][currentX+c] |= sharp[r][c];
}
}
}
myParent.displayState(state);
}
 public void over()...{
System.out.println("game over");
runThread.end();
}
 public synchronized void moveLeft()...{
 if(isMoveAvaliable(currentX-1, currentY))...{
currentX -= 1;
moveTo(currentX, currentY);
}
}
 public synchronized void moveRight()...{
 if(isMoveAvaliable(currentX+1, currentY))...{
currentX += 1;
moveTo(currentX, currentY);
}
}
 private boolean isOver()...{
 if(currentY==0)...{
return false;
}
return false;
}
 private synchronized void resetState()...{
state = new int[Matrix.ROW][Matrix.COLUMN];
moveTo(currentX, currentY);
}
 public synchronized void down()...{
 if(isMoveAvaliable(currentX, currentY+1))...{
currentY += 1;
moveTo(currentX, currentY);
 }else...{
 if(isOver())...{
over();
return;
}
model = state;
check();
resetState();
newSharp();
}
}
 public synchronized void check()...{
Vector clearVector = new Vector();
 for(int i=Matrix.ROW-1; i>< |