《Java语言程序设计》
实训报告
实训题目: java五子棋小游戏
专 业: 计算机网络
班 级: 08计算机网络(2)班
姓 名: XXX
指导教师: XXX
二00九年 11月 27日
目 录
1.实训目的. 3
2.实训题目描述和要求. 3
2.1实训题目描述. 3
2.2实训要求. 3
3.实训报告内容. 5
3.1主框架. 5
3.2画背景及棋盘、棋子及说明信息等. 8
3.3实现鼠标侦听及各按钮功能. 10
3.4判断五连及时间走动. 17
4.总结. 21
4.1结论. 21
4.2心得. 21
参考书目:. 22
实训指导教师评语. 23
1.实训目的
《Java程序设计》课程实训是学习Java程序开发不可缺少的实践环节。它可以将理论应用于实践,将所学知识与实际相结合,加深对所学知识的理解和应用。学完此门课程后,能使用Java开发小型应用程序。
2.实训题目描述和要求
2.1实训题目描述
实训题目:java五子棋游戏
描述:
通过java的swing组件,实现五子棋简单的双人对战,并通过内部条件判断实现输赢的判断及双方的下棋时间的控制。
2.2实训要求
进程安排:
(1):游戏界面的实现
(2):棋盘的绘制及黑白棋子的判定
(3):完成判断某一横行是否连成五子及所有方向是否连成五子的功能
(4):防止刷屏及几个简单按钮功能的实现
(5):完成最后“游戏设置”按钮的实现
游戏功能:
(1)游戏界面:
(2):判断输赢:
(3):游戏超时:
3.实训报告内容
3.1主框架
package chengxu.zhu.chengxuti;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class FiveChess extends JFrame implements MouseListener, Runnable{
//获取电脑屏幕的宽度与高度
int weight=Toolkit.getDefaultToolkit().getScreenSize().width;
int height=Toolkit.getDefaultToolkit().getScreenSize().height;
//BufferedImage img=null;
//定义一个Image类型的变量
Image image;
//获取鼠标的位置
int x,x1= 490;
int y,y1= 435;
//用来保存棋子
int qizhi[][]=new int [20][20];
//用来判断所下棋子颜色
boolean heibai=true;
//用来判断游戏是否结束(即:是否五子相连)
boolean youxikaishi=false;
// int jiaodian[][]=new int [18][18];
// 保存最多拥有多少时间(秒)
int maxTime = 0;
// 做倒计时的线程类
Thread t = new Thread(this);
// 保存黑方与白方的剩余时间
int blackTime = 0;
int whiteTime = 0;
// 保存双方剩余时间的显示信息
String blackMessage = "无限制";
String whiteMessage = "无限制";
public FiveChess(){
//隐藏标题栏
this.setUndecorated(true);
//给窗体命名
this.setTitle("实训作业------>>五子棋");
//设置窗体大小
this.setSize(700,500);
//this.setLocation((weight-500)/2,(height-500)/2);
//窗体始终在最前端(始终d置顶)
this.setAlwaysOnTop(true);
//设置初始位置
this.setLocation((weight-700)/2, (height-500)/2);
//禁止改变窗体大小
this.setResizable(false);
//设置关闭为完全关闭
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//重画背景
this.repaint();
//添加鼠标侦听事件
this.addMouseListener(this);
t.start();
t.suspend();
//通过前面定义的Image类型变量获取图像
image=this.getToolkit().getImage("../image/aa.jpg");
//设置窗口为可见
this.setVisible(true);
/*try {
img = ImageIO.read(new File("chessbackground.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
public static void main(String[] arges){
//主程序开始
new FiveChess();
}
}
3.2画背景及棋盘、棋子及说明信息等
public void paint(Graphics g){
//防止闪屏
BufferedImage bi = new BufferedImage(700, 500,BufferedImage.TYPE_INT_RGB);
//画出读入的图像
g.drawImage(image, 0 ,0, this);
// 输出时间信息
g.setColor(Color.WHITE);
g.setFont(new Font("宋体", 0, 14));
g.drawString("黑方时间:" + blackMessage, 490, 460);
g.drawString("白方时间:" + whiteMessage, 490, 480);
//画棋盘
for(int i=0;i<18;i++){
g.setColor(Color.BLUE);
g.drawLine(75+i*22, 60, 75+i*22, 434);
g.drawLine(75, 60+i*22, 449, 60+i*22);
}
//画棋盘的9个黑点
g.fillOval(138, 123, 6, 6);
g.fillOval(248, 123, 6, 6);
g.fillOval(358, 123, 6, 6);
g.fillOval(138, 233, 6, 6);
g.fillOval(248, 233, 6, 6);
g.fillOval(358, 233, 6, 6);
g.fillOval(138, 343, 6, 6);
g.fillOval(248, 343, 6, 6);
g.fillOval(358, 343, 6, 6);
g.setColor(Color.RED);
g.setFont(new Font("宋体", 10, 30));
g.drawString("★" , x1, y1);
for(int i=0;i<18;i++){
for(int j=0;j<18;j++){
if(qizhi[i][j]==1){
g.setColor(Color.BLACK);
int tempX=i*22+60;
int tempY=j*22+60;
g.fillOval(tempX+7, tempY-7, 14, 14);
}
if(qizhi[i][j]==2){
int tempX=i*22+60;
int tempY=j*22+60;
g.setColor(Color.WHITE);
g.fillOval(tempX+7, tempY-7, 14, 14);
g.setColor(Color.BLACK);
g.drawOval(tempX+7, tempY-7, 14, 14);
}
}
}
}
3.3实现鼠标侦听及各按钮功能
public void mouseClicked(MouseEvent e) {
// 游戏设置
if (e.getX() >= 546 && e.getX() <= 695 && e.getY() >= 192&& e.getY() <= 236) {
String input = JOptionPane.showInputDialog("请输入游戏的最大时间(单位:分钟),如果输入0,表示没有时间限制:");
try {
maxTime = Integer.parseInt(input) * 60;
if (maxTime < 0) {
JOptionPane.showMessageDialog(this, "请输入正确信息,不允许输入负数!");
}
if (maxTime == 0) {
int result = JOptionPane.showConfirmDialog(this,
"设置完成,是否重新开始游戏?");
if (result == 0) {
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 19; j++) {
qizhi[i][j] = 0;
}
}
// 另一种方式 allChess = new int[19][19];
// message = "黑方先行";
heibai = true;
blackTime = maxTime;
whiteTime = maxTime;
blackMessage = "无限制";
whiteMessage = "无限制";
this.youxikaishi = true;
this.repaint();
}
}
if (maxTime > 0) {
int result = JOptionPane.showConfirmDialog(this,
"设置完成,是否重新开始游戏?");
if (result == 0) {
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 19; j++) {
qizhi[i][j] = 0;
x1= 490;
y1= 435;
}
}
// 另一种方式 allChess = new int[19][19];
// message = "黑方先行";
heibai = true;
blackTime = maxTime;
whiteTime = maxTime;
blackMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
whiteMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
t.resume();
this.youxikaishi = true;
this.repaint();
}else{
blackTime = maxTime;
whiteTime = maxTime;
blackMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
whiteMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
t.resume();
}
}
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
JOptionPane.showMessageDialog(this, "请正确输入信息!");
}
}
// 关于
if (e.getX() >= 600 && e.getX() <= 678 && e.getY() >= 74
&& e.getY() <= 115) {
JOptionPane.showMessageDialog(this, "制作人:\nQQ:841043598\n游戏名:java五子棋");
}
// 说明
if (e.getX() >= 543 && e.getX() <= 692 && e.getY() >= 251
&& e.getY() <= 291) {
JOptionPane.showMessageDialog(this, "五子棋,每人下一次,分别为白子与黑子,\n若谁最先五子相连,谁获胜^_^");
}
// 退出
if (e.getX() >= 606 && e.getX() <= 682 && e.getY() >= 370
&& e.getY() <= 412) {
int tuichu = JOptionPane.showConfirmDialog(this, "游戏结束");
if(tuichu==0){
System.exit(0);
}
}
// 开始游戏
if (e.getX() >= 544 && e.getX() <= 697 && e.getY() >= 141
&& e.getY() <= 177) {
int result = JOptionPane.showConfirmDialog(this, "是否开始游戏?");
if (result == 0) {
// 现在重新开始游戏
// 重新开始所要做的操作: 1)把棋盘清空,allChess这个数组中全部数据归0.
// 2) 将 游戏信息: 的显示改回到开始位置
// 3) 将下一步下棋的改为黑方
for (int i = 0; i < 18; i++) {
for (int j = 0; j < 18; j++) {
qizhi[i][j] = 0;
}
}
// 另一种方式 allChess = new int[19][19];
heibai = true;
x1= 490;
y1= 435;
blackTime = maxTime;
whiteTime = maxTime;
if (maxTime > 0) {
blackMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
whiteMessage = maxTime / 3600 + ":"
+ (maxTime / 60 - maxTime / 3600 * 60) + ":"
+ (maxTime - maxTime / 60 * 60);
t.resume();
} else {
blackMessage = "无限制";
whiteMessage = "无限制";
}
this.youxikaishi = true;
this.repaint();
}
}
if (e.getX() >= 605 && e.getX() <= 685 && e.getY() >= 313
&& e.getY() <= 350) {
int result = JOptionPane.showConfirmDialog(this, "是否确认认输?");
if (result == 0) {
if (heibai) {
JOptionPane.showMessageDialog(this, "黑方已经认输,游戏结束!");
} else {
JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!");
}
youxikaishi = false;
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
//如果开始为真则开始游戏,反之结束游戏
if(youxikaishi==true){
//获取鼠标位置
x=e.getX();
y=e.getY();
//如果鼠标点击在棋盘范围内则执行下面条件
if(x>70&&x<455&&y>55&&y<440){
//得到棋盘各个相交点的位置
x=(x-75)/22;;
y=(y-60)/22;
//判断该点是否有落子
if(qizhi[x][y]==0){
//判断下黑棋还是白棋
if(heibai==true){
qizhi[x][y]=1;
heibai=false;
x1= 490;
y1= 435;
// this.setFont(new Font("宋体",Font.BOLD,0)) ;
this.repaint();
}
else{
qizhi[x][y]=2;
heibai=true;
x1= 490;
y1= 135;
this.repaint();
}
}
else{
JOptionPane.showMessageDialog(this, "当前位置已经有棋子,您不能落子到此处,请重新落子!");
}
//判断是否五连(即:是否游戏结束)
boolean wulian=this.wulianzhi();
if(wulian==true){
JOptionPane.showMessageDialog(this, "游戏结束,"+ (qizhi[x][y] == 1 ? "黑方" : "白方") + "获胜!");
youxikaishi=false;
}
}
}else{
x=e.getX();
y=e.getY();
if(x>70&&x<455&&y>55&&y<440){
JOptionPane.showMessageDialog(this, "请开始游戏");
}
}
}
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
3.4判断五连及时间走动
public boolean wulianzhi(){
boolean wulianzhi=false;
int xianglianshu=1;
int yanse=qizhi[x][y];
xianglianshu = this.checkCount(1, 0, yanse);
if (xianglianshu >= 5) {
wulianzhi = true;
} else {
// 判断纵向
xianglianshu = this.checkCount(0, 1, yanse);
if (xianglianshu >= 5) {
wulianzhi = true;
} else {
// 判断右上、左下
xianglianshu = this.checkCount(1, -1, yanse);
if (xianglianshu >= 5) {
wulianzhi = true;
} else {
// 判断右下、左上
xianglianshu = this.checkCount(1, 1, yanse);
if (xianglianshu >= 5) {
wulianzhi = true;
}
}
}
}
return wulianzhi;
}
private int checkCount(int xChange, int yChange, int color) {
int count = 1;
int tempX = xChange;
int tempY = yChange;
while (x + xChange >= 0 && x + xChange <= 18 && y + yChange >= 0
&& y + yChange <= 18
&& color == qizhi[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 && x - xChange <= 18 && y - yChange >= 0
&& y - yChange <= 18
&& color == qizhi[x - xChange][y - yChange]) {
count++;
if (xChange != 0)
xChange++;
if (yChange != 0) {
if (yChange > 0)
yChange++;
else {
yChange--;
}
}
}
return count;
}
@Override
public void run() {
// TODO Auto-generated method stub
if (maxTime > 0) {
while (true) {
if (heibai) {
blackTime--;
if (blackTime < 0) {
JOptionPane.showMessageDialog(this, "黑方超时,游戏结束!");
youxikaishi=false;
break;
}
} else {
whiteTime--;
if (whiteTime < 0) {
JOptionPane.showMessageDialog(this, "白方超时,游戏结束!");
youxikaishi=false;
break;
}
}
blackMessage = blackTime / 3600 + ":"
+ (blackTime / 60 - blackTime / 3600 * 60) + ":"
+ (blackTime - blackTime / 60 * 60);
whiteMessage = whiteTime / 3600 + ":"
+ (whiteTime / 60 - whiteTime / 3600 * 60) + ":"
+ (whiteTime - whiteTime / 60 * 60);
this.repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(blackTime + " -- " + whiteTime);
}
}
}
4.总结
4.1结论
游戏的主界面由一张图片构成,没添加其他的组件。所有的功能全部有鼠标点击事件来完成。在游戏说明中,简单的说明了这个五子棋的运行方式。游戏只能在点击游戏开始的按钮后才会开始,在游戏结束后,要点击重新开始,把整个游戏的界面以及内部的参数全部初始化,要再次开始游戏还要点击开始按钮。在游戏设置中,通过设置游戏时间来规定玩家下棋时间。在游戏说明中,通过弹出的窗口来告知作者信息。在认输中,一方点击后,该方认输,游戏结束。在退出中,通过玩家选择是、否、取消来判定退出游戏
在界面设计方面,使用PhotoShop来处理,把几张图片拿来合成,做成现在的主界面。
4.2心得
在做这个项目最大的体会,就在做之前,最好是要有个详细的计划。把需要的功能设计到位。不然,到最后牵一发而动全身。
其次要感谢指导老师给予我的指导!
参考书目:
[1] 赵景晖、迟勇.《Java语言程序设计》.大连:大连理工大学出版社.2008.10
[2] 埃史尔、陈昊鹏.《Java编程思想)》.北京:机械工业出版社.2007.06
江西工业职业技术学院电子与信息工程分院
实训指导教师评语
班级:08计网(2)班 学生姓名: 学号:
指导教师评语(包括工作态度,遵守纪律;基本理论、知识、技能;独立工作能力和分析解决问题的能力;完成任务情况及水平):
学生成绩(五级分制):
指导教师签名: 年 月 日