注册
当前位置: 首页> 其他范文> 情书>

五子棋的开发与测试软件测试课程设计

发布时间:2021-02-21 20:10:13 浏览数:

软件测试小论文 题目:五子棋的开发与测试 班 级:
计算机科学与技术特色本班 小组成员:
完成日期:
2015 指导教师:
摘 要 五子棋游戏不仅能增强思维能力,提高记忆力,而且富含哲理,有助于修身养性。既有“场”的概念,亦有“点”的连接,是古今哲理的结晶。因此,开发出一款简单实用的单机版五子棋软件很有意义。  本论文分析了五子棋游戏的游戏规则,设计了游戏算法,并选择eclipse作为该软件的开发平台,实现了五子棋的多种对战模式,既可人与人对战,也可人与电脑对战。还实现了,自定义棋盘行列数。

本文将从开发环境的安装,到五子棋的功能分析与设计,到各功能模块的实现,逐步向您展现五子棋的实现过程。经测试,本游戏系统功能齐全,能平稳运行,具有较强的使用价值。  关键词:五子棋;
思考算法;
多人对战;
人机对战;

目 录 1.引言 1 1.1编写目的 1 1.2背景 1 2.单机版五子棋系统介绍 2 2.1平台简介 2 2.2游戏概述 2 3.基于Java的五子棋游戏的设计 3 3.1游戏模块 3 3.1.1 开局、退出、棋盘 3 3.1.2 模式栏 4 3.2游戏流程图 4 4.软件测试 5 4.1测试的目的 5 4.2测试的方法 5 4.3白盒测试 6 4.3.1测试用例 7 4.4黑盒测试 10 4.5测试游戏存在的问题 12 4.6游戏不足的解决方案 12 4.6.1游戏改进后的代码 12 4.7回归测试 13 5.总结 15 参考文献 16 附录 17 1.引言 1.1编写目的 根据测试计划报告,对软件进行测试,详细记录测试过程,以对软件的质量进行评价,为软件设计人员提供BUG依据,故做产生测试分析报告。

1.2背景 为了使游戏更加完善,使玩家有更好的游戏体验,针对游戏出现的一些问题,做出修复,使游戏更加生动,符合玩家的游戏习惯。

2.单机版五子棋系统介绍 2.1平台简介 Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

2.2游戏概述 该游戏软件采用 Java 语言设计,在 Windows 系统为玩家提供五子棋游戏人 机对战的基本功能。玩家可以通过鼠标在棋盘的相应位置下子,一方为白色,另 一方为黑色,先下的为黑子(主场)。游戏过程中,只要有一人先连成五个棋子, 不论横、竖或斜,就会在屏幕上显示是谁赢了比赛,也可以是平局收场,从而可 以进行下一场比赛。在比赛过程中,如果一方需要悔棋,先得通过对手的同意才可以。

3.基于Java的五子棋游戏的设计 本项目中五子棋主要包含两大主要模块,如下图3.1(a)所示。第一个模块为主要模块,用于实现五子棋的游戏功能。第二个模块为辅助模块,用于实现五子棋的相关辅助设置。游戏主界面如图3.1(b)。

五子棋游戏 视图帮助块 游戏模块 图3.1(a) 主要模块 图3.1(b)游戏主界面 3.1游戏模块 该模块实现游戏的主要功能,共包含两个小模块,如下图3.2(a)所示。第一个模块为棋盘栏,实现游戏玩家点击下棋的功能。第二个小模块为模式栏,对下棋的方式进行选择。游戏菜单如图3.2(b)所示。

游戏模块 模式栏 开局、退出、棋盘栏 图3.2(a) 游戏模块 图3.2(b) 游戏菜单 3.1.1 开局、退出、棋盘 实现可视化的开局与退出功能,以及棋盘选择对战模式。

图3.3 开局、退出、棋盘 3.1.2 模式栏 模式栏,主要实现游戏过程中的各种控制功能,包括人人、人机实例化对战模式。

图3.4 模式选择 是 电脑下子 电脑是否下子 是 电脑下子 电脑是否下子 否 游戏结束 是 白子或黑子是否有5个连成一线 否 游戏者是否下子 否 游戏者下子 模式选择 开局 3.2游戏流程图 4.软件测试 4.1测试的目的 软件测试是为了发现错误而执行程序的过程。或者说,软件测试是根据软件开发各阶段的规格说明和程序的内部结构而精心设计一批测试用例{即输入数据及其预期的输出结果},并利用这些测试用例去运行程序,以发现程序错误的过程。设计测试的目标是想以最少的时间和人力,系统地找出软件中潜在的各种错误和缺陷。如果成功地实施了测试,就能够发现软件中的错误。测试的附带收获是,它能够证明软件的功能和性能与需求说明相符合。此外,实施测试收集到的测试结果数据为可靠性分析提供了依据。而测试的目的就是在软件投入生产性运行之前,尽可能地发现软件中的错误。

4.2测试的方法 常见的软件测试阶段的工作主要分为单元测试、集成测试、确认测试和系统测试四个步骤,测试方法有黑盒测试和白盒测试两种方法:黑盒测试(已经知道产品应该具有的功能,可以通过测试来检验是否每个功能都正常);
白盒测试(如果知道产品内部工作过程,可以通过测试来检验内部动作是否按照说明书的规定正常进行)。

本游戏测试的主要方法包括黑盒测试和白盒测试,由小组人员通过自己亲自去玩,然后观察游戏在运行过程中,所需要实现的功能有没有实现,以及在测试过程中有没有发现新的问题记录在案。然后根据测试后所产生的一系列的问题,有本组负责编码人员对游戏进行改进,然后在进行测试,就这样重复的进行这样的工作,直到游戏的运行与预想时的状况基本一致时,才算通过测试。

图4.1 完整游戏图 4.3白盒测试 通过程序的源代码进行测试而不使用用户界面。这种类型的测试需要从代码句法发现内部代码在算法,溢出,路径,条件等等中的缺点或者错误,进而加以修正,这一方法是把测试对象看作一个打开的盒子,测试人员依据程序内部逻辑结构相关信息,设计或选择测试用例,对程序所有逻辑路径进行测试,通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。用软件白盒测试产生的测试用例能够:
1.保证一个模块中的所有独立路径至少被使用一次; 2.对所有逻辑值均需测试true和false; 3.在上下边界及可操作范围内运行所有循环; 4.检查内部数据结构以确保其有效性。

4.3.1测试用例 (1)用例1:
因为类ChessFrame主要功能是创建五子棋游戏主窗体,所以对其进行测试,看其构造五子棋游戏的主窗体的方法是否正确。

class ChessFrame extends JFrame implements ActionListener { private String[] strsize={“20x15“,“30x20“,“40x30“}; private String[] strmode={“人机对弈“,“人人对弈“}; public static boolean iscomputer=true,checkcomputer=true; private int width,height; private ChessModel cm; private MainPanel mp; public ChessFrame() { this.setTitle(“五子棋游戏“); cm=new ChessModel(1); mp=new MainPanel(cm); Container con=this.getContentPane(); con.add(mp,“Center“); this.setResizable(false); this.addWindowListener(new ChessWindowEvent()); MapSize(20,15); JMenuBar mbar = new JMenuBar(); this.setJMenuBar(mbar); JMenu gameMenu = new JMenu(“游戏“); mbar.add(makeMenu(gameMenu, new Object[] { “开局“, “棋盘“,“模式“, null, “退出“ }, this)); JMenu lookMenu =new JMenu(“视图“); mbar.add(makeMenu(lookMenu,new Object[] { “Metal“,“Motif“,“Windows“ },this)); JMenu helpMenu = new JMenu(“帮助“); mbar.add(makeMenu(helpMenu, new Object[] { “关于“ }, this)); } (2)用例2:
用play(int x,int y)方法实现电脑下子,并先通过方法readyplay(int x,int y)判断某坐标位置是否可下棋子。

public void readyplay(int x,int y){ if(badxy(x,y)) return; if (chessExist(x,y)) return; this.arrMapShow[x][y]=3; } public void play(int x,int y){ if(badxy(x,y)) return; if(chessExist(x,y)){ this.isExist=true; return; }else this.isExist=false; if(getisOdd()){ setisOdd(false); this.arrMapShow[x][y]=1; }else{ setisOdd(true); this.arrMapShow[x][y]=2; } } (3)用例3:
计算机走棋方法(computerDo)测试 通过方法 computerDo实现电脑下子的思想 public void computerDo(int width,int height){ int max_black,max_white,max_temp,max=0; setisOdd(true); System.out.println(“计算机走棋 ...“); for(int i = 0; i <= width; i++){ for(int j = 0; j <= height; j++){ if(!chessExist(i,j)){ max_white=checkMax(i,j,2); max_black=checkMax(i,j,1); max_temp=Math.max(max_white,max_black); if(max_temp>max){ max=max_temp; this.x=i; this.y=j; }}}} (4)用例4:
根据提供的棋子信息(颜色、坐标)画棋子方法( draw)的测试 public void draw(Graphics g, int i, int j, int v){ int x = 20 * i+20; int y = 20 * j+20; //画棋盘 if(i!=width && j!=height){ g.setColor(Color.white); g.drawRect(x,y,20,20); } //画黑色棋子 if(v == 1 ){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.black); g.fillOval(x-8,y-8,16,16); } //画白色棋子 if(v == 2 ){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.white); g.fillOval(x-8,y-8,16,16); } if(v ==3){ g.setColor(Color.cyan); g.drawOval(x-8,y-8,16,16); } } (5)用例5:
响应鼠标的点击事件,构造方法(mousePressed)实现鼠标的点击来实现下棋的动作。

public void mousePressed(MouseEvent evt){ int x = (evt.getX()-10) / 20; int y = (evt.getY()-10) / 20; System.out.println(x+“ “+y); if (evt.getModifiers()==MouseEvent.BUTTON1_MASK){ cm.play(x,y); System.out.println(cm.getisOdd()+“ “+cm.getarrMapShow()[x][y]); repaint(); if(cm.judgeSuccess(x,y,cm.getisOdd())){ cm.showSuccess(this); evt.consume(); ChessFrame.iscomputer=false; } (6)用例6:
构造方法judgeSuccess(int x,int y,boolean isodd)对当前棋子各个位置的判断来得出是否胜负。

public boolean judgeSuccess(int x,int y,boolean isodd){ int num=1; int arrvalue; int x_temp=x,y_temp=y; if(isodd) arrvalue=2; else arrvalue=1; int x_temp1=x_temp,y_temp1=y_temp; 4.4黑盒测试 软件黑盒测试也是软件测试的主要方法之一,也可以称为功能测试、数据驱动测试或基于规格说明的测试。测试者不了解程序的内部情况,只知道程序的输入、输出和系统的功能,这是从用户的角度针对软件界面、功能及外部结构进行测试,而不考虑程序内部逻辑结构。

软件黑盒测试法注重于测试软件的功能需求,主要试图发现下列几类错误:
1)功能不正确或遗漏;

2)界面错误;

3)数据库访问错误;

4)性能错误;

5)初始化和终止错误等。

测试方法可以分为以下几种:等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法等。

从理论上讲,软件黑盒测试只有采用穷举输入测试,把所有可能的输入都作为测试情况考虑,才能查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但可能的输入进行测试。这样看来,完全测试是不可能的,所以我们要进行有针对性的测试,通过制定测试案例指导测试的实施,保证软件测试有组织、按步骤,以及有计划地进行。软件黑盒测试行为必须能够加以量化,才能真正保证软件质量,而测试用例就是将测试行为具体量化的方法之一。

五子棋游戏测试用例如下表所示:
用例 操作 预期结果 实际结果 用例1 能否在不同版本的eclipese中运行该游戏 游戏能够在设计该游戏 版本及以上中正常运行 Pass 用例2 运行时能否正常显示主 界面 运行时能正常显示主 界面 Pass 用例3 鼠标单击菜单—开始,是否可以运行游戏 可以运行游戏 Pass 用例4 鼠标单击棋盘,是否会有棋子落于该位置 棋子落于鼠标单击位置 Pass 用例5 当人下子出现“活三”、“冲四”,电脑是否会下子堵截 电脑会下子阻挡 Pass 用例6 多次游戏测试:在人(黑棋)没有出现“活三”、“冲四”的情况下,电脑(白棋)落子是否存在规律 黑棋没有出现“活三”、 “冲四”的情况下,电脑 (白棋)随机落子,不存 在规律 Pass 用例7 进行对战时,按照规则下棋能否正常输赢 可以正常输赢 Pass 用例8 判断在横线上5子能否获得胜利 可以 Pass 用例9 判断在竖线上5子能否获得胜利 可以 Pass 用例10 判断在斜线上5子能否获得胜利 可以 Pass 4.5测试游戏存在的问题 1.通过小组以外人员的游戏测试发现,由于棋盘大小问题,使得可能导致有时棋子满格也没有分出胜负,这样,就很难显示博弈者的水平。

2.小组以外人员的游戏测试后建议认为,我们所设计的五子棋游戏只能实现人机博弈,不能实现人与人之间的博弈,这样很难让更多的人一展他们的高超棋艺。

4.6游戏不足的解决方案 1.通过对后台代码的修改实现对游戏棋盘大小的规格控制选择,新添规格30*20格和40*30格模式,让博弈者尽展各自高超棋艺。

2.在人机对战的基础上新增人人对战模式,以方便人与人之间棋艺博弈的乐趣让更多的爱好五子棋的玩家参与进来。

4.6.1游戏改进 1. 在菜单中新加棋盘选项,再在模式中新增规格30*20格和40*30格模式 实现代码如下:
public ChessModel(int modeChess){ this.isOdd=true; if(modeChess == 1){ PanelInit(20, 15, modeChess); } if(modeChess == 2){ PanelInit(30, 20, modeChess); } if(modeChess == 3){ PanelInit(40, 30, modeChess);}} private void PanelInit(int width, int height, int modeChess){ this.width = width; this.height = height; this.modeChess = modeChess; arrMapShow = new int[width+1][height+1]; for(int i = 0; i <= width; i++){ for(int j = 0; j <= height; j++){ arrMapShow[i][j] = -5; } } } 2在菜单中新加模式选项,新增人人对战模式 if(arg.equals(“人人对弈“)){ this.checkcomputer=false; this.iscomputer=false; cm=new ChessModel(cm.getModeChess()); MapSize(cm.getWidth(),cm.getHeight()); SwingUtilities.updateComponentTreeUI(this); } 4.7回归测试 对修改后的游戏版本执行回归测试 用例 操作 预期结果 测试结果 用例1 选择不同规格棋盘,能否正常运行 能正常运行 Pass 用例2 选择人人对战,能否正常运行 能正常运行 Pass 用例3 选择不同规格棋盘,对其他功能正常运行是否产生影响 没有影响 Pass 用例4 选择人人对战模式,对其他功能正常运行是否产生影响 没有影响 Pass 5.总结 在测试阶段,一系列的测试方案都是为了“破坏”已经建造好的软件系统而特地设计的,它的存在是为了竭力证明程序中的错误不能按照预定要求正确工作。软件测试从不同的角度出发会派生出两种不同的测试原则,从用户的角度出发,就是希望通过软件测试能充分暴露软件中存在的问题和缺陷,从而考虑是否可以接受该产品,从开发者的角度出发,就是希望测试能表明软件产品不存在错误,已经正确地实现了用户的需求,确立人们对软件质量的信心。  通过此次软件测试的课程设计,深刻学习掌握了软件测试和软件测试过程的基本方法和基本技术,关于黑盒、白盒的测试用例的设计,也进行了认真学习研究,从而进一步提高了自己在程序上的编写能力,以及一些之前未触及的问题。

总之,收获颇丰,增强了自己动手以及团队合作的能力。付出才会有回报,实践才能出真知。为即将踏上社会的自己又做了一份理论和实践的准备。

参考文献 [1] 谢希仁.  计算机网络(第五版)[M]. 北京:电子工业出版社,2008年2月  [2] 胡小强   计算机网络[M] 北京:北京邮电大学出版社2005年1月  [3] 刘群策  LoadRunner和软件项目性能测试 [M] 机械工业出版社 2008年  [4] 朱少民 软件测试方法和技术 [M] 清华大学出版社  2005年  [5] 郑人杰  软件测试 [M] 人民邮电出版社 2013年  附录 //Java编程:五子棋游戏源代码 import java.awt.*; import java.awt.event.*; import java.applet.*; import javax.swing.*; import java.io.PrintStream; import javax.swing.JComponent; import javax.swing.JPanel; /* *main方法创建了ChessFrame类的一个实例对象(cf), *并启动屏幕显示显示该实例对象。

**/ public class FiveChessAppletDemo { public static void main(String args[]){ ChessFrame cf = new ChessFrame(); cf.show(); } } /* *类ChessFrame主要功能是创建五子棋游戏主窗体和菜单 **/ class ChessFrame extends JFrame implements ActionListener { private String[] strsize={“20x15“,“30x20“,“40x30“}; private String[] strmode={“人机对弈“,“人人对弈“}; public static boolean iscomputer=true,checkcomputer=true; private int width,height; private ChessModel cm; private MainPanel mp; //构造五子棋游戏的主窗体 public ChessFrame() { this.setTitle(“五子棋游戏“); cm=new ChessModel(1); mp=new MainPanel(cm); Container con=this.getContentPane(); con.add(mp,“Center“); this.setResizable(false); this.addWindowListener(new ChessWindowEvent()); MapSize(20,15); JMenuBar mbar = new JMenuBar(); this.setJMenuBar(mbar); JMenu gameMenu = new JMenu(“游戏“); mbar.add(makeMenu(gameMenu, new Object[] { “开局“, “棋盘“,“模式“, null, “退出“ }, this)); JMenu lookMenu =new JMenu(“视图“); mbar.add(makeMenu(lookMenu,new Object[] { “Metal“,“Motif“,“Windows“ },this)); JMenu helpMenu = new JMenu(“帮助“); mbar.add(makeMenu(helpMenu, new Object[] { “关于“ }, this)); } //构造五子棋游戏的主菜单 public JMenu makeMenu(Object parent, Object items[], Object target){ JMenu m = null; if(parent instanceof JMenu) m = (JMenu)parent; else if(parent instanceof String) m = new JMenu((String)parent); else return null; for(int i = 0; i < items.length; i++) if(items[i] == null) m.addSeparator(); else if(items[i] == “棋盘“){ JMenu jm = new JMenu(“棋盘“); ButtonGroup group=new ButtonGroup(); JRadioButtonMenuItem rmenu; for (int j=0;j<strsize.length;j++){ rmenu=makeRadioButtonMenuItem(strsize[j],target); if (j==0) rmenu.setSelected(true); jm.add(rmenu); group.add(rmenu); } m.add(jm); }else if(items[i] == “模式“){ JMenu jm = new JMenu(“模式“); ButtonGroup group=new ButtonGroup(); JRadioButtonMenuItem rmenu; for (int h=0;h<strmode.length;h++){ rmenu=makeRadioButtonMenuItem(strmode[h],target); if(h==0) rmenu.setSelected(true); jm.add(rmenu); group.add(rmenu); } m.add(jm); }else m.add(makeMenuItem(items[i], target)); return m; } //构造五子棋游戏的菜单项 public JMenuItem makeMenuItem(Object item, Object target){ JMenuItem r = null; if(item instanceof String) r = new JMenuItem((String)item); else if(item instanceof JMenuItem) r = (JMenuItem)item; else return null; if(target instanceof ActionListener) r.addActionListener((ActionListener)target); return r; } //构造五子棋游戏的单选按钮式菜单项 public JRadioButtonMenuItem makeRadioButtonMenuItem( Object item, Object target){ JRadioButtonMenuItem r = null; if(item instanceof String) r = new JRadioButtonMenuItem((String)item); else if(item instanceof JRadioButtonMenuItem) r = (JRadioButtonMenuItem)item; else return null; if(target instanceof ActionListener) r.addActionListener((ActionListener)target); return r; } public void MapSize(int w,int h){ setSize(w * 20+50 , h * 20+100 ); if(this.checkcomputer) this.iscomputer=true; else this.iscomputer=false; mp.setModel(cm); mp.repaint(); } public boolean getiscomputer(){ return this.iscomputer; } public void restart(){ int modeChess = cm.getModeChess(); if(modeChess <= 3 && modeChess >= 1){ cm = new ChessModel(modeChess); MapSize(cm.getWidth(),cm.getHeight()); }else{ System.out.println(“\u81EA\u5B9A\u4E49“); } } public void actionPerformed(ActionEvent e){ String arg=e.getActionCommand(); try{ if (arg.equals(“Windows“)) UIManager.setLookAndFeel( “com.sun.java.swing.plaf.windows.WindowsLookAndFeel“); else if(arg.equals(“Motif“)) UIManager.setLookAndFeel( “com.sun.java.swing.plaf.motif.MotifLookAndFeel“); else UIManager.setLookAndFeel( “javax.swing.plaf.metal.MetalLookAndFeel“ ); SwingUtilities.updateComponentTreeUI(this); }catch(Exception ee){} if(arg.equals(“20x15“)){ this.width=20; this.height=15; cm=new ChessModel(1); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals(“30x20“)){ this.width=30; this.height=20; cm=new ChessModel(2); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals(“40x30“)){ this.width=40; this.height=30; cm=new ChessModel(3); MapSize(this.width,this.height); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals(“人机对弈“)){ this.checkcomputer=true; this.iscomputer=true; cm=new ChessModel(cm.getModeChess()); MapSize(cm.getWidth(),cm.getHeight()); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals(“人人对弈“)){ this.checkcomputer=false; this.iscomputer=false; cm=new ChessModel(cm.getModeChess()); MapSize(cm.getWidth(),cm.getHeight()); SwingUtilities.updateComponentTreeUI(this); } if(arg.equals(“开局“)){ restart(); } if(arg.equals(“关于“)) JOptionPane.showMessageDialog(this, “五子棋游戏测试版本“, “关于“, 0); if(arg.equals(“退出“)) System.exit(0); } } /* *类ChessModel实现了整个五子棋程序算法的核心 */ class ChessModel { //棋盘的宽度、高度、棋盘的模式(如20×15) private int width,height,modeChess; //棋盘方格的横向、纵向坐标 private int x=0,y=0; //棋盘方格的横向、纵向坐标所对应的棋子颜色, //数组arrMapShow只有3个值:1,2,3,-5, //其中1代表该棋盘方格上下的棋子为黑子, //2代表该棋盘方格上下的棋子为白子, //3代表为该棋盘方格上没有棋子, //-5代表该棋盘方格不能够下棋子 private int[][] arrMapShow; //交换棋手的标识,棋盘方格上是否有棋子的标识符 private boolean isOdd,isExist; public ChessModel() {} //该构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘 public ChessModel(int modeChess){ this.isOdd=true; if(modeChess == 1){ PanelInit(20, 15, modeChess); } if(modeChess == 2){ PanelInit(30, 20, modeChess); } if(modeChess == 3){ PanelInit(40, 30, modeChess); } } //按照棋盘模式构建棋盘大小 private void PanelInit(int width, int height, int modeChess){ this.width = width; this.height = height; this.modeChess = modeChess; arrMapShow = new int[width+1][height+1]; for(int i = 0; i <= width; i++){ for(int j = 0; j <= height; j++){ arrMapShow[i][j] = -5; } } } //获取是否交换棋手的标识符 public boolean getisOdd(){ return this.isOdd;} //设置交换棋手的标识符 public void setisOdd(boolean isodd){ if(isodd) this.isOdd=true; else this.isOdd=false; } //获取某棋盘方格是否有棋子的标识值 public boolean getisExist(){ return this.isExist; } //获取棋盘宽度 public int getWidth(){ return this.width; } //获取棋盘高度 public int getHeight(){ return this.height; } //获取棋盘模式 public int getModeChess(){ return this.modeChess; } //获取棋盘方格上棋子的信息 public int[][] getarrMapShow(){ return arrMapShow; } //判断下子的横向、纵向坐标是否越界 private boolean badxy(int x, int y){ if(x >= width+20 || x < 0) return true; return y >= height+20 || y < 0; } //计算棋盘上某一方格上八个方向棋子的最大值, //这八个方向分别是:左、右、上、下、左上、左下、右上、右下 public boolean chessExist(int i,int j){ if(this.arrMapShow[i][j]==1 || this.arrMapShow[i][j]==2) return true; return false; } //判断该坐标位置是否可下棋子 public void readyplay(int x,int y){ if(badxy(x,y)) return; if (chessExist(x,y)) return; this.arrMapShow[x][y]=3; } //在该坐标位置下棋子 public void play(int x,int y){ if(badxy(x,y)) return; if(chessExist(x,y)){ this.isExist=true; return; }else this.isExist=false; if(getisOdd()){ setisOdd(false); this.arrMapShow[x][y]=1; }else{ setisOdd(true); this.arrMapShow[x][y]=2; } } //计算机走棋 /* *说明:用穷举法判断每一个坐标点的四个方向的的最大棋子数, *最后得出棋子数最大值的坐标,下子 **/ public void computerDo(int width,int height){ int max_black,max_white,max_temp,max=0; setisOdd(true); System.out.println(“计算机走棋 ...“); for(int i = 0; i <= width; i++){ for(int j = 0; j <= height; j++){ if(!chessExist(i,j)){//算法判断是否下子 max_white=checkMax(i,j,2);//判断白子的最大值 max_black=checkMax(i,j,1);//判断黑子的最大值 max_temp=Math.max(max_white,max_black); if(max_temp>max){ max=max_temp; this.x=i; this.y=j; } } } } setX(this.x); setY(this.y); this.arrMapShow[this.x][this.y]=2; } //记录电脑下子后的横向坐标 public void setX(int x){ this.x=x; } //记录电脑下子后的纵向坐标 public void setY(int y){ this.y=y; } //获取电脑下子的横向坐标 public int getX(){ return this.x; } //获取电脑下子的纵向坐标 public int getY(){ return this.y; } //计算棋盘上某一方格上八个方向棋子的最大值, //这八个方向分别是:左、右、上、下、左上、左下、右上、右下 public int checkMax(int x, int y,int black_or_white){ int num=0,max_num,max_temp=0; int x_temp=x,y_temp=y; int x_temp1=x_temp,y_temp1=y_temp; //judge right for(int i=1;i<5;i++){ x_temp1+=1; if(x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judge left x_temp1=x_temp; for(int i=1;i<5;i++){ x_temp1-=1; if(x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num<5) max_temp=num; //judge up x_temp1=x_temp; y_temp1=y_temp; num=0; for(int i=1;i<5;i++){ y_temp1-=1; if(y_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judge down y_temp1=y_temp; for(int i=1;i<5;i++){ y_temp1+=1; if(y_temp1>this.height) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num; //judge left_up x_temp1=x_temp; y_temp1=y_temp; num=0; for(int i=1;i<5;i++){ x_temp1-=1; y_temp1-=1; if(y_temp1<0 || x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judge right_down x_temp1=x_temp; y_temp1=y_temp; for(int i=1;i<5;i++){ x_temp1+=1; y_temp1+=1; if(y_temp1>this.height || x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num; //judge right_up x_temp1=x_temp; y_temp1=y_temp; num=0; for(int i=1;i<5;i++){ x_temp1+=1; y_temp1-=1; if(y_temp1<0 || x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } //judge left_down x_temp1=x_temp; y_temp1=y_temp; for(int i=1;i<5;i++){ x_temp1-=1; y_temp1+=1; if(y_temp1>this.height || x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==black_or_white) num++; else break; } if(num>max_temp&&num<5) max_temp=num; max_num=max_temp; return max_num; } //判断胜负 public boolean judgeSuccess(int x,int y,boolean isodd){ int num=1; int arrvalue; int x_temp=x,y_temp=y; if(isodd) arrvalue=2; else arrvalue=1; int x_temp1=x_temp,y_temp1=y_temp; //判断右边 for(int i=1;i<6;i++){ x_temp1+=1; if(x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断左边 x_temp1=x_temp; for(int i=1;i<6;i++){ x_temp1-=1; if(x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) return true; //判断上方 x_temp1=x_temp; y_temp1=y_temp; num=1; for(int i=1;i<6;i++){ y_temp1-=1; if(y_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断下方 y_temp1=y_temp; for(int i=1;i<6;i++){ y_temp1+=1; if(y_temp1>this.height) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) return true; //判断左上 x_temp1=x_temp; y_temp1=y_temp; num=1; for(int i=1;i<6;i++){ x_temp1-=1; y_temp1-=1; if(y_temp1<0 || x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断右下 x_temp1=x_temp; y_temp1=y_temp; for(int i=1;i<6;i++){ x_temp1+=1; y_temp1+=1; if(y_temp1>this.height || x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) return true; //判断右上 x_temp1=x_temp; y_temp1=y_temp; num=1; for(int i=1;i<6;i++){ x_temp1+=1; y_temp1-=1; if(y_temp1<0 || x_temp1>this.width) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } //判断左下 x_temp1=x_temp; y_temp1=y_temp; for(int i=1;i<6;i++){ x_temp1-=1; y_temp1+=1; if(y_temp1>this.height || x_temp1<0) break; if(this.arrMapShow[x_temp1][y_temp1]==arrvalue) num++; else break; } if(num==5) return true; return false; } //赢棋后的提示 public void showSuccess(JPanel jp){ JOptionPane.showMessageDialog(jp,“你赢了,好厉害!“,“win“, JOptionPane.INFORMATION_MESSAGE); } //输棋后的提示 public void showDefeat(JPanel jp){ JOptionPane.showMessageDialog(jp,“你输了,请重新开始!“,“lost“, JOptionPane.INFORMATION_MESSAGE); } } /* *类MainPanel主要完成如下功能:
*1、构建一个面板,在该面板上画上棋盘;

*2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等) **/ class MainPanel extends JPanel implements MouseListener,MouseMotionListener{ private int width,height;//棋盘的宽度和高度 private ChessModel cm; //根据棋盘模式设定面板的大小 MainPanel(ChessModel mm){ cm=mm; width=cm.getWidth(); height=cm.getHeight(); addMouseListener(this); } //根据棋盘模式设定棋盘的宽度和高度 public void setModel(ChessModel mm){ cm = mm; width = cm.getWidth(); height = cm.getHeight(); } //根据坐标计算出棋盘方格棋子的信息(如白子还是黑子), //然后调用draw方法在棋盘上画出相应的棋子 public void paintComponent(Graphics g){ super.paintComponent(g); for(int j = 0; j <= height; j++){ for(int i = 0; i <= width; i++){ int v = cm.getarrMapShow()[i][j]; draw(g, i, j, v); } } } //根据提供的棋子信息(颜色、坐标)画棋子 public void draw(Graphics g, int i, int j, int v){ int x = 20 * i+20; int y = 20 * j+20; //画棋盘 if(i!=width && j!=height){ g.setColor(Color.white); g.drawRect(x,y,20,20); } //画黑色棋子 if(v == 1 ){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.black); g.fillOval(x-8,y-8,16,16); } //画白色棋子 if(v == 2 ){ g.setColor(Color.gray); g.drawOval(x-8,y-8,16,16); g.setColor(Color.white); g.fillOval(x-8,y-8,16,16); } if(v ==3){ g.setColor(Color.cyan); g.drawOval(x-8,y-8,16,16); } } //响应鼠标的点击事件,根据鼠标的点击来下棋, //根据下棋判断胜负等 public void mousePressed(MouseEvent evt){ int x = (evt.getX()-10) / 20; int y = (evt.getY()-10) / 20; System.out.println(x+“ “+y); if (evt.getModifiers()==MouseEvent.BUTTON1_MASK){ cm.play(x,y); System.out.println(cm.getisOdd()+“ “+cm.getarrMapShow()[x][y]); repaint(); if(cm.judgeSuccess(x,y,cm.getisOdd())){ cm.showSuccess(this); evt.consume(); ChessFrame.iscomputer=false; } //判断是否为人机对弈 if(ChessFrame.iscomputer&&!cm.getisExist()){ cm.computerDo(cm.getWidth(),cm.getHeight()); repaint(); if(cm.judgeSuccess(cm.getX(),cm.getY(),cm.getisOdd())){ cm.showDefeat(this); evt.consume(); } } } } public void mouseClicked(MouseEvent evt){} public void mouseReleased(MouseEvent evt){} public void mouseEntered(MouseEvent mouseevt){} public void mouseExited(MouseEvent mouseevent){} public void mouseDragged(MouseEvent evt){} //响应鼠标的拖动事件 public void mouseMoved(MouseEvent moveevt){ int x = (moveevt.getX()-10) / 20; int y = (moveevt.getY()-10) / 20; cm.readyplay(x,y); repaint(); } } class ChessWindowEvent extends WindowAdapter{ public void windowClosing(WindowEvent e){ System.exit(0); } ChessWindowEvent() { } }

上一篇:XX县关于贯彻落实全市打好农业农村污染治理攻坚战作战方案(2018-2020年)实施方案

上一篇:在换届纪律工作谈话会上的讲话

相关范文