利用大學所習得的迴圈技巧解出魔方陣可能解,並設計遊戲方式讓玩家可以動腦破關,設置難度為三關,點擊灰色方塊並可與黃色方塊交換,直到上下左右以及對角數字相加相等。
(一)解答畫面
(二)解答Model
public class Model {
private String sCheck[] = new String[4];
private StringBuilder sResult ;
private int iNum;
public void setNum(int iRow,int iCol){//設置九宮格
int n = iRow;
iNum = 0;
sResult = new StringBuilder();
for (int i = 0; i < sCheck.length; i++) {sCheck[i] = "";}
int v[] = new int[iRow*iCol];
init(v);
int a[] = new int [iRow*iCol];
magic_UL(a,v,n);
print(a,n);
a = new int [iRow*iCol];
magic_UR(a,v,n);
print(a,n);
a = new int [iRow*iCol];
magic_IL(a,v,n);
print(a,n);
a = new int [iRow*iCol];
magic_IR(a,v,n);
print(a,n);
}
private void init(int[] v) {
for (int i = 0; i < v.length; i++) {v[i] = i+1;}
}
private void magic_UL(int[] a, int[] v, int n) {//第一組解
int r = 0,c = n/2,newr = 0,newc = 0;
for (int i = 0; i < v.length; i++) {
a[r*n+c] = v[i];
newr = ((r-1)+n) % n;
newc = ((c-1)+n) % n;
if (a[newr*n+newc] != 0){
newr = r+1;
newc = c;
}
r = newr;
c = newc;
}
}
private void magic_UR(int[] a, int[] v, int n) {//第二組解
int r = 0,c = n/2,newr = 0,newc = 0;
for (int i = 0; i < v.length; i++) {
a[r*n+c] = v[i];
newr = ((r-1)+n) % n;
newc = ((c+1)+n) % n;
if (a[newr*n+newc] != 0){
newr = r+1;
newc = c;
}
r = newr;
c = newc;
}
}
private void magic_IL(int[] a, int[] v, int n) {//第三組解
int r = n-1,c = n/2,newr = 0,newc = 0;
for (int i = 0; i < v.length; i++) {
a[r*n+c] = v[i];
newr = ((r+1)+n) % n;
newc = ((c-1)+n) % n;
if (a[newr*n+newc] != 0){
newr = r-1;
newc = c;
}
r = newr;
c = newc;
}
}
private void magic_IR(int[] a, int[] v, int n) {//第四組解
int r = n-1,c = n/2,newr = 0,newc = 0;
for (int i = 0; i < v.length; i++) {
a[r*n+c] = v[i];
newr = ((r+1)+n) % n;
newc = ((c+1)+n) % n;
if (a[newr*n+newc] != 0){
newr = r-1;
newc = c;
}
r = newr;
c = newc;
}
}
private void print(int[] a, int n) {//印出解答
sResult.append("第" + (iNum+1) + "組為:\n");
for (int i = 0; i < a.length; i++) {
sCheck[iNum] += a[i];
sResult.append(String.format("%3d |", a[i]));
if (i%n == n-1){sResult.append("\n--------------------------\n");}
}
iNum ++ ;
}
public String getResult(){
return sResult.toString();
}
public String[] getCheck(){
return sCheck;
}
}
(三)UIView
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class StyleBox_View extends JFrame implements ActionListener{
private JPanel jpNorth = new JPanel(new FlowLayout());
private JPanel jpWest = new JPanel();
private JPanel jpCenter= new JPanel(new FlowLayout());
private JPanel jpEast = new JPanel();
private JLabel jlTitle = new JLabel("請選擇關卡");
private JComboBox jCom = new JComboBox();
private JButton jbStart = new JButton("Start");
private JButton jbResult = new JButton("看答案");
private JButton jbExplain = new JButton("說明");
private int iCol,iRow;//欄列
private JButton[][] jbGame;//宣告按鈕陣列
private JButton jbSource,jbTarget;// 記錄移動視窗按鈕,及目標按鈕
private int [] myRandom;//建立亂數陣列供排列
private Model m = new Model();//處理答案的Model
private JTextArea jta = new JTextArea();//答案文字
private JScrollPane js;//捲軸
public StyleBox_View(){
super();
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
int screenHeight = (int) screenSize.getHeight();// 解析度長
int screenWidth = (int) screenSize.getWidth();// 解析度寬
this.getContentPane().setBackground(Color.CYAN);
this.setSize(800,600);
this.setLocation(screenWidth / 2 - this.getWidth() / 2, screenHeight / 2
- this.getHeight() / 2);// 設定Frame置中
getjpNorth();
this.add(jpNorth,BorderLayout.NORTH);
this.setVisible(true);
jbResult.addActionListener(this);
jbExplain.addActionListener(this);
}
private void getjpNorth() {
jpNorth.add(jlTitle);
getjCom();
jpNorth.add(jCom);
jbStart.addActionListener(this);
jpNorth.add(jbStart);
jpNorth.add(jbExplain);
}
private void getjCom() {
DefaultComboBoxModel com = new DefaultComboBoxModel();
for (int i = 0; i < 3; i++) {com.addElement(i+1);}
jCom.setModel(com);
jCom.addActionListener(this);
}
private void Start() {
if (jCom.getSelectedIndex() == 0) {iCol = 3;iRow = 3;}
if (jCom.getSelectedIndex() == 1) {iCol = 5;iRow = 5;}
if (jCom.getSelectedIndex() == 2) {iCol = 7;iRow = 7;}
m.setNum(iRow, iCol);
myRandom = new int[iRow*iCol];//建立亂數陣列供排列
getRandomArray();
jpWest.setLayout(new GridLayout(iRow, iCol));
jpWest.removeAll();
jpCenter.removeAll();
jpEast.removeAll();
int btnCount = 1; //記錄共有多少個按鈕
jbGame = new JButton[iRow][iCol];
for (int i = 0; i < iRow; i++) {
for (int j = 0; j < iCol; j++) {
jbGame[i][j] = new JButton();
jbGame[i][j].setText("" + myRandom[btnCount-1]);//利用亂數陣列來定義按鈕內文字
jbGame[i][j].setBackground(Color.YELLOW); //定義按鈕顏色
jbGame[i][j].addMouseListener(new MouseAdapter() { //建立滑鼠事件
public void mousePressed(MouseEvent e) {
JButton mb = (JButton) e.getSource();
btnCheck(mb); //當此按鈕被點擊時,執行 btnCheck()
}
});
jpWest.add(jbGame[i][j]);
btnCount++;
}
}
setGame();
this.add(jpWest,BorderLayout.WEST);
jpCenter.add(jbResult);
this.add(jpCenter,BorderLayout.CENTER);
jbStart.setEnabled(false);
jbResult.setEnabled(true);
pack();
}
private void getRandomArray() {
int iNOOFRND = iRow * iCol - 1;
int iLoopCount = 0;
int iResult = 0;
while (iLoopCount < iNOOFRND) {
iResult = 1 + (int) (iNOOFRND * Math.random());
if (!bFound(myRandom, iResult, iLoopCount)) {
myRandom[iLoopCount] = iResult;
iLoopCount++;
}
}
myRandom[iRow * iCol - 1] = 0;
}
private boolean bFound(int iA[], int iR, int iLimit) {//檢查是否解答完成
for (int i = 0; i <= iLimit; i++) {if (iA[i] == iR) {return true;}}
return false;
}
private void btnCheck(JButton mb) {
for (int i = 0; i < iRow; i++) {
for (int j = 0; j < iCol; j++) {
if (mb == jbGame[i][j]) {
jbTarget = jbGame[i][j];
btnChange(jbSource, jbTarget); //呼叫btnChange()來動移按鈕
}
}
}
}
private void setGame() {
jbGame[iRow - 1][iCol - 1].setText((iRow*iCol) + ""); //將最後一個按鈕文字改為數字9
jbGame[iRow - 1][iCol - 1].setBackground(Color.GRAY); //修改最後一按鈕顏色
jbGame[iRow - 1][iCol - 1].setFocusable(true); //將駐點放在最後一個按鈕上
jbSource = jbGame[iRow - 1][iCol - 1]; //記錄最後一按鈕為移動視窗按鈕
}
private void btnChange(JButton jbSource, JButton jbTarget) {
String tmp = jbSource.getText(); //將來源端按鈕上之數字存進 tmp中
jbSource.setText(jbTarget.getText()); //將來源端按鈕文字變成目的端按鈕文字
jbTarget.setText(tmp); //將目的端按鈕文字變成 tmp值
jbSource.setBackground(Color.YELLOW); // 來源端變橘色
jbTarget.setBackground(Color.GRAY); // 目的端變藍色
this.jbSource = jbTarget; //將記錄按鈕位址存為目的端
checkWin(); //檢查是否勝利
}
private void getEastJPanel() {
jpEast.removeAll();
jpEast.setLayout(new BorderLayout());
js = new JScrollPane(jta);
jpEast.add(js);
this.add(jpEast,BorderLayout.EAST);
jta.setText(m.getResult());
pack();
}
private void checkWin() {//確認是否獲勝
String sNow = "";
for (int i = 0; i < iRow; i++) {
for (int j = 0; j < iCol; j++) {
sNow += jbGame[i][j].getText(); //取得nowStr目前btn狀態字串
}
}
String sCheck[] = m.getCheck();//取出四組解答
for (int i = 0; i < sCheck.length; i++) {//巡邏檢查
if (sNow.equals(sCheck[i])) {
JOptionPane.showMessageDialog(this, "恭喜過關");
break;
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jbStart){Start();}
else if (e.getSource() == jbResult){
getEastJPanel();
jbResult.setEnabled(false);
jbStart.setEnabled(true);
jpWest.removeAll();
this.validate();
}else if (e.getSource() == jCom){Start();}
else if (e.getSource() == jbExplain){
JOptionPane.showMessageDialog(this, "點擊黃色格子會與灰色格子互換\n直到上下左右及對角數字相加相等就可過關");
}
}
public static void main(String[] args) {
final StyleBox_View sv = new StyleBox_View();
sv.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
sv.addWindowStateListener(new WindowStateListener() {
@Override
public void windowStateChanged(WindowEvent e) {
sv.pack();
}
});
}
}
(四)檔案下載


留言
張貼留言