《Java语言程序设计》大作业报告
中国石油大学(北京)2015 — 2016 学年第二学期
班级:_____计算机14-1_______
姓名:_____ 许 恺_________________
学号:______2014011329___________
- 题意分析
程序首先需要九个可以移动的格子,大小相等,有字符串标示,其次要可以相应鼠标和键盘方向键的控制,可以*移动,并且与此同时记录步数,最后在满足条件时弹出对话框并显示步数以及是否打破记录,关于打破记录还需要文件的操作。
需要用到事件监听和键盘监听借口和方法,以及按钮的出发,还有文件的读写和对话框等技术。
- 程序设计思路
(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].addActionListener(this);
Game.Buttons[i][j].addKeyListener(this);
this.getContentPane().add(Game.Buttons[i][j]);
Game.Buttons[i][j].setEnabled(false);
}
}
}
}
(3) 设计button的点击事件,和键盘的响应事件(实现方法代码见源程序)
(4) 通过移动button完成游戏响应检查函数弹出成功对话框显示步数和是否打破记录(实现方法代码见源程序)
(5) 点击对话框的“是”再来一次
- 关键功能说明
(1) 九宫格初始化模块:按照一定算法将0~8随机安放到9个格子中;添加控件添加事件监听。
(2) Button按钮触发事件模块:找出触发的button,找出他的四周有没有空的格子,如果有则交换,没有则不动,交换后判断此状态是否胜利,是否弹出对话框,读出历史最佳纪录,判断是否打破纪录写入文件。
(3) 键盘事件监听模块:找到空的格子,根据触发的按键,判断空格子的反方向有没有button,如果有则交换,没有则不动,交换后判断此状态是否胜利,是否弹出对话框,读出历史最佳纪录,判断是否打破纪录写入文件。
(4) 是否成功模块:依次判断格子的字符串是否分别是“1”“2”“3”“4”“5”“6”“7”“8”,是则返回true,否则返回false。
- 运行结果及分析
因为是字节流储存,所以显示是字符
- 设计经验总结
刚刚开始感觉很难,因为对图形界面太不了解了,有的函数和类都不知道,所以超级难入手,但是当看网上的代码和同学的多了之后也就知道该怎么编了,一旦入手,后面的就感觉没有那么难了,现在编完了就感觉图形界面也就那么回事,都是固定的模式,模块添加也很简单,虽然还是有很多不懂的地方但是相比于做大作业之前已经有很多的提高了,还认识了很多不认识的组件,同学们都用了不同的方法,我用的是网格布局然后添加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 } }