Java程序设计报告书

重庆邮电大学

Java程序设计报告书

题    目 ___________________________________

二   级   学  院 ____________________

      专   业  名   称 ____________________

      班            级 ____________________

      学   生  学   号 ____________________

学   生  姓   名 ____________________

指导教师(职称学位) __________________

成           绩  ____________________

二0XX   年    月

一、   课程设计目的

更好的掌握java编程以及布局和设计。特别是JAVA GUI和API的更好的应用。

二、   课程设计内容

1.课程设计简介

此课程设计是一个小游戏(五子棋)的实现,主要运用了GUI(用户图形界面)和API(应用程序借口)来实现。当然,Event侦听等也是这个程序的特色。此程序没有用到图片的引用,棋盘和棋子的设计完全是应用函数绘制,再加入复选框,按钮,标签及实现本游戏的用户界面布局。虽然本游戏没有使用一般游戏使用的Timer刷新,但却用Event侦听,加入了估价函数以及构造策略,同样完美的实现了一个五指棋人机对战游戏。总之,是一款茶余饭后,无聊打发时间,老少皆宜的简单小游戏。

2.设计说明(带功能图)

说实话,这个貌似没啥功能,真还不知道咋描述。那就说说废话:两个复选框按钮实现电脑先落棋还是人先落棋,以及按钮“开始游戏”和“重置游戏”,后面就是两个标签记录步数和“OH,MY GOD!YOU WIN!”,“OH,MY GOD!YOU LOSE!”。棋盘就是用来show。我们还是看图:

 

3.设计流程(带流程图)

Java程序设计报告书

此设计流程图大致就这样,浅显易懂,呵呵。当然,就像简介中说的这事一个事件监听触发游戏,没有Timer。但值得指出的是监听从游戏初始化完成即开始一直到推出本游戏。设计流程这里就不再赘述,相信这图简单得够直观了,对此我也相当郁闷!

4.实现功能(带实现图)

a.  首先我们先看看初始化好的游戏界面

b.  选择谁先走第一步以及黑白棋的选择。游戏这里设计的是谁先走谁就是黑棋,也就是间接的选择了白子还是黑子。另外还要一起说明的就是选择了黑白子以及谁走第一步之后,尚不能在棋盘上点棋。那么‘游戏开始’按钮点击之后就可以落棋了。如图:

Ⅰ.人先走(为了和电脑先区别,我们这里没有预先落子)

Ⅱ.电脑先走(我们可以看见点按哦已经先落子了,并且落子必是在棋盘正中心‘天元’位置)

c.  五子输赢以及便签功能的实现

           d.重置游戏。(这里就不在贴图了,因为重置之后就如a的图)

5.详细设计

下面才是此游戏的重点,我们只列举关键的几项:

开始之前,我们先看一下JAVA API这个是学习JAVA必须的。(1.6中文版)

⑴    包,继承,借口

import java.awt.*;

import javax.swing.*;

*AWTSWING既是GUI的关键组成,但现目前逐渐被SWT取代*

import java.awt.event.*;

import java.awt.Color;

publicclass FiveStone extends JPanel implements ActionListener,MouseListener,MouseMotionListener,ItemListener

*JPanel是轻量级容器,属JComponent的子类*

//ActionListener 用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册。在发生操作事件时,调用该对象的 actionPerformed 方法。

//MouseListener 用于接收组件上“感兴趣”的鼠标事件(按下、释放、单击、进入或离开)的侦听器接口。

//MouseMotionListener 用于接收组件上的鼠标移动事件的侦听器接口。

//ItemListener 接收项事件的侦听器接口。特别适于处理项事件的类实现此接口。

paintrepaint

    publicvoid paint(Graphics g)//覆盖javax.swing.JComponent.paint {

       draw_qipan(g);

    }

        publicvoid Game_re() //游戏重新开始

    {

       repaint();//重绘此组件。 如果此组件是轻量级组件,则此方法会尽快调用此组件的 paint 方法。否则此方法会尽快调用此组件的 update 方法。

       Game_start_csh();

    }

这里paint进行重写,实例化主类调用构造函数时一起调用,并且paint不能直接调用,必需要repaint来,在调用repaint的时候程序会尽快调用paint。这点非常重要!

这里只做需要的简单介绍,那重写的paint里提到画棋盘,那么我们简单说说画棋盘。

    publicvoid draw_qipan(Graphics G) //画棋盘 15*15

    {

       G.setColor(Color.lightGray);//背景色

       G.fill3DRect(10,10,500,500,true);//绘制一个用当前颜色填充的 3-D 高亮显示矩形。矩形的边是高亮显示的,以至于从左上角看呈斜面并加亮。高亮显示效果所用的颜色根据当前颜色确定。

       G.setColor(Color.black);

       for(int i=1;i<16;i++)

       {

           G.drawLine(20,20*i,300,20*i);

           G.drawLine(20*i,20,20*i,300);

       }

        G.fillOval(158,158,6,6);

        G.fillOval(77,77,6,6);

        G.fillOval(77,237,6,6);

        G.fillOval(237,77,6,6);

        G.fillOval(237,237,6,6);

    }

drawLine既是画棋盘,前一个调用函数画横线,后一个画竖线。fillOval前两个参数是在frame中的坐标,后一个是画的矩形的大小,第一个画‘天元’,后四个画‘星位’。

⑶Event监视

    publicvoid mousePressed(MouseEvent e){}//“鼠标按下”事件。鼠标按下时生效

    publicvoid mouseClicked(MouseEvent e)//"鼠标点击"事件。鼠标按下释放时生效

    {

       //Graphics g=getGraphics();

       int x1,y1;

       x1=e.getX();//返回事件相对于源组件的水平 x 坐标。

       y1=e.getY();//返回事件相对于源组件的水平 y 坐标。

       if (e.getX()<20 || e.getX()>300 || e.getY()<20 || e.getY()>300)

       {

           return;

       }

       if (x1%20>10)

       {

           x1+=20;

       }

        if(y1%20>10)

       {

           y1+=20;

       }

       x1=x1/20*20;

       y1=y1/20*20;

       set_Qizi(x1,y1);

    }

    publicvoid mouseEntered(MouseEvent e){}//鼠标进入事件

    publicvoid mouseExited(MouseEvent e){}//鼠标退出事件

    publicvoid mouseReleased(MouseEvent e){}//鼠标释放事件

    publicvoid mouseDragged(MouseEvent e){}//鼠标点中拖拉移动事件

    publicvoid mouseMoved(MouseEvent e){}//鼠标移动事件

在这些函数中,没有进行重写的都不具备实在意义,mouseClicked(MouseEvent e)在本游戏中才有实在意义。即:鼠标点击落子,鼠标点击按钮,鼠标点击复选框,鼠标点击最小化最大化以及退出。

⑷人工智能

    在这个游戏中,我们需要电脑像我们一样,堵住对方的棋和布局自己的棋,但是我们要怎样实现这样抽象的东西呢?这时候我们需要估计函数及其构造策略。简单的说就是电脑在判断下一步棋的最有价值的走法,在15*15的棋盘上的可落子点进行评估。

    我们先从五子棋步数由少到多说起:

当棋子才开始只有一两步时,这时周围的落子点的价值都差不多,所以看

publicclass AutoPlay{

     int x,y;

     void autoPlay(int chesspad[][],int a,int b){

          int randomNumber=(int)(Math.random()*8)+1;

          switch(randomNumber){

             case(1):

                  ...

             case(2):

                  ...

             case(3):

              ...

             case(4):

              ...

             case(5):

              ...

             case(6):

              ...

             case(7):

              ...

             case(8):

              ...

            }

      }

}//针对八种方案,随机一点即可。看右图

Java程序设计报告书

当针对三步及以上时,周围的落子点的价值就会出现明显的偏差,我们看,这里我们不再粘贴代码,直接到源文件就可以:

publicclass Scan{

    int shape[][][]=newint[16][16][5];//java对于未赋值的数组元素初始化赋为0,对越界数组在编译时可以通过,在解释的时候提示错误。

   void scan(int chesspad[][],int colour){//查看八方向上相邻同色棋子个数

        int i,j;

        for(i=1;i<=15;i++){

        for(j=1;j<=15;j++){

             if(chesspad[i][j]==0){

                  int m=i,n=j;

                 向上向下-------竖线

              向左向右-------横线

              左上右下-------左斜线

              左下右上-------右斜线

             }

        }

        }    

    }

}

shape[i][j][0] shape[i][j][1] shape[i][j][2] shape[i][j][3] 用于横七竖八连接棋子的数目; shape[i][j][4]用于权值的记录

看图:

  Java程序设计报告书

然后在用Sort.java给shape[i][j][0] shape[i][j][1] shape[i][j][2] shape[i][j][3]排序,最大值排前。

最后是估计函数和搜索策略:

publicclass Evaluate{

    int max_x,max_y,max;

    publicvoid evaluate(int shape[][][]){

    int i=1,j=1;

    for(i=1;i<=15;i++)

        for(j=1;j<=15;j++){

            switch(shape[i][j][0]) {

                    case 5:实现五子相连给予最高权值

                    case 4:若第一没有五子只有四子情况

                        switch(shape[i][j][1]){

                           case 4:当排序中第一与第二值等为4,给予权值

                        shape[i][j][4]=150+shape[i][j][2]+shape[i][j][3];

                           case 3:当排序中第二值为3,给予权值

                        shape[i][j][4]=100+shape[i][j][2]+shape[i][j][3];

                           default:剩下情况,连子少在其线上落子的价值就低,给予权值

                         shape[i][j][4]=50+shape[i][j][2]+shape[i][j][3];

                              }

                         break;

                    case 3:若第一只有三子的情况

                      switch(shape[i][j][1]){

                            case 3:当排序第一与第二值等为3,给予权值

                         shape[i][j][4]=75+shape[i][j][2]+shape[i][j][3];

                           default: 剩下情况,连子少在其线上落子的价值就低,给予权值

                         shape[i][j][4]=20+shape[i][j][2]+shape[i][j][3];

                           }

                           break;

                   case 2:若第一只有两子的情况给予权值

       shape[i][j][4]=10+shape[i][j][1]+shape[i][j][2]+shape[i][j][3];

                         break;

                   case 1:若只有一子给予权值

shape[i][j][4]=shape[i][j][0]+shape[i][j][1]+shape[i][j][2]+shape[i][j][3];

                   default :

                          shape[i][j][4]=0;无子则为零                     

                  }  

             }      

    int x=1,y=1;

    max=0;

    for(x=1;x<=15;x++)

        for(y=1;y<=15;y++)

            if(max

               max=shape[x][y][4]; 

               max_x=x;max_y=y;

            }    

     }

}

最后得到权值最大的落子点,下子!

6.测试结果

经过多步测试无异常情况,一款简单无聊的五子棋就OK!

三、   课程设计总结

通过这次对JAVA的学习,让我渐渐体会到了JAVA的博大精深。以及怎么学习JAVA,怎么学习计算机语言,怎样对问题进行解决和运用JAVA GUI,查找JAVA API的使用都用了更进一步的理解。虽然计算机语言是一门枯燥的语言,但是当我看到网上的网游,网页,以及应用软件时,才知道其成果是多么恢弘。这些在无形中给我动力,让我热爱上它。虽然现在学的东西少,但是慢慢积累,计算机学问会给自己一个世界!

相关推荐