一、实验目的
(1) 使用Java编写五子棋程序
(2) 掌握编写过程的一些类和类成员的使用,并且了解五子棋制作过程的一些步骤和了解一些算法。
二、实验环境
在电子楼2楼,装有My Eclipse 的计算机上进行
三、实验内容
编写一个五子棋程序。
程序主要实现以下功能:
1.实现五子棋界面,要求人性化界面简洁美观;
2.实现黑白色轮流下棋功能,能提示下棋方;
3.实现连成五子自动判断功能;
4.实现时间设置功能,认输功能;
核心代码如下:
1.我的第一步是设计界面。在这个过程的要使用到以下的步骤:
1.使用MyEclipse 创建一个Project关于这个工程,加入两个类,分别是ChessFrame和Chess,而ChessFrame是这个工程中最重要的一个部分。创建过程中要继承JFrame类,并且要继承Runnable 和 MouseListener 这两个接口,分别是用来监听鼠标的移动和时间的变化。
2.在给这个JFrame设置大小和颜色等一些东西。
这里最主要的是使用了两个函数,是以前没见过的:
1.这个是用来设置默认的窗口关闭事件的
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
2.这两个是用来获得屏幕的大小的
Toolkit.getDefaultToolkit().getScreenSize().height; Toolkit.getDefaultToolkit().getScreenSize().width;
3.把本地的背景图片加到这个窗口中,作为这个窗口的背景图:
使用的到的类有BufferedImage和 ImageIO这两个类,这两个类是专门用来处理这种功能的。主要的代码如下:
BufferedImage bg = null;
bg = ImageIO.read(new File("e:/background.jpg"));
g.drawImage(bg,0,0,this);
这样这个图片就加到了这个窗口的背景去了。
这里有一个改进就是双缓冲技术,可以防止闪屏。这个技术就是在界面和内存都有一幅图,我们的改动不是直接画界面,而是内存中先画好然后把内存中直接显示出来,那样就没有了一前一后的,那就没有了闪屏的事情发生了。
4.就是画棋盘和写一些游戏信息:
这步比较简单,也没什么可以说的,用到的一些画线的函数,和写String的一些函数。
以上做完以后就可以出现以下的界面:
1.我的第二步就是增加对mouse的点击和移动的处理,这样以后就可以用来下棋。在这个过程的要使用到以下的步骤:
1.增加对mouse的监视,然后重写它的一些函数:
1.我们在ChessFrame的构造函数中加入了addMouseListener()函数,然后重写关于这个的四个函数,我们这这里不重写所有的函数,就改写一个MousePress函数就可以了。改写的代码如下:
publicvoid mousePress(MouseEvent arg0) {
this.x = arg0.getX();
this.y = arg0.getY();
if (this.canplay)
this.repaint();
}
现在要处理的就是加上棋子了,我在这个做了一下小改动可以更加准确的定位下棋的位置:
if (x >= 10 && x <= 374 && y >= 72 && y <= 450) {
int sx1 = (this.x - 10) / 20;
int sy2 = (this.y - 72) / 20;
int yx1 = (this.x - 10) % 20;
int yy2 = (this.y - 72) % 20;
if (yx1 >= 10) {
sx1++;
}
if (yy2 >= 10) {
sy2++;
}
就是这个,我们通过监控鼠标的就可以得到点击的X,Y坐标,我在这里通过对它求余,假如余数大于10(就是一个格子的一半)那就给+1,不然不变。后面的画棋子是很简单的一个过程,使用的是现成的函数(drawoval)
2.这部要做的就是记录棋子和五子连的判断:
1.我们通过一个数组int给保存棋子,如果是0就是没子,1表示是黑子,2表示白子。在每次重绘的时候遍历这个数组显示,这样就可以保存棋子了。
2.判断五子连起来然后获胜的算法:
这个算法是鉴戒例子上的:
privateboolean isline(int x, int y, int xchange, int ychange, int color) {
int tempx = xchange;
int tempy = ychange;
int count = 1;
while (x + xchange >= 0 && y + ychange >= 0
&& color == chess1[x + xchange][y + ychange]) {
count++;
if (xchange != 0) {
xchange++;
}
if (ychange != 0) {
if (ychange < 0) {
ychange--;
} else {
ychange++;
}
}
}
xchange = tempx;
ychange = tempy;
while (x - xchange >= 0 && y - ychange >= 0
&& color == chess1[x - xchange][y - ychange]) {
count++;
if (xchange != 0) {
xchange++;
}
if (ychange != 0) {
if (ychange < 0) {
ychange--;
} else {
ychange++;
}
}
}
if (count >= 5) {
returntrue;
} else {
returnfalse;
}
}
中心思想就是要判断就要判断8个方向,其中有的只是相反的方向,我们使用关于X,Y的相对的变化来判断,并且使用count来计数,如果到了5个就可以判断胜利啦。
1.我的第三步就是时间的变化和一些键的设置
1.关于时间的变化主要是在于线程的使用,这里我们这个JFrame它继承了Runnable 这个接口,不过我们要重写Run函数,这个run函数的代码如下:
publicvoid run() {
if (this.second > 0) {
while (true) {
this.repaint();
if (this.isblack) {
this.ss1--;
if (this.ss1 == 0) {
JOptionPane
.showMessageDialog(this, "黑方超时~~~~¡¤游戏结束");
this.message1="0:0:0";
this.ss1=-1;
this.canplay = false;
}elseif(this.ss1>0)
{
this.message1 = this.ss1
/ 3600
+ " : "
+ (this.ss1 / 60 - this.ss1 / 3600 * 60)
+ " : "
+ (this.ss1 - this.ss1 / 60 * 60 - this.ss1 / 3600 * 60 * 60);
this.repaint();
}else
{
}
} else {
this.ss2--;
if (this.ss2 == 0) {
JOptionPane.showMessageDialog(this,
"白方超时~~~~¡¤¡¤游戏结束");
this.message2="0:0:0";
this.canplay = false;
}elseif(this.ss2>0)
{
this.message2 = this.ss2
/ 3600
+ " : "
+ (this.ss2 / 60 - this.ss2 / 3600 * 60)
+ " : "
+ (this.ss2 - this.ss2 / 60 * 60 - this.ss2 / 3600 * 60 * 60);
this.repaint();
}else
{
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
这个函数是用来事时间的变化,所以每操作以后就让线程sleep(1000)就可以了,那样就是一秒钟。这样就可以倒计时了。
2.现在我们要点击一个按钮要它有响应。
这里我们其实就没用到什么button,那为什么会有反应呢,因为我们通过鼠标的点击范围来确定要响应什么函数,这就是这里面的秘密.
在publicvoid mouseClicked(MouseEvent arg0) 函数里有下面这些if的判断
if (x1 >= 404 && x1 <= 473 && y1 >= 74 && y1 <= 103)
if (x1 >= 404 && x1 <= 473 && y1 >= 127 && y1 <= 155)
if (x1 >= 404 && x1 <= 473 && y1 >= 179 && y1 <= 208)
if (x1 >= 404 && x1 <= 473 && y1 >= 286 && y1 <= 316)
if (x1 >= 404 && x1 <= 473 && y1 >= 338 && y1 <= 367)
if (x1 >= 404 && x1 <= 473 && y1 >= 390 && y1 <= 419)
这就是为了确定鼠标的范围,然后相对调用函数。
其他还有就是一些Debug处理,在程序已经处理了,结果的还是蛮可以处理的,不过只能是人人对战。
四、实验心得与小结
这次试验总的来说没有想像中那么难,还有视屏的帮助,感觉起还是很容易动手的,不过由于自己没上心,没有做比较大的改动,最主要的人机的对战没做出来是满遗憾的,不过通过这个试验,让我学习了不少的知识,比如双缓冲,mouselistener 等许多许多的知识,还有关于五子棋算法的设计也是一部分。不管怎么说还是有学到知识的,没什么改动,但对现有的知识的掌握还是很可以的。
五、指导教师评议
成绩评定: 指导教师签名:
第二篇:五子棋报告 java
XXXX大学
XX学院
课程设计报告
课程名称: 面向对象程序设计
题目名称: 五子棋游戏设计
学生姓名:
专业班级:
指导教师: 任晓强
一、 课程设计目的与任务(四号、宋体、加黑、顶格)
(1)掌握Java编程、面向对象的基础知识。
(2)较熟练地编写Java应用程序Application。
(3)了解Java的常用标准类库、编程技巧、异常处理。
(4)联系已学过的内容,巩固所学的理论,增强独立工作能力。
(5)通过设计主要使学生有一个独立编写程序的过程,对理论学习及动手能力都有一个很大的提高。
(6)通过本次设计,进一步培养学生热爱专业的思想,同时对本专业综合素质的提高起一个积极的推动作用。
课程设计过程中,要严格遵守实践环节的时间安排,听从指导教师的指导。正确地完成上述内容,记录实习日记,规范完整地撰写出课程设计报告。
二、 课程设计内容
1 本设计题目的主要内容
设计一个15╳15围棋棋盘,由两玩家交替进行对战,并可以实现以下功能:
1.选择落子的先后顺序
2.重置棋盘
3.刷新重新开始
4.退出提示
并且规定退出者判为负,但退出过程中要有提示。以防不小心点错了。
最后判断某一方是否为五子连珠。
实现一个简单的多用户五子棋的游戏程序,包括如下两个界面
(1)选择对弈桌(执黑、执白)。
(2)在游戏界面,有开始,退出(游戏未结束、点退出自动判负);
2 设计思想与程序构架
2.1 程序流程图
2.2 程序的功能分配
a. 棋盘的绘制
public void draw_qipan(Graphics G) //画棋盘 15*15{
G.setColor(Color.lightGray);
G.fill3DRect(10,10,300,300,true);
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);
}
}
b. 添加按钮
Button b1=new Button("开始");
Button b2=new Button("重置游戏");
Label lblWin=new Label(" ");
Checkbox ckbHB[]=new Checkbox[3];
Button exist = new Button("退出");
public void init(){
ckbHB[0]=new Checkbox("执白",ckgHB,false);
ckbHB[1]=new Checkbox("执黑",ckgHB,false);
ckbHB[2]=new Checkbox("观看",ckgHB, false);
}
c. 鼠标棋子的触发事件
public void mouseClicked(MouseEvent e) {
Graphics g=getGraphics();
int x1,y1;
x1=e.getX();
y1=e.getY();
if (e.getX()<20 || e.getX()>300 || e.getY()<20 || e.getY()>300) {
return;
}
if (x1%20>10) {
x1+=10;
}
if(y1%20>10) {
y1+=10;
}
x1=x1/20*20;
y1=y1/20*20;
set_Qizi(x1,y1);
m*=(-1);
}
d. 按钮的触发事件
public void actionPerformed(ActionEvent e) {
Graphics g=getGraphics();
if (e.getSource()==b1) {
Game_start();
}
else{
Game_re();
}
if(e.getSource()==exist){
Game_re();
lblWin.setText(Get_qizi_color(color_Qizi)+"输了!");
intGame_Start=0;
}
e. 判断落子的位置及画出相应的黑白棋子
public void set_Qizi(int x,int y) //落子{
if (intGame_Start==0) //判断游戏未开始{
return;
}
if (intGame_Body[x/20][y/20]!=0) {
return;
}
Graphics g=getGraphics();
if (color_Qizi==1)//判断黑子还是白子{
g.setColor(Color.black);
color_Qizi=0;
}
else{
g.setColor(Color.white);
color_Qizi=1;
}
g.fillOval(x-10,y-10,20,20);
intGame_Body[x/20][y/20]=color_Qizi+1;
}
f. 判断胜负
if (Game_win_1(x/20,y/20)) //判断输赢1{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_2(x/20,y/20)) //判断输赢2{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_3(x/20,y/20)) //判断输赢3{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_4(x/20,y/20)) //判断输赢4{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
}
3 软件使用说明书
按提示操作
4 序测试及分析
a. 进入游戏界面
游戏开始的界面有三个选择项,用户可以选择相应的角色,选择完毕后点击开始进入游戏。
b. 选择角色,开始下棋
首先达到五个棋子连在一块的赢了,并在红色区域显示谁赢了!
c. 下完后,重新开始
下完一盘后游戏停止,点击重新开始,界面回到初始界面,选择角色继续游戏.
d.游戏中点退出,自动判输
在下棋的过程当中谁中途退出,即点击退出,系统自动判断谁输
5 设计总结
通过此次课程设计,将我本学期所学的JAVA知识得到巩固和应用,在设计的过程中我遇到了很到问题,不过在老师和同学们的帮助和自己的思考下还是很好的完成了。这此课程设计还让我懂得了写程序不能闭门造车,要努力拓宽知识面,开阔视野,拓展思维。它还让我学会了在网上查阅那些无限的资料。由于自己的分析设计和程序经验不足,该系统设计和实现过程中,还有许多没有完善的地方,比如用户界面设计不够美观,异常出错处理比较差等多方面问题,这些都有待进一步完善和提高。对于文中出现的不足和系统中出现的问题敬请老师指导。
三 、 附录
创建棋盘类
Public class WcyChess extends Applet implements ActionListener,MouseListener,MouseMotionListener,ItemListener{
int color_Qizi=0;//旗子的颜色标识 0:白子 1:黑子
int intGame_Start=0;//游戏开始标志 0未开始 1游戏中
int intGame_Body[][]=new int[16][16]; //设置棋盘棋子状态
int m=-1;
Button b1=new Button("开始");
Button b2=new Button("重置游戏");
Label lblWin=new Label(" ");
Checkbox ckbHB[]=new Checkbox[3];
Button exist = new Button("退出");
CheckboxGroup ckgHB=new CheckboxGroup();
NetchatClient chat=new NetchatClient();
public void init(){
setLayout(null);
addMouseListener(this);
add(b1);
b1.setBounds(330,50,80,30);
b1.addActionListener(this);
add(b2);
b2.setBounds(330,90,80,30);
b2.addActionListener(this);
ckbHB[0]=new Checkbox("执白",ckgHB,false);
ckbHB[0].setBounds(320,20,60,30);
ckbHB[1]=new Checkbox("执黑",ckgHB,false);
ckbHB[1].setBounds(380,20,60,30);
ckbHB[2]=new Checkbox("观看",ckgHB, false);
add(ckbHB[0]);
add(ckbHB[1]);
add(ckbHB[2]);
ckbHB[0].addItemListener(this);
ckbHB[1].addItemListener(this);
add(lblWin);
lblWin.setBounds(330,180,80,30);
lblWin.setBackground(Color.red);
lblWin.setText("胜利者!");//没有显示?
ckbHB[2].setBounds(440, 20,60, 30);
add(exist);
exist.setBounds(330,130,80,30);
exist.addActionListener(this);
// add(chat);chat.setBounds(20, 500, 300, 300);
chat.frame();
chat.setVisible(true);
Game_start_csh();
setSize(500,600);
setVisible(true);
}
public void itemStateChanged(ItemEvent e) {
if (ckbHB[0].getState()) //选择黑子还是白子{
color_Qizi=0;
}
else{
color_Qizi=1;
}
}
public void mousePressed(MouseEvent e){}
public void mouseClicked(MouseEvent e) {
Graphics g=getGraphics();
int x1,y1;
x1=e.getX();
y1=e.getY();
if (e.getX()<20 || e.getX()>300 || e.getY()<20 || e.getY()>300) {
return;
}
if (x1%20>10) {
x1+=10;
}
if(y1%20>10) {
y1+=10;
}
x1=x1/20*20;
y1=y1/20*20;
set_Qizi(x1,y1);
m*=(-1);
}
public void actionPerformed(ActionEvent e) {
Graphics g=getGraphics();
if (e.getSource()==b1) {
Game_start();
}
else {
Game_re();
}
if(e.getSource()==exist){
Game_re();
lblWin.setText(Get_qizi_color(color_Qizi)+"输了!");
intGame_Start=0;
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseDragged(MouseEvent e){}
public void mouseMoved(MouseEvent e){}
public void paint(Graphics g) {
draw_qipan(g);
}
判断输赢功能实现
if (Game_win_1(x/20,y/20)){ //判断输赢1
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_2(x/20,y/20)){ //判断输赢2
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_3(x/20,y/20)) //判断输赢3{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
if (Game_win_4(x/20,y/20)) //判断输赢4{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
intGame_Start=0;
}
四、 主要参考资料
1. 吴其庆编著.Java程序设计实例教程.北京:冶金工业出版社
2. 柳西玲.许斌编著.Java语言应用开发基础.北京:清华大学出版社
3.丁振凡 Java 语言实用教程 :北京邮电大学出版社