1、1 引言伴随计算机技术不停发展,网络技术普及范围越来越广,网络能够提供服务多样、便捷,已经成为大家生产生活中不可缺乏关键组成部分。现在网络休闲游戏发展快速,它凭借健康、方便、互动性强、益智等很多优点,成为大部分现代人休闲娱乐首选。网络五子棋游戏是使用Java语言开发一款游戏。它使用SOCKET建立连接,多线程处理数据,和可嵌入网络浏览器APPLET作为用户端,这些特点使这款游戏不管是服务器还是用户端实现全部相对轻易。经过对该软件编写,还能够巩固学生对以上多种知识掌握和了解。2 JAVA语言概述2.1 JAVA介绍JAVA是Sun Microsystem企业开发编程语言,是一个简单,面向对象,分
2、布式,解释性,强壮,安全,和系统无关,可移植,高性能,多线程和动态语言。2.1.1 JAVA基础特点(1) 简单性Java和C+语言很相近,但Java比C+简单,它抛弃了C+中部分不是绝对必需功效,如头文件、预处理文件、指针、结构、运算符重载、多重继承和自动强迫同型。 Java实现了自动垃圾搜集,简化了内存管理工作。(2) 面向对象Java提供了简单类机制和动态构架模型。对象中封装了它状态变量和方法,很好地实现了模块化和信息隐藏;而类则提供了一类对象原型,经过继承和重载机制,子类能够使用或重新定义父类或超类所提供方法,从而既实现了代码复用,又提供了一个动态处理方案。(3) 多线程多线程使应用程
3、序能够同时进行不一样操作,处理不一样事件。在多线程机制中,不一样线程处理不一样任务,她们之间互不干涉,不会因为一处等候影响其它部分,这么轻易实现网络上实时交互操作。 (4) 分布性Java是面向网络语言。经过它提供类库能够处理TCP/IP协议,用户能够经过URL地址在网络上很方便访问其它对象。(5) 体系结构中立Java是一个网络语言,为使Java程序能在网络任何地方运行,Java解释器生成和体系结构无关字节码结构文件格式。为了使Java应用程序能不依靠于具体系统,Java语言环境还提供了用于访问底层操作系统功效类组成包,当程序使用这些包时,能够确保它能运行在多种支持Java平台上。(6) 安
4、全性用于网络、分布环境下Java必需要预防病毒入侵,Java不支持指针,一切对内存访问全部必需经过对象实例变量来实现,这么就预防了程序员使用欺骗手段访问对象私有组员,同时也避免了指针操作中轻易产生错误。2.1.2 Java中输入/输出流概念过滤流DataInputStream 和DataOutputStream 除了分别作为FilterInputStream 和FilterOutputStream子类外,还分别实现了接口DataInput 和DataOutput。接口DataInput 中定义方法关键包含从流中读取基础类型数据、读取一行数据、或读取指定长度字节数,如readBoolean()、
5、 readInt()、readLine()、readFully()等。接口DataOutput中定义方法关键是向流中写入基础类型数据或写入一定长度字节数组,如writeChar()、writeDouble()。 DataInputStream能够从所连接输入流中读取和机器无关基础类型数据,用以实现一个独立于具体平台输入方法;DataOutputStream 能够向所连接输出流写入基础类型数据。2.1.3 Socket 机制Socket是面向用户/服务器模型设计,网络上两个程序经过一个双向通讯连接实现数据交换,这个双向链路一端称为一个Socket。 Socket通常见来实现用户方和服务方连接。用
6、户程序能够向Socket写请求,服务器将处理此请求,然后经过Socket将结果返回给用户。Socket通信机制提供了两种通讯方法:有联接和无联接方法,分别面向不一样应用需求。使用有联接方法时,通信链路提供了可靠,全双工字节流服务。在该方法下,通信双方必需创建一个联接过程并建立一条通讯链路,以后网络通信操作完全在这一对进程之间进行,通信完成关闭此联接过程。使用无联接方法时其系统开销比无联接方法小,但通信链路提供了不可靠数据报服务,不能确保信源所传输数据一定能够抵达信宿。在该方法下,通信双方无须创建一个联接过程和建立一条通讯链路,网络通信操作在不一样主机和进程之间转发进行。在java中使用套接字相
7、当简单,Java API为处理套接字通信提供了一个类.Socket。使得编写网络应用程序相对轻易。JAVA支持流套接字(stream socket)和数据报套接字(datagram socket)。流套接字使用TCP(Transmission Control Protocol,传输控制协议)进行数据传输,而数据报套接字使用UDP(User Datagram Protocol,用户数据报协议)。在Socket层实现Java网络程序是严格同时。从一台机器发送数据操作要求对应一个从其它机器接收数据操作。2.2 JAVA工具JDK1) Java编译器Java编译器将Java源代码文件编译成可实施Jav
8、a字节码。Java源代码文件扩展名为 .java,Java编译器把这种扩展名文件编译成扩展名为.class文件。源文件中每个类在编译后全部将产生一个class文件,这意味一个Java源代码文件可能编译生成多个class文件。2) Java解释器Java解释器对编译生成字节码格式可实施程序运行提供支持,它是运行非图形Java程序命令行工具。3 程序设计思绪和算法3.1 人机博弈关键点人机对弈程序,最少应含有以下5个部分: (1)某种在机器中表示棋局方法,能够让程序知道博弈状态。 (2)产生正当走法规则,以使博弈公正地进行,并可判定人类对手是否乱走。 (3)从全部正当走法中选择最好走法技术。 (4
9、)一个评定局面优劣方法,用以同上面技术配合做出智能选择。 (5)一个界面,有了她,这个程序才能用。3.2 五子棋特点及规则 五子棋娱乐性强、规则简单、易学、流行性广。一般人不需长时间专门训练即可自如行棋。所以极受大众欢迎。五子棋规则为: (1)棋盘 采取像围棋盘一样15路或19路线棋盘,在此采取19路棋盘。 (2)下法 两人分别执黑白两色棋子。轮番在棋盘上选择一个无子交叉点落子,无子交叉点又被称为空点。 (3)输赢判定 黑、白双方有一方五个棋子在横、竖或斜方向上连接成一线即为该方赢。3.3 算法设计3.3.1 博弈树搜索过程 在以下讨论中,命名2个博弈者MAX和MIN。下面任务是为MAX找最好
10、移动。假设MAX先移动,然后2个博弈者轮番移动。所以,深度为偶数节点,对应于MAX下一步移动位置,称为MAX节点;深度为奇数节点对应于MIN下一步移动位置,称为MIN节点(博弈树顶节点深度为0)。k层包含深度为2k和2k1节点。通常见层数表示博弈树搜索深度,她能够表示出向前估计必需认识到搜索到终点是不可能(除了在博弈快结束时),所以,常采取在有限范围搜索方法。这里使用启发式搜索。在启发式搜索过程中,关键一步是怎样确定下一个要考察节点,在确定节点时只要能充足利用和问题相关信息,估量出节点关键性,就能在搜索时选择关键性较高节点,以利于博弈者以较快速度求出最好棋步。3.32 采取静态评定函数 这里用
11、评定函数h(i)衡量每一个叶节点位置“值”。 一个最好首步能够由一个最小最大化过程产生。假设轮到MAX从搜索树叶节点中选择,她肯定选择拥有最大值节点。所以,MIN叶节点一个MAX节点双亲倒推值就等于叶节点静态评定值中最大值。其次,MIN从叶结点中选择时,必需选择最小节点(即最负值)。既然如此,MAX叶节点MIN双亲节点被分配一个倒推值,她等于叶节点静态评定值最小值。在全部叶节点父节点被给予倒推值后,开始倒推另一层,假定MAX将选择有最大倒推值MIN后继节点,而MIN会选择有最小倒推值MAX后继节点。继续逐层对节点评定,直到最终开始节点后继者被给予倒推值。MAX将选择有最大倒推值节点作为她首步。
12、整个过程有效性基于这么假设。用整个棋盘估值函数h(n)为静态估值函数。设想目前棋局S为轮到计算机方下棋(用 表示),任选一空点作为计算机方下棋位置(可有若干种选择),接着考虑在此情况下游戏者一方下棋棋局(用O表示);从某一“O”棋局出发,任选一空点作为游戏者一方落子处(又有若干种选择),再次形成计算机方下棋“ ”棋局;依这类推,这么可形成一棵以S为根结点博弈树,该树以O棋局为第2层子结点,以棋局为第3层子结点等等。假如继续向前搜索,可形成多层子结点,现在以向前搜索3层子结点为例来说明极大极小值过程。对第3层子结点某一棋局n,求出其估量值h(n),假设有一博弈树已形成,图1所表示,h(n)值由各
13、结点旁数值给出。 依据极小极大化分析法,先计算第3层子结点h(n)值,然后第2层子结点估量值取她各后继子结点极小值,根结点估量值取她各子结点极大值。这个取得最大估量值子结点即为从S出发计算机方最好落子方案。棋盘上某一行、某一列或某一对角线为一路,这里使 用棋盘为19行19列,所以,行和列方向上共有191938路;从左下到右上方向对角线有37路,一样,从左上到右下方向对角线也有37路。但对于五子棋来说必需在一条直线上有连续五个棋子才能赢。所以,在对角线上就能够降低8路。所以,整个棋盘路总数为:对某一棋局n,第i路得分:h(i)hc(i)hm(i)。 其中:hc(i)为计算机方在第i路估量值得分,
14、hm(i)为游戏者一方在第i路得分。正确得分规则作以下说明。规则中代表一空点;o代表对方棋子;代表有计算机方棋子;表示连续2点为空点;表示连续3个空点接一个计算机方棋子,再接两空点。某一规则 表示如在i路上有棋子组成形如则hc(i)30。其它规则表示相同。在系统中使用关键估值规则以下: 由对称性可知和估值相同,同理可得其它含有这么对称性估值全部认为是相等。在连续两路上出现(3)情形=hc(i)=5 000,一路出现(3),另外一路出现(4)=hc(i)=5 000。所以在整个棋盘上总估值为:为了增加系统智能化也能够添加其它部分规则。3.33 遗传算法优化估值函数 在博弈程序几大关键部分里,估值
15、函数是和具体棋类知识紧密结合一部分。能够说估值函数在很大程度上决定了博弈程序棋力高低。上面给出估值是依据实际经验给出。怎样对上述估值进行优化呢?下面采取遗传算法来改善静态估值。遗传算法估量值在很大程度上也依靠于实施者经验。不过能够利用部分高水平名局棋谱或同其它博弈程序对弈,看使用某一组参数时取胜机率有多大来进行较验。经过几次试验通常就能够得到很好静态估值。传统算法通常只能维护一组很好参数。遗传算法同传统算法相比能够同时维护几组很好参数,经过向其中添加一组新参数,通常是将几组老参数中选出值组合在一起做一点改变。然后同几组老参数比较孰优孰劣,将最差一组从中去除。这里面较关键操作是交叉和变异操作。交
16、叉经过随机交换父代个体信息来继承已经有参数中优良内容;变异经过随机改变个体中基所以增加种群多样性,避免优化因局部震荡而失败。 能够将遗传算法优化估值参数过程用图2表示。遗传算法优点: (1)因为搜索算法是从问题解开始,而不是一组参数。所以被局部震荡干扰造成求最优解失败可能性大大减小。 (2)此算法能将搜索关键集中于性能高部分,能较快地求出最好参数。在使用中应该注意问题以下: 种群数目 这是影响算法性能关键原因。种群数目过大,会造成运算时间太长,结果收敛缓慢;种群数目太小则可能造成算法精度过低,甚至停止不前。 交叉概率 这个用于控制交叉操作频度。此概率过大会造成种群中个体更新过快,较优个体不能稳
17、定保持和传输信息;此概率过小则会使优化过程缓慢甚至停止不前。 变异概率 这个概率用于控制产生变异个体频度,目标是预防整个种群中任意参数多个基因保持不变。一 般使用一个很小概率即足以达成此任务;概率太大则遗传信息无法稳定传输,从而使优化过程变成随机过程,失去确切方向而造成失败。4 程序实现4.1 程序设计思绪实现一个用户能够Internet上任何地方不一样机上进行游戏,使用多线程和网络套接字数据流分布式五子棋游戏,依据要完成功效,本程序采取多用户服务方法。服务器创建服务器Socket,一直处于监听等候状态。用户端是动作提议者,何时发出申请由用户端决定。用户端向服务器发出申请,服务器给响应,用户端
18、发出申请后立即可从Socket通道去取服务方结果。服务器接收两个用户端连接后开始一个线程,不停接收用户端发来数据,并把处理后数据传送给用户端。服务器能够创建任意多局(图3-1)。服 务 器游戏局1游戏局N用户端1用户端2用户端M用户端N图3-1 系统框架Fig.3-1 Frame of System在对服务器和用户端设计开发之前,为了使开发方便,将服务器和用户端之间用以通信变量要求好。经过编写一个接口GameConstant(),在其中定义各个常量值:public static int PLAYER1 = 1;public static int PLAYER2 = 2;public stati
19、c int PLAYER1_WON = 1;public static int PLAYER2_WON = 2;public static int DRAW = 3;public static int CONTINUE = 4; public static int STOP = 100;public static int GAMEPORT = 8000; 服务器和用户端在设计时继承接口GameConstant()里面全部数据。4.2 服务器设计和实现为了使界面友好,服务器使用图形组件,创建成一个能够显示游戏信息框架。在框架中创建一个包含文本区滚动窗格,并在文本区显示游戏信息(图3-2)。图3-
20、2 服务器界面Fig.3-2 Interface of Game-server要建立服务器,需要创建一个服务器Socket,并把它附加到一个端口上,服务器经过这个端口监听连接请求。端口标识Socket上TCP服务。网络类存放在包中,引入包后经过实现一个ServerSocket实例就能够创建一个服务器Socket,并把它附加到一个端口(GAMEPORT)上:ServerSocket serverSocket = new ServerSocket (GAMEPORT);然后,服务器使用下列语句开始监听连接请求:Socket player1 = serverSocket.accept ();Sock
21、et player2 = serverSocket.accept ();服务器开始等候,直到用户提出连接请求。连接建立后,服务器经过数据输入流从用户端接收信息,而且经过数据输出流把对应标识发送给用户端。new DataOutputStream(player1.getOutputStream().writeInt(PLAYER1);new DataOutputStream(player2.getOutputStream().writeInt(PLAYER2);当用户端满足开局条件时,就开启一个线程处理用户之间数据,同时继续监听其它用户端连接请求。多线程是Java一个特点,多线程能够使程序反应愈加
22、快、交互性更强,并能提升实施效率。创建一个新线程生命周期以下状态: 新建,就绪,运行,阻塞,死亡。在Java中,提供了多个控制线程方法,在服务器中用到关键以下多个:public void run ()Java运行系统调用这个方法来实施线程。在用户线程类中,必需覆盖这个方法而且提供线程实施代码。public void start ()该方法开启线程,它引发对run()方法调用。用户类中可运行对象调用该方法。服务器程序采取类HandleGame继承Thread类来实现对线程调用,同时对run ()方法覆盖。 以下是HandleGame () 类里面关键数据域和方法:private char cel
23、l:Char类型数组用来统计玩家标识。private DataInputStream isFromPlayer1;private DataOutputStream osToPlayer1;private DataInputStream isFromPlayer2;private DataOutputStream osToPlayer2;:四个数据流用来实现和两个玩家之间信息传输。public HandleGame (Socket player1, Socket player2):结构函数,两个参数用以接收传输过来Socket对象。public void run():对继承Thread类中run
24、 ()方法进行覆盖。private boolean isFull() :判定是否满格。private boolean isWon(int row,int column,char token):判定新标识单元格是否使一方获胜。游戏局一旦建立起来,服务器便于工作交替地从用户端那里接收数据。从用户端接收到数据后,服务器判定游戏状态,并依据结果进行相关操作,直至游戏结束。4.3 用户端设计和实现用户端负责和玩家交互。所以要创建一个界面,包含一个20*20下棋区域,当玩家选定单元格或接收到别玩家选定单元格时,用不一样标识显示;两个显示游戏名称和游戏状态标签和两个菜单栏上按键用以进行控制,图3-3:图3-
25、3 用户端界面Fig.3-3 Interface of Game-client这里用户程序设计成一个Java Applet,用户能够在Web浏览器里运行。当用户打开GameClient.html文件时,浏览器调用init ()方法对界面进行初始化。点击Start时开启一个线程和服务器连接,经过数据流进行数据交换。connectToServer = new Socket(localhost, GAMEPORT);isFromServer = new DataInputStream(connectToServer.getInputStream();osToServer = new DataOutp
26、utStream(connectToServer.getOutputStream();下面是类GameClient关键方法和数据:public class GameClient extends JApplet implements Runnable, ActionListener, GameConstantsprivate boolean myTurn = false; :标识是否轮到自己下棋 private char myToken = ; :标识自己棋子 private char otherToken = ; :标识对手棋子 private Cell cell = new Cell2020
27、; :生成20*20个单元格 private int rowSelected; :统计所选单元格行 private int columnSelected; :统计所选单元格列 private boolean continueToPlay = true;private boolean waiting = true; :统计游戏进行中状态public void init():初始化用户界面,打开网页时由浏览器调用 public void actionPerformed(ActionEvent e):覆盖ActionListener接口里面actionPerformed ()方法,用来处理用户点击菜
28、单栏引发操作。 public void run()覆盖Runnable接口里run ()方法,用以对游戏过程中数据传输,处理,控制。 在用户程序类中,因为它继承了Applet类,所以不能再经过申明Thread类扩展来实现,只能经过实现Java提供一个Runnable接口,进行线程创建和运行。Runnable接口实现是很简单,它只包含run ()方法,使用时只要将该方法覆盖。从游戏设计来看,单元格是处理鼠标点击事件和显示标识GUI对象。在这里使用是面板,设置单元格Cell为JPanel子类。将Cell类申明为内部类,能够直接使用GameClient类中定义变量和方法,使程序简练明了。Cell类中
29、包含以下关键数据和方法:public class Cell extends JPanel implements MouseListenerprivate int row; private int column; private char token = ; public Cell(int row, int column):结构函数 public void paintComponent(Graphics g):Graphics对象g是由Java运行系统自动创建,这个对象控制信息绘制方法。能够使用定义在Graphics类中多个画法绘制字符串几何图形。 public void mouseClicke
30、d(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseReleased(MouseEvent e) public void mousePressed(MouseEvent e):接口MouseListener中方法。4.4 程序运行首先将编写好程序使用Java编译器编译,生成以class为扩展名类文件,然后使用Java解释器分别运行服务器和用户端。用户端发出连接,服务器接收后开启线程对游戏进行控制,游戏结束时关闭线程。具体步骤图3
31、-4所表示:玩家一1. 初始化用户界面2. 向服务器请求连接,并从服务器获知所用棋子标识。3. 从服务器得到开始标志。4. 等候玩家标识单元格,并向服务器发送单元格行号和列号。5. 从服务器接收游戏状态。6. 假如状态是WIN,显示是胜者,假如玩家二获胜,接收玩家二最终一步走棋信息。中止循环。7. 假如状态是DRAW,显示游戏结束,中止循环。8. 假如状态是CONTINUE,接收玩家二选定单元格行号和列号,标识玩家二选定单元格。服务器创建一个服务器套接字。接收第一个玩家连接请求,而且通知玩家她是玩家一,使用标识“X”。接收第二个玩家连接请求,而且通知玩家她是玩家二,使用标识“O”。开启对局线程
32、。处理对局:1 告诉玩家一开始游戏。2 接收玩家一选定单元格行和列。3 判定游戏状态(STOP,WIN,DRAW,CONTINUE)。假如玩家一退出,向玩家二发送状态(STOP),退出。4 假如玩家一获胜,给两个玩家全部发送状态(PLAYER1_WON),而且向玩家二发送玩家一走棋信息。退出。5 假如状态是CONTINUE,通知玩家二轮她走棋,而且向玩家二发送玩家一最新选定单元格行和列。6 接收玩家二选定单元格行和列。7 假如玩家二退出,向玩家一发送状态(STOP),退出。8 假如玩家二获胜,给两个玩家全部发送状态(PLAYER2_WON),而且向玩家一发送玩家二走棋信息。退出。9 假如状态是
33、CONTINUE,发送状态,而且向玩家一发送玩家二最近选定单元格行和列。玩家二1 初始化用户界面2 向服务器请求连接,并从服务器获知所用棋子标识。3 从服务器接收游戏状态。4 假如状态是WIN,显示是胜者,假如玩家一获胜,接收玩家一最终一步走棋信息。中止循环。5 假如状态是CONTINUE,接收玩家一选定单元格行号和列号,标识玩家一选定单元格。6 等候玩家标识单元格,并向服务器发送单元格行号和列号。图3-4 运行步骤Fig.3-4 Flow Chart5 小结伴随计算机和网络技术不停发展,信息技术给大家带来帮助越来越大,单独一台计算机已经不能满足大家需求,网络正在成为大多数人群生产、生活中密不可分一部分。Java作为一个分布式和可移植计算机语言,在网络软件开发上有着尤其优点。它开发方便、快捷,安全性高,对以往复杂功效,尤其是网络通信等方面,实现起来简练明了,在网络编程领域有着巨大发展潜力。在当今网络经济飞速发展时代,Java技术平台无关性、可重用性、模块化等特点大大降低了反复劳动,不管是开发用于Internet浏览网站还是功效复杂网络应用系统,Java全部能够提供有力支持。相信只要合理地利用Java技术,肯定能够在电子商务、大型网站建设中发挥日益关键作用。