宜宾学院
面向对象课程设计
学院:_计算机与信息工程学院_班级: 2014级6班
学生姓名: 郑亮学号:141106020
设计地点(单位)_________宜宾学院__________
设计题目:____________双人五子棋_____________
完成日期:2015年 12月 5日
目录
1 问题要求及任务描述 3
1.1题目要求 3
1.2 主要任务 3
2 解决问题的主要思路和方法 3
2.1 关键问题 3
2.2 拟采用解决问题的方法及算法 4
2.3主要算法和处理
流程
快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计
图以及类图等 4
3 程序实现 6
3.1 程序实现时应考虑的问题 6
3.2 主要源代码及说明 8
3.2.1 总体设计 8
3.2.1 详细设计 8
4 测试 18
4.1 游戏测试结果及分析 18
5 小结 21
5.1本问题解决方法及程序实现小结 21
5.2尚未解决的问题及下一步工作思路。 23
5.3 心得与体会 23
6 参考文献 24
双人五子棋游戏设计
报告
软件系统测试报告下载sgs报告如何下载关于路面塌陷情况报告535n,sgs报告怎么下载竣工报告下载
书
1问题要求及任务描述
1.1题目要求
双人五子棋游戏
1.2 主要任务
1.独立设计、编制、调试出一款双人五子棋游戏,并单独完成其中一定量的函数模块。
2.要求该游戏具有趣味性和可操作性,能够正常运行。其中用到Java语言中的各种语句、结构。(如其中需要注意全局变量和局部变量的申明,数组的使用等)
3.双人五子棋要求能够进入可视化界面,二人对弈,当有五颗同色棋子相连时,判断出输赢等一系列游戏流程。
2 解决问题的主要思路和方法
2.1 关键问题
1.棋盘的绘制
2.棋子的绘制,必须落在棋盘的交叉点处
3.有棋子的地方不能重复落子
4.棋子的黑白交替
5.五子连珠的判断(即游戏输赢判断)
2.2 拟采用解决问题的方法及算法
1.棋盘的绘制:可以用一层for 循环通过分别对X,Y 坐标设置相应的增量来绘制棋盘的横线和竖线。
2.绘制棋子:通过填充一个椭圆的方式来绘制棋子,
棋子的落子位子:首先定义一个二维数组a[][],用二维数组的两个参数来对应一个交叉点的X,Y虚坐标,通过鼠标点击的位置所得坐标来整除棋盘格子的宽度。这样就得到了鼠标点击的位置的最近的一个交叉的位置。然后通过交叉点的位置信息,以交叉点为圆心来绘制相应的棋子。
3.有棋子的位置不能重复落子:可以给二维数组a[][]付初值为“0”,当 a[x][y]==0 时表示无子可以落子,当a[x][y] ! = 0 时就不能落子。
4.棋子的黑白交替:可以定义一个布尔型变量Order 当为真时就为:黑子Order 为假时就为:白子。
5.五子连珠的判断:首先定义一个整形变量color 来存放棋子的颜色。先
对color进行赋值。横向的判断是定义count1 来记录棋子个数,当横向左右有相同颜色的棋子就让count1加上1,当count1 >= 5 时五子连珠成功,结束游戏。其它纵向和斜向方法相同。
2.3主要算法和处理流程图以及类图等
类视图:
算法处理流程图
3 程序实现
3.1 程序实现时应考虑的问题
1. 根据所选题目,首先设计模块图
2. 画出主程序和主要模块的流程图
3.2 主要源代码及说明
3.2.1总体设计
主要包括的类有两个个:Myframe, MyPanel
1、Myframe类:Myframe类是java版五子棋的主框架,程序的启动类。其中包括游戏界面的创建、按钮的设置、相关的事件监听器设置、游戏的启动、实现重新游戏。
2、MyPanel类:MyPanel类主要实现的是棋盘的绘制、创建数组存放棋子的坐标、设置只能在棋盘内可以落子、实现判断黑白棋的输赢。
3.2.1详细设计
1.Myframe类
变量定义:
private MyPanel; //新建一个自定义的Jpanel
public JButton btnReset; //创建新游戏按钮
public JButton btnExit; //创建退出
public JButton btnMin; //创建最小化按钮
public JButton btnBfirst; //创建黑子先按钮
public JButton btnWfirst; //创建白子先按钮
按钮的监听器和按钮功能实现:
/**
* 创建新游戏按钮
*/
btnReset = new JButton("\u65B0\u6E38\u620F");
btnReset.setFont(f1);
btnReset.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
myPanel.Reset();//调用重置棋盘的函数
myPanel.canPlay = true;//开始游戏
myPanel.repeat = true; //解决重复点击设置颜色按钮
repaint(); //调用重绘函数
}
});
btnReset.setBounds(432, 351, 142, 58);
myPanel.add(btnReset);
btnReset.setUI(new MyButtonUI());
btnReset.setBackground(new Color(250, 154, 81, 240));
/**
* 创建退出按钮
*/
btnExit = new JButton("\u9000\u51FA");
btnExit.setFont(f2);
btnExit.setBounds(506, 415, 68, 39);
myPanel.add(btnExit);
btnExit.setUI(new MyButtonUI());
btnExit.setBackground(new Color(250, 154, 81, 240));
btnExit.addMouseListener(new MouseAdapter() { //实现按钮单击退出的功能
@Override
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
});
/**
* 创建最小化按钮
*/
btnMin = new JButton("\u9690\u85CF");
btnMin.setFont(f2);
btnMin.setBounds(432, 415, 68, 39);
myPanel.add(btnMin);
btnMin.setUI(new MyButtonUI());
btnMin.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) { //实现单击按钮窗口最小化的功能
setExtendedState(JFrame.ICONIFIED);
}
});
btnMin.setBackground(new Color(250, 154, 81, 240));
/**
* 黑子优先按钮
*/
btnBfirst = new JButton("\u9ED1\u5148");
btnBfirst.setFont(f2);
btnBfirst.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
if(myPanel.repeat){
boolean b = true;
myPanel.setOrder(b); //设置落子顺序的函数,真伪黑先,假为白
myPanel.repeat = false;
}
}
});
btnBfirst.setUI(new MyButtonUI());
btnBfirst.setBackground(new Color(250, 154, 81, 240));
btnBfirst.setBounds(506, 50, 68, 39);
myPanel.add(btnBfirst);
/**
* 白子优先按钮
*/
btnWfirst = new JButton("\u767D\u5148");
btnWfirst.setFont(f2);
btnWfirst.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
if(myPanel.repeat){
boolean b = false;
myPanel.setOrder(b);//设置落子顺序的函数,真伪黑先,假为白线。
myPanel.repeat = false;
}
}
});
btnWfirst.setUI(new MyButtonUI());
btnWfirst.setBackground(new Color(250, 154, 81, 240));
btnWfirst.setBounds(432, 50, 68, 39);
myPanel.add(btnWfirst);
}
1.MyPanel类
变量定义:
private int ChessRadius = 14; //棋子半径
private int GridNum = 20 ; //棋盘格子数
private int GridWidth = 20; // 棋盘格子宽度
public int x = 0;
public int y = 0; // 棋子坐标
public int a[][] = new int[GridNum][GridNum];// 保存下过的棋子位子,“0”表示无子,“1”表示黑子,“2”表示白子
public boolean Order; // 真为黑方先,假为白方先
public boolean repeat = false; //解决重复点击设置颜色的按钮
public String s; // 显示游戏顺序
public boolean canPlay = false; //为真就开始游戏
功能实现:
public void setOrder(boolean Order) { // 设置落子顺序
this.Order = Order;
}
public void Reset() { // 重置棋盘
for (int i = 0; i < GridNum; i++) {
for (int j = 0; j < GridNum; j++) {
a[i][j] = 0;
}
}
}
public void ChessAlternating(MouseEvent e){ // 记住棋子的位子,并实现棋子的黑白交替
if (canPlay) {
/*
*关键问题中:棋子的绘制,必须落在棋盘的交叉点处的具体算法
*/
x = e.getX(); //获得鼠标点击位置
y = e.getY();
if (x >= 35 && x <= 415 && y >= 60 && y <= 440) {
x = (x - 30) / GridWidth;
y = (y - 55) / GridWidth;
if (a[x][y] == 0) {
if (Order == true) {
a[x][y] = 1;
Order = false;
s = "轮到白方";
repaint();
} else {
a[x][y] = 2;
Order = true;
s = "轮到黑方";
}
}
}
repaint();
}
}
/**
* 关键问题中:判断五子相连算法的具体实现
*/
private boolean winOrLose() {
boolean flag = false;
int color=3;
if(a[x][y]== 1 ||a[x][y]== 2 ){
color = a[x][y];
}
// 判断横向
int count1 = 1;
int i = 1;
while (x + i < GridNum && color == a[x + i][y]) {
count1++;
i++;
}
i = 1;
while (x - i >= 0 && color == a[x - i][y]) {
count1++;
i++;
}
if (count1 >= 5) {
flag = true;
}
// 判断纵向
int count2 = 1;
int i2 = 1;
while (y + i2 < GridNum && color == a[x][y + i2]) {
count2++;
i2++;
}
i2 = 1;
while (y - i2 >= 0 && color == a[x][y - i2]) {
count2++;
i2++;
}
if (count2 >= 5) {
flag = true;
}
// 判断左上,右下
int count3 = 1;
int i3 = 1;
while (x + i3 < GridNum && y + i3 < 20 && color == a[x + i3][y + i3]) {
count3++;
i3++;
}
i3 = 1;
while (x - i3 >= 0 && y - i3 >= 0 && color == a[x - i3][y - i3]) {
count3++;
i3++;
}
if (count3 >= 5) {
flag = true;
}
// 判断右上,左下
int count4 = 1;
int i4 = 1;
while (x + i4 < GridNum && y - i4 >= 0 && color == a[x + i4][y - i4]) {
count4++;
i4++;
}
i4 = 1;
while (x - i4 >= 0 && y + i4 < GridNum && color == a[x - i4][y + i4]) {
count4++;
i4++;
}
if (count4 >= 5) {
flag = true;
}
return flag;
}
/**
* 关键问题中:棋盘绘制的具体实现
*/
g2d.setColor(new Color(139, 90, 38));
g2d.setStroke(new BasicStroke(1));
for (int i = 0; i < GridNum; i++) {
g2d.drawLine(35 + GridWidth * i, 60, 35 + GridWidth * i, 440); // 竖线
g2d.drawLine(35, 60 + GridWidth * i, 415, 60 + GridWidth * i); // 横线
}
/**
* 关键问题中:棋盘绘制的具体实现
*/
g2d.setColor(Color.black); 设置画笔颜色
for (int i = 0; i < GridNum; i++) {
for (int j = 0; j < GridNum; j++) {
if (a[i][j] == 1) {// 黑子
int x = i * GridWidth + 35;
int y = j * GridWidth + 60;
g2d.fillOval(x - 7, y - 7, ChessRadius, ChessRadius);//绘出棋子
g2d.setColor(new Color(168, 13, 20));
g2d.drawString(s, 460, 155);//显示游戏顺序
g2d.setColor(Color.black);
}
if (a[i][j] == 2) { // 白子
g2d.setColor(new Color(168, 13, 20));
g2d.drawString(s, 460, 155);
g2d.setColor(Color.white);
int _x = i * GridWidth + 35;
int _y = j * GridWidth + 60;
g2d.fillOval(_x - 7, _y - 7, ChessRadius, ChessRadius);
g2d.setColor(Color.black);
}
/**
* 游戏结束显示游戏结果
*/
if (winOrLose()) {
g2d.setColor(new Color(230,0,0));
g2d.setFont(new Font("黑体", Font.BOLD, 30));
g2d.drawString((a[x][y] == 1 ? "黑方" : "白方") + "获胜", 445, 240);
g2d.setColor(Color.black);
g2d.drawString("“游戏结束”",415,290);
g2d.setFont(new Font("楷体", Font.BOLD, 25));
canPlay = false;
}
4 测试
4.1游戏测试结果及分析
1.游戏先手测试:
白子先:
黑先:
2.检验判断胜利:
游戏程序能正常运行,并且游戏功能正常。
5小结
5.1本问题解决方法及程序实现小结
在游戏界面设计之初为了考虑游戏的美观性,采用了现在比较热门的扁平化设计所以去掉了JFrame中经典的框架界面。所以在Myframe类中的构造函数publicMyframe()中的setUndecorated(true);这句代码就是去掉JFrame中的经典外边框。当然去掉界面的外边框就没有了退出和最小化的功能,为了实现这两个功能所以在游戏界面中加上了“隐藏”和“退出”这两个按钮。
去点JFrame中的经典边框,也就没有了标题栏和拖动标题栏移动界面的功能了,可以看出上面的截图中有一条白色的标题栏。
标题栏的主要实现方法如下:
/**
* 画出游戏窗口标题栏
*/
g2d.setColor(new Color(250,250,250)); //设置标题栏的颜色为白色。
g2d.setClip(0, 3, getWidth(), 30); // 设置标题栏的高度为30px。
g2d.fillRoundRect(1, 3, getWidth() - 7, getHeight() - 1, 20, 20); // 填充一个矩形作为标题栏
g2d.setClip(null);
/**
* 设置游戏标题
*/
g2d.setFont(new Font("黑体", Font.BOLD, 20));
g2d.setColor(Color.DARK_GRAY);
g2d.drawString("五子棋", 14, 25);
然后拖动标题栏实现窗口移动的功能就在Myframe类中实现的源代码如下:
myPanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (e.getY()<=30) { // 实现窗口拖动功能
setLocation(jfx+(e.getXOnScreen()-mx), jfy+(e.getYOnScreen()-my));
}
}
});
myPanel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
mx = e.getXOnScreen();
my = e.getYOnScreen();
jfx = getX();
jfy = getY();
}
});
myPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(myPanel);
myPanel.setLayout(null);
/*代码参考“极客学院教学视频java教学视频自定义API视频教程”*/
5.2尚未解决的问题及下一步工作思路。
该游戏还缺少几个关键功能:悔棋,游戏计步器,游戏时间的限制。这几个功能未能实现。这些功能只有在学完时间类的操作后才能具体实现。
游戏代码需要整理,没有完全用到面向对象程序设计思想,所以现在的代码看起很混乱。
5.3 心得与体会
虽然是C++的程序设计,因为没有具体学习C++的界面处理所以采用了java语言进行程序编写
通过这次程序设计的过程,让我渐渐体会到了编程的博大精深。以及怎么学习编程语言,怎么使用C++面向对象程序设计思想,怎样对问题进行解决和运用JAVA GUI,查找JAVA API的使用都用了更进一步的理解。
对于Java中的引用,初始化类等,开始我并不是非常的理解,知道就这么做就能实现相应的功能了,并没有很深刻的去理解它为什么要这么做。但是真正的要用Java去做一个东西不理解它是不行的,而且其间这课设涉及到了Java 中的绝大多数的
知识点
高中化学知识点免费下载体育概论知识点下载名人传知识点免费下载线性代数知识点汇总下载高中化学知识点免费下载
,如Java图形用户界面设计、Java的异常处理机制、Java输入输出流,要应用这些东西更要求我去好好理解Java的这些规则。好在有一定的C++基础Java 与C++语法类似,并把C++中一些较低级和较难以理解的功能都去掉了,如多继承、指针等,同时Java增强了部分功能。所以理解起来也比较容易。但是理解了Java的规则要把这个课设做好也不是那么容易,最难的部分是如何实现各个功能的划分和类的通讯问题。我在这方面就遇到了不少的问题。
自己的编程习惯要加以改正,不能看到题目就开始写代码,应该完整按照软件设计步:
1、概要设计,主要包括:
1)结构设计
2)接口设计
3)全局数据结构设计
4)过程设计
2、详细设计。
这样写出的程序才有可读性和可修改性。
总结这次课设,我还是收获不少。虽然界面也不是很美观,有点功能间的连接做的也不是特别的好,但是我能认识到自己的不足,并且在跟同学的交流中也学到了一些他们的设计思路,也知道今后要加强哪些方面的知识。
6 参考文献
[1] 郑莉. C++语言程序设计(第四版). 清华大学. 2010. 7
[2] 耿祥义. Java2实用教程(第4版). 清华大学. 2012. 10