JAVA网上五子棋游戏设计
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Java 网上五子棋游戏设计
傅伟,吴希忠 来源:www.javathinker.org
一 课程选题背景
在修 WEB 高级开发与应用技术课程之前,我对于 java 语言了解甚少。所以想 通过这次课程的机会,深入系统的学习一下这门语言,同时,学习关系 web 开发 的基础知识。所以我先从语言入手,用 java 编写了这个网上五子棋游戏,作为 我们的课程论文。
void sendToRoom(int roomNum,String msg){ for(int i=0;i<size();i++){ if(roomNum==第 i 个线程的房间号) //向第 i 个线程连接的客户机发送消息 } } }
SendToOthers()方法用于向同房间的其他用户发送消息(msg)这个方法与 SendToRoom()一样,将使用 for 循环检查元素(线程)的房间号。但是,并 不会与 ot 连接的客户机发送消息。
客户机 1 的请求:“[STAERT]” 客户机 2 的请求:“[STAERT]” 服务器的应答:[COLOR]BLACK”与“[CLOR]WHITE
二.服务器端
网络五子棋游戏服务器端主要有三个类:OmokServer 类、Omok_ Thread 类
(线程类)和 BManager 类(消息广播者)。
6
count()方法用来查找并计算连在一起的棋子的个数。P 为基准坐标,dx、dy 分别为表示横向于竖向的变量。col 代表棋子颜色。弱 dx 为-1,dy 为 0,则计算 左边连续棋子的个数;若 dx 为 1,dy 为 1,则计算左下到右上连续棋子的个数。 dx 与 dy 只取-1、0、1 三个值之一。下面是 count()方法的代码。
请看图表 3。假设五个黑子从左向右分别标记为 1、2、3、4、5,那么我们可 以先放置 1、2、3、4 棋子,如果黑方最后一颗棋子 5 号棋放在如图所示的位置, 则黑方在横向上五子连珠,黑方胜。这个过程如何用程序实现呢?在放 5 号棋子 后,首先程序要计算出他左边连在一起的黑色棋子的个数。其左边已放有 2 号与 1 号棋子,且这两颗棋子连在一起,所以 5 号棋子左边相连的黑色棋子有两颗。 然后,再计算 5 号棋子右边连在一起的黑色棋子的个数。如图,5 号棋子右边有 3 号。4 号两颗棋子。因此,5 号棋子左边、右边及 5 号棋子合起来共 5 颗黑色 棋子,黑方获胜。当然在竖直方向与对角线方向上也采取相同的方法进行检查。
间使用 0 以上的自然数来标记。事实上,我们并不时真正创建了房间,而只是将 房间号码赋予了客户机而已。以此,我们可以实现拥有相同号码的客户机彼此间 可以相互通信。
例如,客户机向服务器提出进入某个房间的请求后,服务器必须确认所请求 的房间是否允许它进入,然后,发送相应的请求给客户机。对于消息,我们可以 采用“[消息类型]+内容”的形式。假若客户机想进入 20 号房间,那么,它需要 向服务器发送消息“[ROOM]20”.如果第 20 号房间允许进入,那么,服务器在 进行了某些处理后会向客户机传送消息“[ROOM]20”。相反,若 20 号房间禁止 入内,则服务器将向客户机发送“[NULL]”消息。
二 目标
Java 的广泛流行是与它所编写的程序可以在网络上运行且可以跨平台。事 实上,支持 Java 的浏览器内置 Java 虚拟机,使得 Java 的小程序能够在网络上 完全地传送和运行。这样使得程序人员即使不具备有关的网络知识,也能编写出 高质量的网络通信程序。“网上五子棋游戏”便是其最好的例子。
图表 4 8
在游戏的过程中我们要测试程序是否能够真正达到五子棋的标准,那么我们 就要根据下面的五子棋规则进行参照(图表 5)。
五子棋规则: 1. 五子棋专用盘为 15 条横线×15 条坚线组成,交叉的每个点都可以行棋。 2. 游戏分黑白两方,每局由规定黑方先行。黑方玩家移动鼠标在棋盘中点击
行棋。 3. 当黑方行棋完毕,转由白方行棋。游戏结束后黑白方互换颜色。 4. 禁手是对局中被判为负的行棋手段。白棋无禁手。 胜负判定: 某一方玩家最先在棋盘上形成横、竖、斜连成五连或长连。将获得胜利。
Private Boolean check(point p,int cool)
{
if(count(p,1,0,col)+count(p,-1,0,col)==4)
// 横向检查
return true;
if(count(p,0,1col)+count(p,0,-1,col)==4)
// 竖向检查
return true;
OmokServer 类在受到客户机的连接请求后,将创建新的套接字,并使其与客
户机连接,然后启动线程,并将线程添加至 BManager 对象中。
Private BManager bMan=new BManager();
//消息广播者对象
...........
While(true){
Socket socket=server.accept();
此时我们可以在待机室中分别看到这两个客户的名字,在等待两名客户分别 输入房间号后,他们就可以进入该房间。如果这两个用户输入的房间号相同,那 么他们就可以分别点击“开始对决”正式进入游戏状态。当一名用户输掉比赛或 者认输后,用户可以点击“弃权”键结束游戏,此时用户可以自由选择重新开始 或者再次进入待机室。(图表 4)
图表 5
和局判定: 1. 对局双方一致同意和棋。 2. 全盘已下满,无空白交叉点。 经过我的测试后,程序能够正常运行,并无任何错误
9
Private int count(Point p,int dx,int dy,int col) { int i=0; for(;map[p.x+(i+1)*dx][p.y+(i+1)*dy]==col;i++)
{} return i; }
check()方法会调用 count()方法,用来判断是否五子连珠。其代码如下。
本程序是一个基于网络协议为 TCP/IP 的网上对弈游戏,采用服务器-客户端 的网络架构模式,允许网络上的多台机器(可能是两台机器)同时运行,一台用作 服务器,始终处理网络上要求它进行服务的请求。如果有机器请求与它进行连接, 用作服务器的机器接受之后就可以进行相互之间的通信。
通过本程序,我们初步熟悉并掌握 java 语言的基本知识,掌握服务器-客户 端的网络架构模式,为以后学习高级 web 开发课程做准备。
BManager 类继承了 Vector 类,它的元素为 Omok_ Thread 线程对象,这样 才能自由地参照 Omok_ Threadd 对象的房间号及玩家的名字等。为了实现向指定 的房间发送消息,需要比较 Bmanager 各元素的房间号和给定的房间号,若两者 相同,则向此房间发送消息。
SendToRoom()方法用于向指定的房间(roomnum)发送消息(msg),代码如下。
3
客户机请求:[ROOM]20 服务器的应答:[ROOM]20,或[NULL]
又例如,假设两个玩家同时进入某个房间,要进行对弈。首先,一名玩家点 击开始按钮,向服务器发送“[STAERT]”消息,另一名玩家也向服务器发送了 “[STAERT]”消息,然后服务器将会认为这两名玩家要进行对弈,它会随时向 玩家指派棋子,并分别向玩家发送“[COLOR]BLACK”与“[CLOR]WHITE”消 息。
5
服务器的负担,消息的传播将变得十分缓慢。 三. 客户端
首先要实现五子棋盘(OmokBoard 类)。五子棋盘继承了画布类,它内嵌于 框架窗口中,拥有 15*15(255)个方格。为了响应用户的下棋动作,五子棋盘 必须能够响应鼠标事件。并且它必须拥有输出流,用以向对手传递棋手的下棋信 息。程序中也有多种方法用来实现绘图操作。然而,程序中最重要的部分时如何 决定胜负。横,竖或者对角线方向上拥有五颗同样的棋子时,即为胜利。
if(count(p,-1,-1,col)+count(p,1,1col)==4)
// 对角线方向检查
return true;
if(count(p,1,-1,col)+count(p,-1,1,col)==4) // 对角线方向检查
return true; }
若用户将 color 颜色的棋子放在(x,y)位置上,程序将会进行如下检查。如
三 总体构架
我们通过使用套接字 SOCKET 来实现游戏之间的通讯,它是基于点对点的通 讯,开始让服务器初始化建立服务器套接字 SOCKET,基于某个端口 PORT,然后 打开客户端套接字 SOCKET,连接到服务器端的地址 ADDRESS 和端口 PORT,在这 之间可能发生异常 EXCEPTION。
//获取套接字
Omok_Thread ot=new Omok_Thread(socket);
//创建线程
ot.start();
//启动线程
bMan.add(ot);
//添加线程
...........
}
4
Omok_Thread 对象不仅可以获取套接字、输入输出流,而且它还提供了有关 客户机的消息。例如客户机的姓名、房间号、游戏开始与否等。这是因为我们需 要确定消息的来源及主要在某个房间传播的消息。并且,消息广播者也需要参照 线程对象的房间号,以便将消息发送至某个房间中。
“网络五子棋”是由服务器端和客户端组成的。游戏分为黑方与白方,只要 其中一方的棋子形成“五子连珠”之势,即可获胜。
1
服
务
器 网
端 络
五
子
客
棋
户
端
网络五子棋游戏服务器端主要有三个类:OmokServer 类、Omok_ Thread 类 (线程类)和 BManager 类(消息广播者)。它的主要功能是连接客户端,使多 个客户端连接在一起,最终实现联网。
图表 1 服务器端
2
网络五子棋游戏客户端主要是实现五子棋的界面和功能的程序,我们可以通 过服务器端连接多个客户端实现最终游戏的目的。
Hale Waihona Puke Baidu
四 技术要点
图表 2 客户端
一.创建待机室 该游戏创建了待机室,供其他未处于下棋状态的人们使用,也可以创建另一
个房间,供下棋的两个人使用。 我们可以通过标记号码来区分待机室与下棋室。即用 0 标记待机室,其他房
果获胜,则向服务器发送“[WIN]”消息。同时,服务器也会向其对手发送“[LOSE]”
消息。
Map[x][y]=color;
If(check(new Point(x,y),color))
{writer.println(“[WIN]”);
7
}
五 成果与测试
假设 OmokServer.java 与 OmokClient.java 都存放在 C 盘根目录下,那么我 们可以根据以下步骤运行及测试游戏。 1、在 DOS 窗口中输入 C:\javac OmokServer.java 运行服务器端。 2、在 DOS 窗口中输入 C:\javac OmokClient.java 运行第一个客户端。 3、在 DOS 窗口中再次输入 C:\javac OmokClient.java 运行第二个客户端。 4、在第一个客户端输入有效的姓名后,点击“去待机室”进入等待状态。 5、第二个客户端输入有效的姓名后,点击“去待机室”也进入等待状态。
图表 3
Map 是一个二元数组,用于保存棋子的位置。如果在(2,3)位置上有一颗 黑色棋子,则向数组元素 map[2][3]赋入常数 BLACK(=1);则将 WHITE(=-1)值 代入。并且,如果某个五子棋盘左上端坐标就变为(1,1),而非(0,0)。
为了计算方便,我这里将 map 的大小定义为 17*17,而并非是先前的 15*15。 因此,五子棋盘左上就坐标就变为(1,1),而非(0,0)
void sendToOthers(Omok_Thread ot,String msg){ for(int i=0;i<size();i++){ if(第 i 个线程的房间号==ot 的房间号&&第 i 个线程!=ot){
} } }
sendToRoom()与 sendToOthers()方法的不足之处在于,房间越多,它们就会增重
傅伟,吴希忠 来源:www.javathinker.org
一 课程选题背景
在修 WEB 高级开发与应用技术课程之前,我对于 java 语言了解甚少。所以想 通过这次课程的机会,深入系统的学习一下这门语言,同时,学习关系 web 开发 的基础知识。所以我先从语言入手,用 java 编写了这个网上五子棋游戏,作为 我们的课程论文。
void sendToRoom(int roomNum,String msg){ for(int i=0;i<size();i++){ if(roomNum==第 i 个线程的房间号) //向第 i 个线程连接的客户机发送消息 } } }
SendToOthers()方法用于向同房间的其他用户发送消息(msg)这个方法与 SendToRoom()一样,将使用 for 循环检查元素(线程)的房间号。但是,并 不会与 ot 连接的客户机发送消息。
客户机 1 的请求:“[STAERT]” 客户机 2 的请求:“[STAERT]” 服务器的应答:[COLOR]BLACK”与“[CLOR]WHITE
二.服务器端
网络五子棋游戏服务器端主要有三个类:OmokServer 类、Omok_ Thread 类
(线程类)和 BManager 类(消息广播者)。
6
count()方法用来查找并计算连在一起的棋子的个数。P 为基准坐标,dx、dy 分别为表示横向于竖向的变量。col 代表棋子颜色。弱 dx 为-1,dy 为 0,则计算 左边连续棋子的个数;若 dx 为 1,dy 为 1,则计算左下到右上连续棋子的个数。 dx 与 dy 只取-1、0、1 三个值之一。下面是 count()方法的代码。
请看图表 3。假设五个黑子从左向右分别标记为 1、2、3、4、5,那么我们可 以先放置 1、2、3、4 棋子,如果黑方最后一颗棋子 5 号棋放在如图所示的位置, 则黑方在横向上五子连珠,黑方胜。这个过程如何用程序实现呢?在放 5 号棋子 后,首先程序要计算出他左边连在一起的黑色棋子的个数。其左边已放有 2 号与 1 号棋子,且这两颗棋子连在一起,所以 5 号棋子左边相连的黑色棋子有两颗。 然后,再计算 5 号棋子右边连在一起的黑色棋子的个数。如图,5 号棋子右边有 3 号。4 号两颗棋子。因此,5 号棋子左边、右边及 5 号棋子合起来共 5 颗黑色 棋子,黑方获胜。当然在竖直方向与对角线方向上也采取相同的方法进行检查。
间使用 0 以上的自然数来标记。事实上,我们并不时真正创建了房间,而只是将 房间号码赋予了客户机而已。以此,我们可以实现拥有相同号码的客户机彼此间 可以相互通信。
例如,客户机向服务器提出进入某个房间的请求后,服务器必须确认所请求 的房间是否允许它进入,然后,发送相应的请求给客户机。对于消息,我们可以 采用“[消息类型]+内容”的形式。假若客户机想进入 20 号房间,那么,它需要 向服务器发送消息“[ROOM]20”.如果第 20 号房间允许进入,那么,服务器在 进行了某些处理后会向客户机传送消息“[ROOM]20”。相反,若 20 号房间禁止 入内,则服务器将向客户机发送“[NULL]”消息。
二 目标
Java 的广泛流行是与它所编写的程序可以在网络上运行且可以跨平台。事 实上,支持 Java 的浏览器内置 Java 虚拟机,使得 Java 的小程序能够在网络上 完全地传送和运行。这样使得程序人员即使不具备有关的网络知识,也能编写出 高质量的网络通信程序。“网上五子棋游戏”便是其最好的例子。
图表 4 8
在游戏的过程中我们要测试程序是否能够真正达到五子棋的标准,那么我们 就要根据下面的五子棋规则进行参照(图表 5)。
五子棋规则: 1. 五子棋专用盘为 15 条横线×15 条坚线组成,交叉的每个点都可以行棋。 2. 游戏分黑白两方,每局由规定黑方先行。黑方玩家移动鼠标在棋盘中点击
行棋。 3. 当黑方行棋完毕,转由白方行棋。游戏结束后黑白方互换颜色。 4. 禁手是对局中被判为负的行棋手段。白棋无禁手。 胜负判定: 某一方玩家最先在棋盘上形成横、竖、斜连成五连或长连。将获得胜利。
Private Boolean check(point p,int cool)
{
if(count(p,1,0,col)+count(p,-1,0,col)==4)
// 横向检查
return true;
if(count(p,0,1col)+count(p,0,-1,col)==4)
// 竖向检查
return true;
OmokServer 类在受到客户机的连接请求后,将创建新的套接字,并使其与客
户机连接,然后启动线程,并将线程添加至 BManager 对象中。
Private BManager bMan=new BManager();
//消息广播者对象
...........
While(true){
Socket socket=server.accept();
此时我们可以在待机室中分别看到这两个客户的名字,在等待两名客户分别 输入房间号后,他们就可以进入该房间。如果这两个用户输入的房间号相同,那 么他们就可以分别点击“开始对决”正式进入游戏状态。当一名用户输掉比赛或 者认输后,用户可以点击“弃权”键结束游戏,此时用户可以自由选择重新开始 或者再次进入待机室。(图表 4)
图表 5
和局判定: 1. 对局双方一致同意和棋。 2. 全盘已下满,无空白交叉点。 经过我的测试后,程序能够正常运行,并无任何错误
9
Private int count(Point p,int dx,int dy,int col) { int i=0; for(;map[p.x+(i+1)*dx][p.y+(i+1)*dy]==col;i++)
{} return i; }
check()方法会调用 count()方法,用来判断是否五子连珠。其代码如下。
本程序是一个基于网络协议为 TCP/IP 的网上对弈游戏,采用服务器-客户端 的网络架构模式,允许网络上的多台机器(可能是两台机器)同时运行,一台用作 服务器,始终处理网络上要求它进行服务的请求。如果有机器请求与它进行连接, 用作服务器的机器接受之后就可以进行相互之间的通信。
通过本程序,我们初步熟悉并掌握 java 语言的基本知识,掌握服务器-客户 端的网络架构模式,为以后学习高级 web 开发课程做准备。
BManager 类继承了 Vector 类,它的元素为 Omok_ Thread 线程对象,这样 才能自由地参照 Omok_ Threadd 对象的房间号及玩家的名字等。为了实现向指定 的房间发送消息,需要比较 Bmanager 各元素的房间号和给定的房间号,若两者 相同,则向此房间发送消息。
SendToRoom()方法用于向指定的房间(roomnum)发送消息(msg),代码如下。
3
客户机请求:[ROOM]20 服务器的应答:[ROOM]20,或[NULL]
又例如,假设两个玩家同时进入某个房间,要进行对弈。首先,一名玩家点 击开始按钮,向服务器发送“[STAERT]”消息,另一名玩家也向服务器发送了 “[STAERT]”消息,然后服务器将会认为这两名玩家要进行对弈,它会随时向 玩家指派棋子,并分别向玩家发送“[COLOR]BLACK”与“[CLOR]WHITE”消 息。
5
服务器的负担,消息的传播将变得十分缓慢。 三. 客户端
首先要实现五子棋盘(OmokBoard 类)。五子棋盘继承了画布类,它内嵌于 框架窗口中,拥有 15*15(255)个方格。为了响应用户的下棋动作,五子棋盘 必须能够响应鼠标事件。并且它必须拥有输出流,用以向对手传递棋手的下棋信 息。程序中也有多种方法用来实现绘图操作。然而,程序中最重要的部分时如何 决定胜负。横,竖或者对角线方向上拥有五颗同样的棋子时,即为胜利。
if(count(p,-1,-1,col)+count(p,1,1col)==4)
// 对角线方向检查
return true;
if(count(p,1,-1,col)+count(p,-1,1,col)==4) // 对角线方向检查
return true; }
若用户将 color 颜色的棋子放在(x,y)位置上,程序将会进行如下检查。如
三 总体构架
我们通过使用套接字 SOCKET 来实现游戏之间的通讯,它是基于点对点的通 讯,开始让服务器初始化建立服务器套接字 SOCKET,基于某个端口 PORT,然后 打开客户端套接字 SOCKET,连接到服务器端的地址 ADDRESS 和端口 PORT,在这 之间可能发生异常 EXCEPTION。
//获取套接字
Omok_Thread ot=new Omok_Thread(socket);
//创建线程
ot.start();
//启动线程
bMan.add(ot);
//添加线程
...........
}
4
Omok_Thread 对象不仅可以获取套接字、输入输出流,而且它还提供了有关 客户机的消息。例如客户机的姓名、房间号、游戏开始与否等。这是因为我们需 要确定消息的来源及主要在某个房间传播的消息。并且,消息广播者也需要参照 线程对象的房间号,以便将消息发送至某个房间中。
“网络五子棋”是由服务器端和客户端组成的。游戏分为黑方与白方,只要 其中一方的棋子形成“五子连珠”之势,即可获胜。
1
服
务
器 网
端 络
五
子
客
棋
户
端
网络五子棋游戏服务器端主要有三个类:OmokServer 类、Omok_ Thread 类 (线程类)和 BManager 类(消息广播者)。它的主要功能是连接客户端,使多 个客户端连接在一起,最终实现联网。
图表 1 服务器端
2
网络五子棋游戏客户端主要是实现五子棋的界面和功能的程序,我们可以通 过服务器端连接多个客户端实现最终游戏的目的。
Hale Waihona Puke Baidu
四 技术要点
图表 2 客户端
一.创建待机室 该游戏创建了待机室,供其他未处于下棋状态的人们使用,也可以创建另一
个房间,供下棋的两个人使用。 我们可以通过标记号码来区分待机室与下棋室。即用 0 标记待机室,其他房
果获胜,则向服务器发送“[WIN]”消息。同时,服务器也会向其对手发送“[LOSE]”
消息。
Map[x][y]=color;
If(check(new Point(x,y),color))
{writer.println(“[WIN]”);
7
}
五 成果与测试
假设 OmokServer.java 与 OmokClient.java 都存放在 C 盘根目录下,那么我 们可以根据以下步骤运行及测试游戏。 1、在 DOS 窗口中输入 C:\javac OmokServer.java 运行服务器端。 2、在 DOS 窗口中输入 C:\javac OmokClient.java 运行第一个客户端。 3、在 DOS 窗口中再次输入 C:\javac OmokClient.java 运行第二个客户端。 4、在第一个客户端输入有效的姓名后,点击“去待机室”进入等待状态。 5、第二个客户端输入有效的姓名后,点击“去待机室”也进入等待状态。
图表 3
Map 是一个二元数组,用于保存棋子的位置。如果在(2,3)位置上有一颗 黑色棋子,则向数组元素 map[2][3]赋入常数 BLACK(=1);则将 WHITE(=-1)值 代入。并且,如果某个五子棋盘左上端坐标就变为(1,1),而非(0,0)。
为了计算方便,我这里将 map 的大小定义为 17*17,而并非是先前的 15*15。 因此,五子棋盘左上就坐标就变为(1,1),而非(0,0)
void sendToOthers(Omok_Thread ot,String msg){ for(int i=0;i<size();i++){ if(第 i 个线程的房间号==ot 的房间号&&第 i 个线程!=ot){
} } }
sendToRoom()与 sendToOthers()方法的不足之处在于,房间越多,它们就会增重