完整版java五子棋毕业课程设计.docx
- 文档编号:9349194
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:23
- 大小:172.68KB
完整版java五子棋毕业课程设计.docx
《完整版java五子棋毕业课程设计.docx》由会员分享,可在线阅读,更多相关《完整版java五子棋毕业课程设计.docx(23页珍藏版)》请在冰豆网上搜索。
完整版java五子棋毕业课程设计
目录
1绪论1
1.1课程设计意义1
1.2课设目的1
1.3课设要求1
2网络五子棋介绍2
2.1网络五子棋介绍2
2.2游戏玩法2
3系统整体设计3
3.1整体设计3
3.2系统流程图4
4原理分析5
4.1服务器和客户端通信机制5
4.2多线程机制7
5服务器的设计与实现8
5.1服务器监听8
5.2传递信息9
6客户端设计与实现10
6.1客户端界面设计11
6.1.1GUI图形界面设计12
6.1.2注册监听者13
6.2连接服务器14
6.3传递信息14
6.4棋盘数据结构15
6.5判断输赢算法16
6.6背景音乐17
7设计实现18
8总结20
谢辞21
参考文献21
1绪论
1.1课程设计意义
五子棋是起源于中国古代的传统黑白棋种之一。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
经过一个学期的学习,使我对Java有了一定的了解。
但要深入理解Java语言,单靠上课是不够的。
必须通过课程设计,设计一个比较大的程序,才能更深一步地理解Java语言。
在这次课程中,我选择了网络五子棋作为课题。
编写网络五子棋游戏要利用到Socket网络编程技术和多线程。
通过这次课程设计,熟悉Java的GUI图形界面设计,网络Socket编程和多线程编程。
1.2课设目的
通过课程设计,使学生理论联系实际,在程序设计实践中进一步了解JAVA程序设计方法掌握类和对象的基本编程方法,熟悉GUI图形界面编程技术,初步了解Socket编程方法。
1.3课设要求
通过课程设计完成一个网络五子棋游戏。
由服务器和客户端组成。
在Internet中不同用户使用客户端通过服务器与其它玩家连接。
进行五子棋网络对战或聊天。
程序中要实现GUI图形界面的棋盘、黑子、白子功能,设计棋局存储数据结构,实现开始、重来、退出等基本功能,实现输赢自动判别算法,实现网络对战功能,背景音乐播放功能等。
2网络五子棋介绍
2.1网络五子棋介绍
五子棋是起源于中国古代的传统黑白棋种之一。
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。
五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源远流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。
它是中西文化的交流点,是古今哲理的结晶。
网络五子棋是一般五子棋的网络版,没有加入人机对战功能。
本软件使两个不同计算机的使用者通过一定的网络连接,达到两人对战的功能。
首先运行服务器监听客户端连接请求。
运行客户端与服务器相连,若连接成功,则进入游戏。
选择房间,一个房间最多两个人,人满后,双方可以开始游戏。
2.2游戏玩法
网络五子棋规则:
棋盘采用15条横线×15条坚线组成交叉的每个点都可以放棋。
本游戏至少需要二个客户端才能进行游戏。
客户端与服务器连接成功后,进入游戏大厅(房间号为0),选择一个大于0的房间号,如果该房间未满,即小于两个人,则可进入。
点“游戏开始”,处于等待状态。
如果对方也点击了“游戏开始”。
双方就可以在网上进行对战了。
在对战的同时还可以聊天,可以在同一房间内私聊,也可以发送消息给所有在线的用户。
游戏分黑白两方,每局由规定黑方先行。
黑方玩家移动鼠标在棋盘中点击行棋。
当黑方行棋完毕,转由白方行棋。
同色棋子在棋盘上形成横、竖、斜形成“五子相连”则获胜。
如果弃权,则判为输。
3系统整体设计
3.1整体设计
网络五子棋是采用网络协议为TCPIP的网上对弈游戏,运用“客户端-服务器“(cs)网络架构模式。
实现用户通过Internt连接在任何地方与不同玩家进行对战。
服务器可以创建任意多局游戏。
通过使用多线程和网络套接字SOCKET来实现游戏之间的通讯,它是基于点对点的通讯。
开始让服务器初始化建立服务器套接字SOCKET,基于某个端口PORT,服务器始终处于监听状态。
客户端是动作的发起者,何时发出申请由客户端决定。
客户端向服务器发出申请,服务器给予响应。
打开客户端套接字SOCKET,连接到服务器端的地址ADDRESS和端口PORT。
连接建立后,创建一个SOCKET实例,并开始一个线程,监听该客户端请求。
服务器继续监听其它用户的连接。
服务器通过数据输入流从客户端接收信息,并且通过数据输出流把相应的信息发送给客户端。
客户端发送请求和响应接收到的各种信息。
在服务器和客户端之间传递的消息格式是采用“[消息类别]+内容“组成的,服务器和客户端在传递消息的过程,根据消息的类别来进行相关的操作。
比如要发送聊天信息,则在客户端发送的过程中,自动加上[MSG]在要发送的消息前面,服务器接收到客户端发来的消息,用startsWith()的方法来读取消息头部,如果等于”[MSG]“,进行一步判定是为群聊还是私聊,分别调用不同的方法向客户端发送聊天内容。
图3-1
3.2系统流程图
服务器流程图:
图1-2
图3-2
客户端流程图:
图3-3
图3-3
4原理分析
4.1服务器和客户端通信机制
Socket是面向客户服务器模型设计的,网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。
Socket通常用来实现客户方和服务方的连接。
客户程序可以向Socket写请求,服务器将处理此请求,然后通过Socket将结果返回给用户。
在java中使用套接字相当简单,JavaAPI为处理套接字的通信提供了一个类.Socket。
使得编写网络应用程序相对容易。
JAVA支持流套接字(streamsocket)和数据报套接字(datagramsocket)。
流套接字使用TCP(TransmissionControlProtocol,传输控制协议)进行数据传输,而数据报套接字使用UDP(UserDatagramProtocol,用户数据报协议)。
图4-1
在Java中Socket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是getOutputStream方法。
getInputStream方法可以得到一个输入流,客户端的Socket对象上的getInputStream方法得到的输入流其实就是从服务器端发回的数据流。
GetOutputStream方法得到一个输出流,客户端Socket对象上的getOutputStream方法返回的输出流就是将要发送到服务器端的数据流,(其实是一个缓冲区,暂时存储将要发送过去的数据)。
客户端启动以后,与服务器连接,服务器会启动一个线程来与客户进行文字交流。
要完成这个工作,需要完成三个部分的工作:
Java中有一个专门用来建立Socket服务器的类,名叫ServerSocket,可以用服务器需要使用的端口号作为参数来创建服务器对象。
ServerSocketserver=newServerSocket(8888);
这条语句创建了一个服务器对象,这个服务器使用8888号端口。
当一个客户端程序建立一个Socket连接,所连接的端口号为8888时,服务器对象server便响应这个连接,并且server.accept()方法会创建一个Socket对象。
服务器端便可以利用这个Socket对象与客户进行通讯。
Socketsocket=server.accept();
进而得到输入流和输出流,并进行封装。
reader=newBufferedReader(newInputStreamReader(socket.getInputStream()));
writer=newPrintWriter(socket.getOutputStream(),true);
随后,就可以使用reader.readLine()方法得到客户端的输入,也可以使用writer.println()方法向客户端发送数据。
从而可以根据程序的需要对客户端的不同请求进行回应。
在所有通讯结束以后应该关闭这两个数据流,关闭的顺序是先关闭输出流,再关闭输入流,即使用
reader.close();
writer.close();
相比服务器端,客户端要简单一些,客户端只需用服务器所在机器的ip以及服务器的端口作为参数创建一个Socket对象。
得到这个对象后,就可以用"建立服务器"部分介绍的方法实现数据的输入和输出。
socket=newSocket("127.0.0.1",8888);
reader=newBufferedReader(newInputStreamReader(socket.getInputStream()));
writer=newPrintWriter(socket.getOutputStream(),true);
以上的程序代码建立了一个socket对象,这个对象连接到ip地址为127.0.0.1(本机IP地址,为了验证方便)的主机、端口为8888的服务器对象。
并且建立了输入流和输出流,分别对应服务器的输出和客户端的写入。
4.2多线程机制
多线程机制是指单个程序可以运行多个不同的线程,执行不同的任务。
因为线程只能在单个进程的作用域内活动,所以创建线程比创建进程要廉价得多,同一类线程共享代码和数据空间,每个线程有独立的运行桟和程序计数器(PC),线程切换的开销小。
因此多线程编程在现代软件设计中在量采用。
创建新线程必须编写一个线程类,用Java编写多线程代码有两种方式
●直接继承Java的线程类Thread;
●实现Runnable接口
无论采用哪种方式均需要在程序中编写Run()方法,线程在运行时要完成的任务在该方法实现。
Thread类封装了线程的行为。
继承Thread类须重写run()方法实现各自的任务。
程序中不要直接调用线程的run()方法,而是调用start()方法启动线程,让其进入可调度的状态,线程获得调度时将自动执行run()方法。
由于Java的单重继承的限制,有些类必须继承其它个类时又要实现线程的特性。
这时可通过实现Runnable接口的方式来满足两方面的要求。
Runnable接口只有一个方法run(),它就是线程运行时要执行的方法,只要将具体代码写入其中即可。
线程在调度时将自动调用Runnable接口对象的run方法。
多线程是Java的一个特点,多线程可以使程序反应更快、交互性更强,并能提高执行效率。
在网络五子中如果服务器是单线程的,则只能与一个客户端相连,就失去了网络对战的意义了。
所以应该采用多线程方式。
当服务器与一个客户端建立连接,就开启一个线程与之相连,同时监听其它用户的连接。
5服务器的设计与实现
网络五子棋游戏服务器端主要由以下几部分组成:
图5-1
图5-1
网络五子棋游戏服务器端主要有三个类:
Server类、five_Thread类(线程类)和BManager类(消息广播者)。
服务器端主要通过建立流连接来连接客户端。
服务器建立与一个客户端连接,就开始一个线程,并同时监听其它客户端的连接。
服务器接收一客户端的信息,接收信息后按照此客户端的要求将信息发送到相应的客户端,端起到了中介服务器的作用。
为了更清楚地了解客户端的登陆情况,将服务器设计成图形界面。
创建成一个可以显示游戏信息的框架。
在框架中创建一个包含文本区的滚动窗格,并在文本区显示游戏信息。
图5-2
5.1服务器监听
首先创建一个服务器对象,并把它附加到8888号端口上,服务通过这个端口来监听客户端的连接请求。
通过服务器对象的accept方法来创建一个Socket对象并使其与客户机连接,就开启一个线程处理客户之间数据,同时继续监听其它客户端的连接请求。
并将线程添加至BManager对象bMan中。
ServerSocketserver=newServerSocket(8888);
Socketsocket=server.accept();
five_Threadthread=newfive_Thread(socket);建立一线程
thread.start();启动线程
bMan.add(thread);线程添加至BManager对象
5.2传递信息
当于客户端建立连接后,就建立输入输出流,由于消息的发送和接收。
reader=newBufferedReader(newInputStreamReader(socket.getInputStream()));
writer=newPrintWriter(socket.getOutputStream(),true);
five_Thread对象不仅可以获取套接字、输入输出流,而且它还提供了有关客户机的消息。
例如客户机的姓名、房间号、游戏开始与否等。
这是因为我们需要确定消息的来源及主要在某个房间传播的消息。
并且,消息广播者也需要参照线程对象的房间号,以便将消息发送至某个房间中。
BManager类继承了Vector类,它的元素为five_Thread线程对象,这样可以更容易用BManager的对象来管理线程对象,如添加、删除、返回线程对象。
BManager可以自由地参照five_Thread对象的房间号和玩家的名字,这样能向指定的房间发送消息和用户名字。
需要比较Bmanager各元素的房间号和给定的房间号,若两者相同,则向此房间发送消息。
服务器和客户端之间的交流主要是相同的房间号之间的用户进行。
如发送聊天消息,棋子信息,赢输消息的传送。
sendToAll(Stringmsg)方法向所有用户发送消息,主要是发送群聊消息。
因为消息的发送主要在相同的房间号中时行,要发送群聊消息,即所有房间的用户都能招收到。
在输入聊天信息前加‘a’。
表示向所有人发送。
SendToRoom(five_Threadthread,Stringmsg)方法用于向指定的房间(roomnum)发送消息(msg)。
房间内的两个用户都能接收到消息。
主要用于发送发私聊信息。
sendTothreadhers(five_Threadthread,Stringmsg)方法用于向与消息发送者处于同一房间的用户发送各种命令。
比如发送在1号房间的一个用户发来“[WIN]“,服务器向1号房间的另一个用户发送[[LOSE]。
实现原理:
使用for循环检查元素(线程)的房间号。
用getRoomNumber()得到发送信息的线程的房间号,当房间号相等时,则调用sendTo(i,msg)方法向第i个房间发送消息。
但并不向thread连接的客户机发送消息。
服务器在five_Thread类中重写run()方法,由于处理在与客户端连接过程中的数据传输,处理和控制。
消息传递格式“[消息类别]+内容“。
“[ROOM]2“表示客户端请求进入第二号房间。
服务器判断2号房间是否为满,如果不为满,则向客户端发送“[ROOM]2”,表示可以进入,并发送ROOM2中的其它用户名字。
如果人数已满,则发送[FULL]。
表示房间已满,无法进入。
“[NAME]“表示进入游戏大厅的用户名字。
“[START]“表示客户端要求开始游戏,如果对方也要求游戏,则游戏开始。
服务器发送[COLOR]WRITE和[COLOR]BLACK表示棋子颜色分别给两个客户端。
“[DROPGAME]”表示放弃正在进行中的游戏。
服务器发送“[DROPGAME]“给相同房间中的另一用户。
6客户端设计与实现
客户端负责与用户之间的交互。
包括棋盘类OmokBoard类和Client类。
OmokBoard类继承了JPanel类,它主要用于棋盘的绘制和监听鼠标事件,获得棋子坐标和绘制棋子。
它必须拥有输出流,用以向对手传递棋手的下棋信息。
主要的方法有:
putOpponent()在客户端显示对方棋子,保持双方棋子的一致性。
check()判断一方向上同色棋子个数。
drawStones()绘制棋子。
drawBoard()调用不同的方法,分析实现棋盘、棋子、提示信息的显示。
isRunning()标记游戏运行状态。
reset()清空棋盘,在游戏结果后运行。
Client类,继承JFrame类和实现Runnable接口。
主要由于界面初始化和注册事件监听者。
主要方法:
Run()方法覆盖Runnable接口里的run()方法,用以对游戏过程中的数据传输,处理,控制。
actionPerformed(ActionEventae)实现点击菜单、按钮、文本框回车事件的具体代码。
Connect()与服务器连接。
endgame()结束游戏。
playersInfo()显示用户位置信息,是在游戏大厅中,还是在房间里。
goToWaitRoom()从房间里退出,进入游戏大厅。
网络五子棋客户端主要由以下几部分组成:
图6-1
图6-1
6.1客户端界面设计
图6-2
6.1.1GUI图形界面设计
五子棋客户端界面本软件的的客户端的界面如图6-2所示,主要应用SWING的组件来实现。
界面由菜单、按钮、文本框、各种对话框、棋盘和黑白棋子等组成。
客户端中的按钮、文本框、标签等GUI部件都是布置在面板JPanel上的,
其中还包括将一块面板入在另一块面板中。
这样能实现比较复杂的布局。
多个不同的GUI部件放在面板上时,还要设置它们的布局方式。
这里采用了网络布局(GridLayout)和方位布局(BorderLayout)。
最后将各个面板JPanel添加到窗体JFrame中。
菜单包括游戏、音乐、和帮助菜单项。
首先创建一个菜单条(MenuBar)jmb,
然后创建不同的菜单项(Menu)加入到菜单条中。
JMenusound=newJMenu("音乐");
jmb.add(sound);
最后创建菜单子项(MenuItem)加入菜单项,比如给“音乐”菜单项添加“播放”菜单子项:
JMenuItemplay=newJMenuItem("播放");
Sound.add(play);
棋盘的绘制。
五子棋盘(OmokBoard类),五子棋盘继承了JPanel,它内嵌于框架窗口中棋盘的大小采用15*15个方格。
每个交叉点处可放置棋子。
privatevoiddrawLine(){
gbuff.setColor(Color.BLACK);
for(inti=1;i<=size;i++){
gbuff.drawLine(cell,i*cell,cell*size,i*cell);
gbuff.drawLine(i*cell,cell,i*cell,cell*size);
}
}
当一个用户放下一个棋子后,同一房间里的两个用户的棋盘都要重画,以显示自己和对方下的棋子等信息。
棋子的绘制。
用白色绘制一个圆形的边框,将填充黑色,这样就画好了一个黑色棋。
位置要根据获得的鼠标点击的坐标和棋盘的大小来定。
privatevoiddrawBlack(intx,inty)绘制黑棋
{
Graphics2Dgbuff=(Graphics2D)this.gbuff;
gbuff.setColor(Color.black);
gbuff.fillOval(x*cell-cell2,y*cell-cell2,cell,cell);
gbuff.setColor(Color.red);
gbuff.drawOval(x*cell-cell2,y*cell-cell2,cell,cell);边框
}
6.1.2注册监听者
图形用户界面的每个可能产生事件的组件称为事件源,希望事件源上发生的事件被程序处理,就要把事件源注册给能够处理该事件源上事件的监听者。
图6-3
在这里按钮,菜单,和发送消息的文本框都是事件源。
要想按钮或菜单发生事件时,程序能处理,必须注册监听者。
按钮动作事件ActionEvent的监听者接口为ActionListener,给按钮注册监听者的方法为addActionListener()。
sendBox.addActionListener(this);文本框按回车键
enterButton.addActionListener(this);
exitButton.addActionListener(this);
在actionPerformed(ActionEventae)中编写上体的事件处理代码。
在发生事件时事件源将给其注册的所有监听者对象的发送消息,实际上就是调用监听者对象的actionPerformed()方法,从而完成事件的处理。
通过getSource()方法:
用来获取事件源对象。
处理不同的事件。
如处理单击“音乐播放”菜单和“游戏开始”引起的事件的actionPerfrmed()方法。
publicvoidactionPerformed(ActionEventae)播放音乐
{if(ae.getSource()==play){
Objectselection[]={"fi.MID","five.mid"};
Objectset=JOptionPane.showInputDialog(null,
"选择音乐...","播放...",JOptionPane.QUESTION_MESSAGE,null,selection,selecton[0]);
music=newSound(set.toString());
music.play();
}
elseif(ae.getSource()==startButton){
try{writer.println("[START]");发送开始信息
infoView.setText("等待对方决定.");
startButton.setEnabled(false);
}catch(Exceptione){}
}
进行五子棋游戏的一个重要的内容是获取鼠标点击时在棋盘中的坐标,即落下棋子的位置。
addMouseListener(newMouseAdapter(){
publicvoidmousePressed(MouseEventme){
if(!
enable)return;是否轮到下棋
intx=(int)Math.round(me.getX()(double)cell);得到鼠标坐标
inty=(int)Math.round(me.getY()(double)cell);
坐标要求不超过棋盘大小,在坐标上不存在棋子
if(x==0||y==0||x==size+1||y==size+1)return;
if(map[x][y]==BLACK||map[x][y]==WHITE)return;
writer.println("[STONE]"+x+""+y);向服务器发送棋子信息
}
6.2连接服务器
客户端连接服务器,首先用服务器所在机器的ip以及服务器的端口作为参数创建一个Socket对象。
客户端调用connect()方法进行连接。
Socket socket=newSocket("127.0.0.1",8888);
这里以本机地址127.0.0.1为IP地址,是为了方便服务器和客户端运行在同一台
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整版 java 五子棋 毕业 课程设计