利用大學所習得的迴圈技巧解出魔方陣可能解,並設計遊戲方式讓玩家可以動腦破關,設置難度為三關,點擊灰色方塊並可與黃色方塊交換,直到上下左右以及對角數字相加相等。
(一)解答畫面
(二)解答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(); } }); } }(四)檔案下載
留言
張貼留言