一、 概述
本文使用功能强大的Eclipse开发工具和java开发语言开发出一款拥有自己特色的五子棋小程序,其中Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括 Java 开发工具(Java Development Tools,JDT)。
1.1编程语言
1.1.1 java语言介绍
现代技术的发展,尤其是网络技术,给现代企业带来了许多新的机遇和挑战,如改善客户服务、全球化和信息检索等,这些在技术上反映为信息的获取、系统管理、系统集成、新技术的开发、Internet、Intranet等等与商业的结合。而这些要求一个随处可用的开放的结构和在不同的平台之间低成本的信息传递方式,Java正好满足这些要求。
Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动感的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet。另一方面,Java技术也不断更新。Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、简称API)构成。Java 应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译一次,就可以在各种系统中运行。Java应用编程接口已经从1.1.x版发展到1.2版。目前常用的Java平台基于Java1.2。 Java语言是一个支持网络计算的面向对象程序设计语言。Java语言吸收了Smalltalk语言和C++语言的优点,并增加了其它特性,如支持并发程序设计、网络通信、和多媒体数据控制等。
1.1.2 java语言的优点
(1)面向对象
Java提供了简单的类机制和动态的构架模型。对象中封装了它的状态变量和方法,很好地实现了模块化和信息隐藏;而类则提供了一类对象的原型,通过继承和重载机制,子类可以使用或重新定义父类或超类所提供的方法,从而既实现了代码的复用,又提供了一种动态的解决方案。
(2) 多线程
多线程使应用程序可以同时进行不同的操作,处理不同的事件。在多线程机制中,不同的线程处理不同的任务,他们之间互不干涉,不会由于一处等待影响其他部分,这样容易实现网络上的实时交互操作。
(3)动态性
Java的设计使它适合于一个不断发展的环境。在类库中可以自由地加入新的方法和实例变量而不会影响用户程序的执行。并且 Java通过接口来支持多重继承 ,使之比严格的类继承具有更灵活的方式和扩展性。
(4) 安全性
用于网络、分布环境下的Java必须要防止病毒的入侵,Java不支持指针,一切对内存的访问都必须通过对象的实例变量来实现,这样就防止了程序员使用欺骗手段访问对象的私有成员,同时也避免了指针操作中容易产生的错误。
(5).可移植性
与平台无关的特性使 Java程序可以方便地被移植到网络上的不同机器。同时 ,Java的类库中也实现了与不同平台的接口 ,使这些类库可以移植。另外,Java编译器是由 Java语言实现的 ,Java运行时系统由标准 C实现 ,这使得Java系统本身也具有可移植性。
1.2 java开发平台
1.2.1 java的开发环境
Java是由Sun微系统公司所发展出来的程序语言,它本身是一种对象导向(Object-Oriented)的程序语言。JAVA目前在手机上应用最多的就是JAVA游戏。
Java也号称是能跨平台使用的语言,这主要是因为Java本身被编译之后,并不是直接产生可执行的码,而是产生一种中间码叫作 ByteCode,这种码必需在透过 Java 的直译器来解读它,才能够真正的被执行,所以只要平台上装有这种Java的直译器,就能解读ByteCode也就能执行Java编译过的程序,故与Java程序是在哪种平台上被编译的,就完全没有关系了。Java写出来的程序可分为两类,分别是Java Applet与一般的Application,而Application 这一类就与一般的程序如C++的作用是比较类似的,是一个独立可执行的应用程序,像HotJava是一个浏览器,且就是使用Java程序所开发出来的。最常见的Java程序包括应用程序和applets。应用程序是单独的程序,诸如HotJava浏览器软件就是用Java语言编写的。 Applets类似于应用程序,但是它们不能单独运行, Applets可以在支持Java的浏览器中运行。Applet主要是内置于HTML网页中,在浏览时发挥作用。
1.2.2 java的编辑环境
(一)用功能强大的开源工具Eclipse来开发,相对较为方便,eclipse比较通用,而且支持很多插件。
(二) Java主要是利用文本编辑器来完成程序设计的编辑工作,可以使用各种文本编辑器来编写,例如:记事本、Editplus和UltraEdit软件等都可以用来实现。
(1)用记事本编写过程很简单,只需要带开记事本在里面编写代码几可以了。
(2)用Editplus软件配置JAVA编辑环境:
1:打开Editplus,选择"工具->参数选择"在弹出的窗口中选择"用户工具";
2:点组名称,将"组1"改成别的名称(当然不改也可以);点"添加工具->应用程序";菜单文件选项可写"Java编译",在命令中选择JDK的javac.exe,是在JDK的目录下的bin目录下;参数在下拉菜单中选择"文件名",初始目录在下拉菜单中选择"文件目录";在"捕获输出"前打勾,这就完成了"Java编译"的配置.
3:再点"添加工具->应用程序";菜单文件选项可写"Java运行",在命令中选择JDK的java.exe.参数在下拉菜单中选择"文件名(不含扩展名)",初始目录在下拉菜单中选择"文件目录";在"捕获输出"前打勾,完成了"Java编译"的配置.配置完成了,写一个"Hello World"来测试一下.只要按快捷键"Ctrl+1",是对当前打开的文件进行编译;只要按快捷键"Ctrl+2",是运行当前文件.
(三)Jbulder也是java的一款开发工具,功能更全面,而且操作好多都是即见即所得的,就想VB一样方便快捷,不过它是一款收费软件,所以不是一些大公司一般不会使用它来作为java的开发工具。
1.2.3 java的运行环境
通常一个程序运行的平台是一个硬件或者软件运行的环境。目前比较流行的是Windows 2000, Linux, Solaris, 和MacOS。Java的平台不太一样,它由两个部分组成:一个是Java Virtual Machine即Java虚拟机,另一部分是Java Application Programming Interface (Java API) 即Java应用程序设计接口,这两部份软件就构成了Java运行的基本的环境。Java API 是一个大的已经做好的软件集合,这个集合里有许多开发时所需要的控件,用来辅助开发。Java API和JVM整合在一起处于机器硬件之上。也就是说,Java平台把一个Java应用程序从硬件系统分离开从而很好的保证了程序的独立性。为了更好的适应开发的需要,Java的设计者们为我们提供了三种Java平台:Java 2 Micro Edition (J2ME ), Java 2 Standard Edition (J2SE)和 Java 2 Enterprise Edition (J2EE). 每一个版本都提供了丰富的开发工具箱以适应不同的开发需要。
二、需求分析
2.1五子棋发展史
五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“连珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。
对于五子棋与围棋的关系有两种说法,一说早于围棋,早在“尧造围棋”之前,民间就已有五子棋游戏;一说源于围棋,是围棋发展的一个分支。在中国的文化里,倍受人们的青睐。古代的五子棋的棋具与围棋相同,纵横各十七道。五子棋大约随围棋一起在我国南北朝时先后传入朝鲜、日本等地。
2.2 五子棋功能说明
2.2.1五子棋特点及规则
五子棋的娱乐性强、规则简单、易学、流行性广,普通人不需长时间专门训练即可自如行棋,因此极受大众喜欢·
五子棋规则为:
1.棋盘:采用像围棋盘一样的棋盘,本系统采用18路的棋盘·
2.下法:两人分别执黑白两色棋子,轮流在棋盘上选择一个无子的交叉点落子,无子的交叉点又被称为空点·
3.输赢判断:黑、白双方有一方的五个棋子在横、竖或斜方向上连接成一线即为该方赢。
2.2.2操作界面需求
操作界面如下图(1)、图(2)所示,游戏画面简单易懂:
2.2.3程序流程
2.2.4主要模块分析
我们看到本程序由4个基本功能模块构成,各模块的详细分析如下:
1.初始化FiveChessFrame类
过imagePath = System.getProperty("user.dir")+"/bin/background.jpg" ;
bgImage = ImageIO.read(new File(imagePath.replaceAll("\\\\", "/")));
加载背景图片,然后再背景图上通过:paint方法中的for (int i = 0; i < 18; i++) { g2.drawLine(258, 102 + 30 * i, 767, 102 + 30 * i);
g2.drawLine(258 + 30 * i, 102, 258 + 30 * i, 612);
}语句绘制一个18*18的网格棋盘,每次下棋后通过调用repaint方法来初始化程序。
2.通过public void mousePressed(MouseEvent e)这个主方法中的isBlack变量值来判断当前应该哪一方开始下棋。
3.若是白子,则通过allChess[][]这个二维数组的值为1来定义该子,若是黑子,则通过allChess[][]数组的值为2来定义该子,若为0,则为空。
4.通过checkWin()方法来判定当前方是否已练成5个同颜色的棋子。若同时有了5个同颜色的连子(不论是竖直,水平还是斜方向的)则判定该方获胜。
三、 设计分析
3.1重点模块分析:
本程序最重要的就是能够自动判定黑白两方各个方向上的棋子是否连成了五个相同颜色的棋子,怎么做到这点呢?这个要通过private int checkCount(int xChange, int yChange, int color)方法来判定,然后通过private boolean checkWin()方法判定获胜方(具体方法后边会写出,供读者了解分析)。其次本程序关键的一点就是可以模拟游戏中的按钮来自定义游戏的时间,从而增加本游戏的可控性,智能性,同时增强游戏玩家的趣味性和刺激性。
3.2 设计流程:
因为本程序用Eclipse开发,如图(3):
四、代码设计
4.1 主类Game:
package li;
publicclass Game {
publicstaticvoid main(String[] args) {
FiveChessFrame f = new FiveChessFrame();
}
}
4.2程序窗体类FiveChessFrame类:
4.2.1主类FiveChessFrame:
publicclass FiveChessFrame extends JFrame implements MouseListener, Runnable {
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
int height = Toolkit.getDefaultToolkit().getScreenSize().height;
BufferedImage bgImage = null;
int x = 0;int y = 0;
int[][] allChess = newint[18][18];
boolean isBlack = false;boolean canPlay = true;
String message = "白方先行";int maxTime = 0;
Thread t = new Thread(this);
int blackTime = 0;int whiteTime = 0;
String blackMessage = "无限制";
String whiteMessage = "无限制";
String set="设置";
String help="帮助";
String about="关于";
String start="开始";
String lose="认输";
String rule="规则";
String exit="退出";
public FiveChessFrame() {
this.setTitle("五子棋");
this.setFont(new Font("宋体", Font.BOLD, 40));
this.setSize(1000, 750);
this.setLocation((width - 1000)/2, (height - 750) /2);
this.setResizable(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addMouseListener(this);
this.setVisible(true);
t.start();
t.suspend();
this.repaint();
String imagePath = "" ;
try {
imagePath=System.getProperty("user.dir")+"/bin/4.jpg" ;
bgImage = ImageIO.read(new File(imagePath.replaceAll("\\\\", "/")));
} catch (IOException e) {
e.printStackTrace();
}
}
4.2.2画棋盘的paint方法:
publicvoid paint(Graphics g) {
BufferedImage bi = new BufferedImage(1000, 750,
BufferedImage.TYPE_INT_RGB);
Graphics g2 = bi.createGraphics();
g2.setColor(Color.WHITE);
g2.drawImage(bgImage, 1, 20, this);
g2.setFont(new Font("宋体", Font.BOLD, 20));
g2.drawString("游戏信息:" + message, 428, 83);
g2.setColor(Color.BLACK);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(whiteMessage, 128, 360);
g2.setColor(Color.WHITE);
g2.drawString(blackMessage, 830, 365);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(set, 240, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(help, 320, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(about, 400, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(start, 480, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(lose, 560, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(rule, 640, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
g2.drawString(exit, 720, 660);
g2.setColor(Color.yellow);
g2.setFont(new Font("宋体", Font.BOLD, 30));
for (int i = 0; i < 18; i++) {
g2.drawLine(258, 102 + 30 * i, 767, 102 + 30 * i);
g2.drawLine(258 + 30 * i, 102, 258 + 30 * i, 612);
}
g2.fillOval(375, 219, 8, 8);
g2.fillOval(645,219, 8, 8);
g2.fillOval(645, 489, 8, 8);
g2.fillOval(375, 489, 8, 8);
for (int i = 0; i < 18; i++) {
for (int j = 0; j < 18; j++) {
if (allChess[i][j] == 1) {
int tempX = i * 30 + 258;int tempY = j * 30 + 102;
g2.fillOval(tempX - 12, tempY - 12, 28, 28);
}
if (allChess[i][j] == 2) {
int tempX = i * 30 + 258;int tempY = j * 30 + 102;
g2.setColor(Color.WHITE);
g2.fillOval(tempX - 12, tempY - 12, 28, 28);
g2.setColor(Color.BLACK);
g2.drawOval(tempX - 12, tempY - 12, 28, 28);
}
}
}
g.drawImage(bi, 0, 0, this);
}
4.2.3鼠标点击的mousePressed()方法,其中包括点击各个按钮的相应事件:
publicvoid mousePressed(MouseEvent e) {
System.out.println("X:"+e.getX()); System.out.println("Y:"+e.getY());
if (canPlay == true) {
x = e.getX();
y = e.getY();
if (x >=260 && x <= 767 && y >= 101 && y <= 610) {
x = (x - 260) / 30;y = (y - 101) / 30;
if (allChess[x][y] == 0)
{
if (isBlack == true) {
allChess[x][y] = 1;
isBlack = false;
message = "轮到白方";
} else {
allChess[x][y] = 2;
isBlack = true;
message = "轮到黑方";
}
boolean winFlag = this.checkWin();
if (winFlag == true) {
if(allChess[x][y]== 1){
message="黑方胜利";
t.suspend();
}
else
{
message="白方胜利";
t.suspend();
}
JOptionPane.showMessageDialog(this, "游戏结束,"
+ (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜!");
this.canPlay = false;
}
} else {
JOptionPane.showMessageDialog(this, "当前位置已经有棋子,请重新落子!");
}
this.repaint();
}
}
if (e.getX() >= 482 && e.getX() <= 523 && e.getY() >= 667&& e.getY() <= 685) {int result = JOptionPane.showConfirmDialog(this, "是否重新开始游戏?");if (result == 0) {
for (int i = 0; i < 18; i++) {
for (int j = 0; j < 18; j++) {
allChess[i][j] = 0;
}
}
message = "白方先行";isBlack = false;
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.canPlay = true;this.repaint();
}
}
if (e.getX() >= 245 && e.getX() <= 301 && e.getY() >= 637
&& e.getY() <= 663) {
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 < 18; i++) {
for (int j = 0; j < 18; j++) {
allChess[i][j] = 0;
}
}
message = "白方先行";isBlack = false;
blackTime = maxTime;whiteTime = maxTime;
blackMessage = "无限制";whiteMessage = "无限制";
t.suspend();this.canPlay = true;this.repaint();
}
}
if (maxTime > 0) {
int result = JOptionPane.showConfirmDialog(this,
"设置完成,是否重新开始游戏?");
if (result == 0) {
for (int i = 0; i < 18; i++) {
for (int j = 0; j < 18; j++) {
allChess[i][j] = 0;
}
}
message = "白方先行";isBlack = false;
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.canPlay = true;this.repaint();
}
}
} catch (NumberFormatException e1) {
JOptionPane.showMessageDialog(this, "请正确输入信息!");
}
}
if (e.getX() >= 645 && e.getX() <= 700 && e.getY() >= 637 && e.getY() <= 663) {
JOptionPane.showMessageDialog(this,
"这个一个五子棋游戏程序,黑白双方轮流下棋,当某一方连到五子时,则该方获胜,同时游戏结束。");
}
if (e.getX() >= 325 && e.getX() <= 348 && e.getY() >= 637 && e.getY() <= 663) {
JOptionPane.showMessageDialog(this,"游戏开始时,根据上方提示信息,用鼠标点击棋盘黑白双方轮流下子");
}
if (e.getX() >= 556 && e.getX() <= 621 && e.getY() >= 637 && e.getY() <= 663) {int result = JOptionPane.showConfirmDialog(this, "是否确认认输?");
if (result == 0) {if (isBlack) {message ="黑方认输,白方获胜!!!";this.repaint();JOptionPane.showMessageDialog(this, "黑方已经认输,游戏结束!");
} else {
message="白方认输,黑方获胜!!!";
this.repaint();
JOptionPane.showMessageDialog(this, "白方已经认输,游戏结束!");
}
canPlay = false;
}
}
if (e.getX() >= 402 && e.getX() <= 458 && e.getY() >= 637 && e.getY() <= 663) {
JOptionPane.showMessageDialog(this,"本大人:李嘉帮");
}
if (e.getX() >= 716 && e.getX() <= 762 && e.getY() >= 648&& e.getY() <= 665) {JOptionPane.showMessageDialog(this, "游戏结束");System.exit(0);
}
}
publicvoid mouseReleased(MouseEvent e) {
}
privateboolean checkWin() {
boolean flag = false;
int count = 1;int color = allChess[x][y];
count = this.checkCount(1, 0, color);
if (count >= 5) {
flag = true;
} else {
count = this.checkCount(0, 1, color);
if (count >= 5) {flag = true;
} else {
count = this.checkCount(1, -1, color);
if (count >= 5) {
flag = true;
} else {
count = this.checkCount(1, 1, color);
if (count >= 5) {
flag = true;
}
}
}
}
return flag;
}
privateint checkCount(int xChange, int yChange, int color) {
int count = 1;
int tempX = xChange;
int tempY = yChange;
while (x + xChange >= 0 && x + xChange <= 17 && y + yChange >= 0
&& y + yChange <= 17
&& color == allChess[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 <= 17 && y - yChange >= 0&& y - yChange <= 17&& color == allChess[x - xChange][y - yChange]) {count++;
if (xChange != 0)
xChange++;
if (yChange != 0) {
if (yChange > 0)
yChange++;
else {
yChange--;
}
}
}
return count;
}
publicvoid run() {
if (maxTime > 0) {
while (true) {
if (isBlack) {
blackTime--;
if (blackTime == 0) {
message ="白方胜利";
JOptionPane.showMessageDialog(this, "黑方超时,游戏结束!");
blackMessage ="0:0:0";this.canPlay=false;this.repaint();t.suspend();
}
} else {
whiteTime--;
if (whiteTime == 0) {
message ="黑方胜利";
JOptionPane.showMessageDialog(this, "白方超时,游戏结束!");
whiteMessage ="0:0:0";this.canPlay =false;
this.repaint();t.suspend();
}
}
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) {
e.printStackTrace();
}
}
}
}
五、 游戏的调试
1 由于本程序是在Eclipse中开发的,所以程序在运行的过程中是看不到中间的编译过程的,直接从测试类Game运行来进行游戏的调试,如图(4):
图(4)
3 测试一下游戏下方各虚拟按钮的效果,看是否能正常响应鼠标的操作,首先点击“设置”按钮并在对话框中输入数字5时如下图(5)所示:
图(5)
回车后如图(6)所示:
图(6)
点击“是”按钮后如图(7)所示:
图(7)
由于篇幅有限不在一一测试,最后看下获胜后的结果如图(8)所示:
图(8)
第六章 结论
通过对五子棋游戏的编写,使自己对java语言有了更深的了解。也更加熟悉和了解了java开发工具Eclipse的使用
同时,程序在编写完毕之后还有很多地方需要完善。例如:可以把另一方选择为电脑方,让电脑自动下,也可以给游戏添加背景音乐;甚至可以修改成网络游戏,用户可以在网上对战。总之,有很多地方可以扩充和完善。在此次毕业设计过程中我也学到了许多了关于计算机方面的知识,编程能力有了很大的提高。
参考文献
[1] 叶核亚,陈道蓄.Java 2程序设计实用教程.电子工业出版社,2008,11(8)
[2] 严小卫,莫建文.智能五子棋的设计与实现.广西师范大学学报1999年12月
[3] (美)埃克尔 著,陈昊鹏 译,《Java编程思想》 机械工业出版社20##年06
[4]《Java课程设计案例精编》 张广彬 孟红蕊 张永宝 编著 清华大学出版社
[5]www.mldn.cn