logo资料库

网络课程设计 Java五子棋网络版.doc

第1页 / 共18页
第2页 / 共18页
第3页 / 共18页
第4页 / 共18页
第5页 / 共18页
第6页 / 共18页
第7页 / 共18页
第8页 / 共18页
资料共18页,剩余部分请下载后查看
计算机网络课程设计 石河子大学信息科学与技术学院 计算机网络课程设计 课题名称: Java 网络版五子棋游戏 学生姓名: 廖树婷 学 院 专 班 号: 系: 业: 级: 2009082205 信息科学与技术学院 计算机科学与技术专业 09 级 1 班 指导教师: 马洪亮老师 完成时间: 2012 年 1 月 4 日 第 1页 共 18页
计算机网络课程设计 1、 题目及要求 1.1 题目: Java 网络版五子棋游戏 1.2 要求: 1) 用 Java 实现五子棋游戏 2) 运用所学的 TCP 知识,实现端到端联机五子棋游戏。 2、 功能设计(功能模块及模块图) 本五子棋为双方对弈。游戏开启后,点击“开始”按钮,开始游戏。等待 对方开始。双方都开始后,先点击“开始”的玩家先落子。鼠标点击要下棋子 的位置,下棋,并在双方棋盘上显示。双方可在游戏未结束前以及对方未落子 前悔棋。五子连成一条线(4 个方向都可)即成功。关闭游戏则退出。 五子棋: 包括棋子类、棋盘类、游戏类、画图类、每步类。 网络传输: NetGame 用于游戏消息的传输。CreateGame 用于建立游戏的服务端和客户端的 socket 套接字。ChessMessage 游戏的消息,用于传输使用。 ServiceMain/ClientMain 创建客户端、服务器端的创建。 3、 详细设计 3.1 设计方法;各功能模块主要关键技术的运用,计算公式,实现方法, (文字表述) 1) 棋子类 Chessman 只有一个属性:棋子的颜色 color。还定义了两个常量白棋颜 色为-1,黑棋颜色为 1。 2) 存储每步的类 Step:下子的坐标 x、y 及棋子 Chessman。 3) 棋 盘 类 Board 中 有 棋 子 、 棋 盘 的 矩 阵 board[15][15] 、 每 步 的 链 表 集 合 LinkedList(用于悔棋)。 以及下棋子的方法 playChess(Step step),悔棋的方法 back(),判断输赢的方 法 isWin(int x,int y)。 1.playChess(Step step)此方法用于下棋,判断传来的 step 的位置是否可以落 子,若不能返回 false,可以落子就将当前落子的这一步加入记录“每步”的链 第 1页 共 18页
计算机网络课程设计 表中去,将棋子颜色填入相应棋盘矩阵中。 2.back()悔棋,去除 Step 中最后一条记录,并将此步对应的矩阵上的坐标改回 0. 3.isWin(int x,int y)判断输赢,当前子所在的 4 个方向上(横竖撇那)进行 遍历,判断该子是否已连成 5 子。 4) 游戏类 Game,本类中有开始、结束标志、当前走棋的颜色、本地棋子颜色、棋 盘对象,本类的方法: 1.start(int color)游戏开始,设置传来的颜色为本机开始游戏的颜色。 2.playChess(int x, int y,int color) 先判断越界,然后判断下的棋子颜色 是否等于当前要走的子颜色,若相等就将棋子坐标、颜色封装成 Step,调用 board 的方法加入这一步。再调用 board 的 isWin()判读这一步是否赢。未赢则改变要下 子的颜色。 3.back()调用棋盘类悔棋的方法,且改变棋子颜色(悔棋不换色) 5) DrawGame 绘制游戏类。本类主要用于绘制棋盘。继承 JFrame 类,用到其中的 绘制面板、按钮等方法. 1.内部类 BoardPanel,paintComponent 方法为 BoardPanel 的重载方法,用于 绘制棋盘的实时落子情况。 2. localPlayChess()用于下本地棋子。 3. netPlayChess()用于网络传来的子下到本地。 6) NetGame 用于传输双方的棋子,响应本地棋子的消息,向本地发送对方传来的 棋子。 1. 初始化创建 DrawGame 画游戏,将传来的套接字的信道初始化。 2. 内部类 Service 用于实时刷新传来数据的信道 ObjectInputStream, 并判 断传来的消息是那类数据,并调用网络相关方法处理。 3. 响应 DrawGame 类点击棋盘的方法,接受消息,并调用本地相关方法处理。 7) CreateGame 用于区分服务端和客户端,本游戏用 TCP 传输,所以服务端设置接 收端口,客户端设置发送的 IP 及端口。创建套接字,创建游戏。 3.2 各功能模块程序的流程图; 第 2页 共 18页
计算机网络课程设计 服 务 器 端 传递消息 传递消息 客 户 端 点击开始按钮, 本地设为已开始 接受到“开 始”消息 对方是否开始 No 发送”开始”消息 Yes 本地是否开始 No 等待本机开始 等待传来的开始 游戏开始 3.3 本设计的重点、难点及解决方法。 1) Board 中的 isWin()方法:判断输赢,之前写了一个很长的判断该子是否连成 5 子的方法,但是没有这样写的简单,运用到的算法如下 定义如下数组: int[][] fx = { {0,-1}, {1,-1}, {1,0}, {1,1} //上 //右斜上 //右 //右斜下 }; 首先对四个方向遍历,正向、反向寻找,若坐标上有棋子,并且颜色与检查 点坐标相同,则记录加一,直到记录到5。 2) 网络开始功能,如流程图所绘制的,需要双方都开始,游戏才能开始。因此设 置了两个变量localStart和netStart。 3) 网络传输功能,在做此功能时,由于内部类Service没有将它实例化,线程也没 有启动。所以传输过来的消息没办法收到。但若在CreateGame中创建NetGame时 就实例化内部类,则画图的类就调用不出来,导致程序无法运行。最后我是将内 第 3页 共 18页
计算机网络课程设计 部类放到创建客户端的类ClientMain中,这样就可以先绘图,后收消息了。 4) 最难的问题是,之前做此游戏,我是将创建socket、画图放在fiveGame类中, 并创建NetGame来创建游戏,在fiveGame中可以响应本机的消息(下子、开始、 悔棋)并传到NetGame中。NetGame也接受对方传来的消息。但是,当接收到了消 息,没办法传给创建它的fiveGame类,通知它重绘。所以一直停留在这个问题上 没法继续做下去。最后终于想到了一个办法,让绘图类下移一层,放到game、 NetGame 之间。绘图类拥有Game,本机消息可有创建绘图类的NetGame类响应, 网络上传来的消息也可以通过NetGame类发送给DrawGame类响应和重绘。 4、 总结 游戏截图 本次课程设计是我做的时间最长的一个课程设计,历时两个月。期间用了很多 方法,最初我是想做一个类似 CS 局域网的联机模式的五子棋,可多人、多组进行。 但是做到最后,却只能用最简单的客户端服务器模式进行,因为时间不够了,但是 这个五子棋游戏很容易扩展,如果想做成 CS 局域网版的也很容易,用 UDP 协议寻 找局域网的主机,响应并愿意连接的主机发回数据包,开始游戏时在建立 TCP 传输 游戏之间的消息。无论服务器、客户端游戏都具有自我判断的能力,利用网络只需 传输消息。还有一种版本就是服务器同一判断输赢、传输消息,各客户端负责接受、 发送消息给服务器。但是最后在实现过程中,游戏架构设计的偏差使得类之间的调 第 4页 共 18页
计算机网络课程设计 用出现问题。原先设计的是创建网络和游戏的 FiveGame 类,创建 Game 上转成 NetGame,再在 NetGame 里连接,FiveGame 还创建了游戏用到的画图功能,可将本 机传来的消息发送到 Game 中。但是对方发来的消息在 NetGame 中,无法通知创建 它的 FiveGame 类。所以后来舍弃这样的设计。 在游戏实现方面,由于架构开始设计就错了,因此出现了多次返工,最终的版 本利于扩展,结构清晰。所以对这个小游戏还是挺满意的。学到了很多东西。而后 对于网络方面的扩展也易于实现,只需要将网络部分写到 NetGame 中,就可实现所 需的传输模式。 5、 参考 百度、csdn、JDK6.0 手册 6、 附:源程序。 /** * 棋子对象 * * 棋子就有一个属性:颜色 * */ public class Chessman { //为了方便用户使用,定义两个常量 public static final int COLOR_WHITE=-1; public static final int COLOR_BLACK=1; private int color; // public Chessman(int color){ this.color = color; } public int getColor() { return color; } public void setColor(int color) { this.color = color; } } /** * 步骤对象 */ public class Step { private Chessman chessman; private int x; private int y; 第 5页 共 18页
计算机网络课程设计 public Step(Chessman chessman, int x, int y) { super(); this.chessman = chessman; this.x = x; this.y = y; } public Chessman getChessman() { return chessman; } public void setChessman(Chessman chessman) { this.chessman = chessman; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } } import java.util.LinkedList; /** * 棋盘对象 * * */ public class Board { private int[][] board = new int[15][15];//和图片上格子相同 private LinkedList stepList = new LinkedList(); //用集合保存步骤, 所以用泛型,类型为Step //走棋的方法,走过的地方不能走棋 public boolean playChess(Step step/*因为棋子坐标都封装在了Step中*/){ //集合中默认的都是0,0表示没有棋子 if(board[step.getY()][step.getX()]!=0){//不是0,说明有棋子,返回false,不让走 棋 return false; } //没有棋子就走棋,并且得到棋子的颜色 board[step.getY()][step.getX()] = step.getChessman().getColor(); 第 6页 共 18页
计算机网络课程设计 stepList.add(step); return true; } public Step back(){ //悔棋方法 try{ Step step = stepList.removeLast()/*这个方法会抛出异常*/;//最后一步的位置 移除 board[step.getY()][step.getX()] = 0;//把当前位置置零 return step; }catch(Exception e){ return null; } } public boolean isWin(int x,int y){ int[][] fx = { {0,-1}, {1,-1}, {1,0}, {1,1} //上 //右斜上 //右 //右斜下 }; int chess = board[y][x]; for(int i=0;i=-1;j-=2){ for(int k=1;k<=4;k++){ //正向,反向两次 //偏移多少位 int dx = x + (fx[i][0]*j*k); int dy = y + (fx[i][1]*j*k); if(dx < 0||dy<0||dx>=board[0].length||dy>=board.length){ continue fxLoop; } if(chess == board[dy][dx]){ count++; if(count==5){ return true; } }else{ continue fxLoop; } 第 7页 共 18页 } } }
分享到:
收藏