天天看點

《Java語言程式設計》大作業報告 九宮格遊戲

《Java語言程式設計》大作業報告

中國石油大學(北京)2015 — 2016 學年第二學期

班級:_____計算機14-1_______

姓名:_____  許 恺_________________

學号:______2014011329___________

  1. 題意分析

程式首先需要九個可以移動的格子,大小相等,有字元串标示,其次要可以相應滑鼠和鍵盤方向鍵的控制,可以自由移動,并且與此同時記錄步數,最後在滿足條件時彈出對話框并顯示步數以及是否打破記錄,關于打破記錄還需要檔案的操作。

        需要用到事件監聽和鍵盤監聽借口和方法,以及按鈕的出發,還有檔案的讀寫和對話框等技術。

  1. 程式設計思路

(1) 首先将容器的大小确定,劃分成九個的網格布局。

this.setLayout(new GridLayout(3,3));

(2) 按照一定的邏輯算法,随機将0~8九個button放到九個網格中。

public void init(){ //初始化使用算法使其随機出現,并填加格子以及事件監聽和鍵盤監聽

for(int i = 0;i < 8;i++)

        {

            this.num[i] = i+1;

        }

        this.num[8] = -1;

        this.num[5] = -1;

        this.num[8] = 6;

        for(int i = 0;i < 8;i++)

            int idx =(int) (Math.random() * 8);

            int tmp = this.num[7];

            this.num[7] = this.num[idx];

            this.num[idx] = tmp;

           }

for(int i = 0;i < 3;i++)

             for(int j = 0;j < 3;j++)

             {

                if(this.num[i * 3 + j] != -1)

                {

                    Game.Buttons[i][j] =  new JButton("" + this.num[i * 3 + j]);

                    Game.Buttons[i][j].addActionListener(this);

                    Game.Buttons[i][j].addKeyListener(this);

                    this.getContentPane().add(Game.Buttons[i][j]);

               }

               else

                    Game.Buttons[i][j] =  new JButton("");

                    Game.Buttons[i][j].setEnabled(false);

                }

            }

}

(3) 設計button的點選事件,和鍵盤的響應事件(實作方法代碼見源程式)

(4) 通過移動button完成遊戲響應檢查函數彈出成功對話框顯示步數和是否打破記錄(實作方法代碼見源程式)

(5) 點選對話框的“是”再來一次

《Java語言程式設計》大作業報告 九宮格遊戲
  1. 關鍵功能說明

(1) 九宮格初始化子產品:按照一定算法将0~8随機安放到9個格子中;添加控件添加事件監聽。

(2) Button按鈕觸發事件子產品:找出觸發的button,找出他的四周有沒有空的格子,如果有則交換,沒有則不動,交換後判斷此狀态是否勝利,是否彈出對話框,讀出曆史最佳紀錄,判斷是否打破紀錄寫入檔案。

(3) 鍵盤事件監聽子產品:找到空的格子,根據觸發的按鍵,判斷空格子的反方向有沒有button,如果有則交換,沒有則不動,交換後判斷此狀态是否勝利,是否彈出對話框,讀出曆史最佳紀錄,判斷是否打破紀錄寫入檔案。

(4) 是否成功子產品:依次判斷格子的字元串是否分别是“1”“2”“3”“4”“5”“6”“7”“8”,是則傳回true,否則傳回false。

  1. 運作結果及分析
《Java語言程式設計》大作業報告 九宮格遊戲
《Java語言程式設計》大作業報告 九宮格遊戲

因為是位元組流儲存,是以顯示是字元

《Java語言程式設計》大作業報告 九宮格遊戲
  1. 設計經驗總結

剛剛開始感覺很難,因為對圖形界面太不了解了,有的函數和類都不知道,是以超級難入手,但是當看網上的代碼和同學的多了之後也就知道該怎麼編了,一旦入手,後面的就感覺沒有那麼難了,現在編完了就感覺圖形界面也就那麼回事,都是固定的模式,子產品添加也很簡單,雖然還是有很多不懂的地方但是相比于做大作業之前已經有很多的提高了,還認識了很多不認識的元件,同學們都用了不同的方法,我用的是網格布局然後添加button,感覺這樣界面友好一點。彈出的對話框可以JOptionPane而不是再定義JDialog,檔案的讀寫方法很多,選一種自己了解的就好。

總的來說學到了很多知識,更加鞏固了本來就很薄弱的java。

附:源程式

package com.Game1;

import java.awt.*;
import java.awt.event.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.*;

public class Game extends JFrame implements ActionListener,KeyListener{
    
    int number_path=0;       //記錄步數
    int best_recond=0;        //最佳成績
    int replay=0;
    int[] num={1,2,3,4,5,6,7,8,0};
    String str="已走步數:";
    String str1="最佳成績:";
    static JButton[][] Buttons=new JButton[3][3];        //九宮格
    public Game(){            
        super("九宮格遊戲");
        this.setBounds(400,100,700,700);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLayout(new GridLayout(3,3));
        this.init();
        this.setVisible(true);
    }
    public void init(){        //初始化使用算法使其随機出現,并填加格子以及事件監聽和鍵盤監聽
        for(int i = 0;i < 8;i++)
        {
            this.num[i] = i+1;
        }
        this.num[8] = -1;
        this.num[5] = -1;
        this.num[8] = 6;
        for(int i = 0;i < 8;i++)
        {
            int idx =(int) (Math.random() * 8);
            int tmp = this.num[7];
            this.num[7] = this.num[idx];
            this.num[idx] = tmp;
        }
        for(int i = 0;i < 3;i++)
        {
            for(int j = 0;j < 3;j++)
            {
                if(this.num[i * 3 + j] != -1)
                {
                    Game.Buttons[i][j] =  new JButton("" + this.num[i * 3 + j]);
                    Game.Buttons[i][j].addActionListener(this);
                    Game.Buttons[i][j].addKeyListener(this);
                    this.getContentPane().add(Game.Buttons[i][j]);
                }
                else
                {
                    Game.Buttons[i][j] =  new JButton("");
                    Game.Buttons[i][j].addActionListener(this); 
                    Game.Buttons[i][j].addKeyListener(this);
                    this.getContentPane().add(Game.Buttons[i][j]);
                    Game.Buttons[i][j].setEnabled(false);
                }
            }
        }
    }
    @Override
    public void actionPerformed(ActionEvent e) {    //滑鼠事件監聽,交換格子内容步數加1
        int i,j;
        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
                if(e.getSource()==Buttons[i][j]){
                    if(i+1!=3&&Buttons[i+1][j].getText()==""){
                        Buttons[i+1][j].setText(Buttons[i][j].getText());
                        Buttons[i+1][j].setEnabled(true);
                        Buttons[i][j].setText("");
                        Buttons[i][j].setEnabled(false);
                        number_path++;
                    }
                    if(i-1!=-1&&Buttons[i-1][j].getText()==""){
                        Buttons[i-1][j].setText(Buttons[i][j].getText());
                        Buttons[i-1][j].setEnabled(true);
                        Buttons[i][j].setText("");
                        Buttons[i][j].setEnabled(false);
                        number_path++;
                    }
                    if(j+1!=3&&Buttons[i][j+1].getText()==""){
                        Buttons[i][j+1].setText(Buttons[i][j].getText());
                        Buttons[i][j+1].setEnabled(true);
                        Buttons[i][j].setText("");
                        Buttons[i][j].setEnabled(false);
                        number_path++;
                    }
                    if(j-1!=-1&&Buttons[i][j-1].getText()==""){
                        Buttons[i][j-1].setText(Buttons[i][j].getText());
                        Buttons[i][j-1].setEnabled(true);
                        Buttons[i][j].setText("");
                        Buttons[i][j].setEnabled(false);
                        number_path++;
                    }
                }
            }
        }
        if(winfail()){    //判斷這次操作後是否勝利,讀出最佳成績,并判斷是否打破記錄
            try {
                FileInputStream  fin=new FileInputStream("bestrecond.int");
                DataInputStream din=new DataInputStream(fin);
                best_recond=din.readInt();
                din.close();
                fin.close();
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            if(number_path>best_recond){
                JOptionPane.showConfirmDialog(this,"你太厲害了!!這麼難都能赢!!!才用了"+Integer.toString(number_path)+"步!!然而并沒有打破記錄。曆史最佳成績是:"+Integer.toString(best_recond));
                if(replay==JOptionPane.YES_OPTION){
                    Game G=new Game();
                }
            }
            else{
                JOptionPane.showConfirmDialog(this,"你太厲害了!!這麼難都能赢!!!才用了"+Integer.toString(number_path)+"步!!打破了曆史記錄!!曆史最佳成績是:"+Integer.toString(best_recond));
                try {
                    FileOutputStream  fin=new FileOutputStream("bestrecond.int");
                    DataOutputStream din=new DataOutputStream(fin);
                    din.writeInt(number_path);
                    din.close();
                    fin.close();
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                if(replay==JOptionPane.YES_OPTION){
                    Game G=new Game();
                }
            }
        }
    }
    public void keyPressed(KeyEvent e){        //鍵盤事件監聽,交換格子内容步數加1
        int i,j;
        boolean b=false;
        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
                if(Buttons[i][j].getText()==""){
                    if(i+1!=3&&e.getKeyCode()==KeyEvent.VK_UP){
                        Buttons[i][j].setEnabled(true);
                        Buttons[i][j].setText(Buttons[i+1][j].getText());
                        Buttons[i+1][j].setText("");
                        Buttons[i+1][j].setEnabled(false);
                        number_path++;
                        b=true;break;
                    }
                    if(i-1!=-1&&e.getKeyCode()==KeyEvent.VK_DOWN){
                        Buttons[i][j].setEnabled(true);
                        Buttons[i][j].setText(Buttons[i-1][j].getText());
                        Buttons[i-1][j].setText("");
                        Buttons[i-1][j].setEnabled(false);
                        number_path++;
                        b=true;break;
                    }
                    if(j+1!=3&&e.getKeyCode()==KeyEvent.VK_LEFT){
                        Buttons[i][j].setEnabled(true);
                        Buttons[i][j].setText(Buttons[i][j+1].getText());
                        Buttons[i][j+1].setText("");
                        Buttons[i][j+1].setEnabled(false);
                        number_path++;
                        b=true;break;
                    }
                    if(j-1!=-1&&e.getKeyCode()==KeyEvent.VK_RIGHT){
                        Buttons[i][j].setEnabled(true);
                        Buttons[i][j].setText(Buttons[i][j-1].getText());
                        Buttons[i][j-1].setText("");
                        Buttons[i][j-1].setEnabled(false);
                        number_path++;
                        b=true;break;
                    }
                }
            } 
            if(b) break;
        }
        if(winfail()){        //判斷這次操作後是否勝利,讀出最佳成績,并判斷是否打破記錄
            try {
                FileInputStream  fin=new FileInputStream("bestrecond.int");
                DataInputStream din=new DataInputStream(fin);
                best_recond=din.readInt();
                din.close();
                fin.close();
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            if(number_path>best_recond){
                JOptionPane.showConfirmDialog(this, "你太厲害了!!這麼難都能赢!!!才用了"+Integer.toString(number_path)+"步!!然而并沒有打破記錄。曆史最佳成績是:"+Integer.toString(best_recond));
                if(replay==JOptionPane.YES_OPTION){
                    Game G=new Game();
                }
            }
            else{
                JOptionPane.showConfirmDialog(this, "你太厲害了!!這麼難都能赢!!!才用了"+Integer.toString(number_path)+"步!!打破了曆史記錄!!曆史最佳成績是:"+Integer.toString(best_recond));
                try {
                    FileOutputStream  fin=new FileOutputStream("bestrecond.int");
                    DataOutputStream din=new DataOutputStream(fin);
                    din.writeInt(number_path);
                    din.close();
                    fin.close();
                } catch (FileNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                if(replay==JOptionPane.YES_OPTION){
                    Game G=new Game();
                }
            }
        }
    }
    public static boolean winfail(){     //判斷輸赢函數,每個格的字元都符合即可
        int i,j,k=1,n=0;
        for(i=0;i<3;i++){
            for(j=0;j<3;j++){
                if(Buttons[i][j].getText().equals(Integer.toString(k++))){
                    n++;
                }
            }
        }
        if(n>=8) return true;
        return false;
    }
    public static void main(String[] args) {
        
        Game G=new Game();
    }
    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
        
    }
}