import javax.swing.JPanel ;
import java.awt.Graphics ;
import java.awt.BorderLayout ;
import java.awt.Color ;
import java.util.ArrayList ;
public class MobileSorter extends JFrame {
//上邊距
public static final int TOP_SPA = 100 ;
//左邊距
public static final int LEFT_SPA = 100 ;
public static void main(String args[]) {
JFrame.setDefaultLookAndFeelDecorated(true) ;
MobileSorter ms = new MobileSorter() ;
ms.setVisible(true) ;
}
public MobileSorter() {
//設置窗體大小
this.setSize(400 ,400) ;
//new出組件
MyPanel p = new MyPanel() ;
//布置窗體
this.setLayout(new BorderLayout()) ;
this.add(p ,BorderLayout.CENTER) ;
//啟動線程
Thread t = new Thread(p) ;
t.start() ;
}
}
class MyPanel extends JPanel implements Runnable {
//存儲圓數據的數組
private ArrayList ca = new ArrayList(9);
/**
* 中心圓
*/
private Circle cCenter = null ;
public MyPanel() {
init() ;
}
public void paint(Graphics g) {
//畫與5號位的斜連接線
for (int i = 0; i<9; i++) {
if (i == 4) continue ;
Circle.drawLine(g ,(Circle)ca.get(4) ,(Circle) ca.get(i)) ;
}
//垂直和橫線和豎線
g.setColor(Color.BLACK) ;
for (int i = 0; i<9; i++)
for (int j = 0; j<9; j++)
if (i != j && i < j)
if (j - i ==3 || (i + 1 == j && j%3 != 0))
Circle.drawLine(g , (Circle) ca.get(i) ,(Circle) ca.get(j)) ;
/** 畫圓 */
for (int i = 0; i<9; i++)
((Circle) ca.get(i)).drawMe(g) ;
}
/**
* 初始化
*/
public void init() {
//創建圓
for (int i = 1; i<10; i++)
this.ca.add(new Circle(i)) ;
//生成圓內的數
int[] n = new int[9] ;
for (int i = 0; i<n.length; ) {
int c ;
c = (int)(Math.random() * 8) + 1 ;
boolean isRepeat = false ;
for (int j = 0; j<i; j++)
if (n[j] == c) {
isRepeat = true ;
break ;
}
if (isRepeat) continue ;
if (i == 4) i ++ ;
((Circle)this.ca.get(i)).setNum(c) ;
n[i] = c ;
i ++ ;
}
}
/**
* 線程
*/
public void run() {
int oPos = 0 ; //值為1的圓的標號
int sPos ; //值為1的圓的下壹個圓的標號
int ePos ; //終端圓標號
int cPos = 0 ; //操作圓標號
cCenter = (Circle)this.ca.get(4) ; //中心圓
//找出圓內數字的1的圓
for (int i = 0; i<this.ca.size(); i++)
if (((Circle)this.ca.get(i)).getNum() == 1) {
oPos = i ;
break ;
}
sPos = Circle.getNextDeasil(oPos) ;
ePos = oPos ;
while (true) {
cPos = sPos ;
while (true) {
Circle c = (Circle)this.ca.get(cPos) ;
Circle n = (Circle)this.ca.get(Circle.getNextDeasil(cPos)) ;
checkSwap(c ,n) ;
cPos = Circle.getNextDeasil(cPos) ;
if(ePos == Circle.getNextDeasil(cPos)) {
ePos = cPos ;
break ;
}
}
if (ePos == Circle.getNextDeasil(sPos)) {
System.out.println ("OVER!") ;
break ;
}
}
}
/**
* 延遲
*/
private void animation() {
this.repaint() ;
try { Thread.sleep(1000) ;}catch (Exception ex) { }
}
/**
* 交換
*/
private void checkSwap(Circle c ,Circle n) {
int cNum = c.getNum() ;
int nNum = n.getNum() ;
if (cNum > nNum) {
cCenter.setNum(n.getNum()) ;
n.setNum(0) ;
this.animation() ;
n.setNum(c.getNum()) ;
c.setNum(0) ;
this.animation() ;
c.setNum(cCenter.getNum()) ;
cCenter.setNum(0) ;
this.animation() ;
}
}
}
class Circle {
/**
* 各圓之間的間距
*/
public static final int CIR_SPA_BET = 60 ;
/**
* 圓的直徑
*/
public static final int CIR_WD = 30 ;
/**
* 圓的標號 ,1-9
*/
private int pos ;
/**
* 圓的左上角x坐標
*/
private int x ;
/**
* 圓的左上角y坐標
*/
private int y ;
/**
* 圓內的數
*/
private int num ;
public Circle(int pos) {
this.pos = pos ;
this.x = MobileSorter.LEFT_SPA + (pos-1) % 3 * CIR_SPA_BET ;
this.y = MobileSorter.TOP_SPA + (pos-1) / 3 * CIR_SPA_BET ;
}
/**
* 畫圓與圓中的數字
*/
public void drawMe(Graphics g) {
//圓
g.setColor(Color.BLACK) ;
g.fillOval(x ,y ,CIR_WD ,CIR_WD) ;
//數字
g.setColor(Color.WHITE) ;
if (num != 0)
g.drawString(String.valueOf(num)
,x + CIR_WD / 2 - 3 ,y + CIR_WD / 2 + 5) ;
else
g.drawString("空"
,x + CIR_WD / 2 - 3 ,y + CIR_WD / 2 + 5) ;
}
/**
* 畫兩個圓之間的連接線
*/
public static void drawLine(Graphics g ,Circle a , Circle b) {
g.drawLine(a.getX() + Circle.CIR_WD / 2
,a.getY() + Circle.CIR_WD / 2
,b.getX() + Circle.CIR_WD / 2
,b.getY()+ Circle.CIR_WD / 2) ;
}
public void setNum(int num) {
this.num = num ;
}
public int getX() {
return x ;
}
public int getY() {
return y ;
}
public int getPos() {
return pos ;
}
public int getNum() {
return num ;
}
public static int getNextDeasil(int pos) {
if (pos >=0 && pos <=8 && pos != 4) {
if (pos == 0)
return 1 ;
else if (pos == 1)
return 2 ;
else if (pos == 2)
return 5 ;
else if (pos == 3)
return 0 ;
else if (pos == 5)
return 8 ;
else if (pos == 6)
return 3 ;
else if (pos == 7)
return 6 ;
else if (pos == 8)
return 7 ;
}
return -1 ;
}
/**
* 根據順時針方向返回下個圓的標號
*/
public int getNextDeasil() {
if (pos >=0 && pos <=8 && pos != 4) {
if (pos == 0)
return 1 ;
else if (pos == 1)
return 2 ;
else if (pos == 2)
return 5 ;
else if (pos == 3)
return 0 ;
else if (pos == 5)
return 8 ;
else if (pos == 6)
return 3 ;
else if (pos == 7)
return 6 ;
else if (pos == 8)
return 7 ;
}
return -1 ;
}
}