目 录
第一章 绪论.................................. 3
1.1 课题背景.................................. 3
1.2 开发目的.................................. 3
1.3 开发意义.................................. 3
第二章 需求分析............................. 3
2.1 可行性研究................................ 3
2.2需求分析.................................. 4
2.2.1功能需求............................... 4
2.2.2 环境需求.............................. 4
第三章总体设计............................... 4
3.1 系统设计思想............................... 4
3.2 系统总体设计............................... 5
3.3 游戏截图................................... 5
第四章 程序源代码............................. 6
第五章工作总结.............................. 18
致 谢...................................... 19
参考文献.................................... 19
摘 要
目前,以计算机技术和网络技术为核心的现代网络技术已在现实生活和生产中得以广泛的使用,休闲类网络游戏集趣味性,娱乐性,互动性和益智性于一体,已经成为多数人群的休闲方式。本程序是VC平台下的一个小程序,使用C++语言,基于MFC类库,所有的类均继承于MFC类库,通过对Socket技术理解,实现在局域网内客户端和服务器之间的连接,通信,以及处理信息字段来获取具体的信息类型和和内容,以实现程序的聊天内容,图形加载,主机连接,以及五子棋核心进程之间的通信。
关键词:MFC,Socket,客户端,服务器
第一章 绪论
1.1 课题背景
五子棋是起源于中国古代的传统黑白棋种之一。现代五子棋日文称之为“連珠”,英译为“Renju”,英文称之为“Gobang”或“FIR”(Five in a Row的缩写),亦有“连五子”、“五子连”、“串珠”、“五目”、“五目碰”、“五格”等多种称谓。
1.2 开发目的
为了迎合广大五子棋爱好者的需求和交流,设计出一款基于网络版的五子棋游戏,玩家可以通过网络挑选自己喜爱的对手并同其进行比赛,比赛过程中可以进行聊天,达到相互交流经验的作用,使其不仅能够进行比赛,同时也能达到交友的功能。
1.3 开发意义
五子棋不仅能增强思维能力,提高智力,而且富含哲理,有助于修身养性。五子棋既有现代休闲的明显特征“短、平、快”,又有古典哲学的高深学问“阴阳易理”;它既有简单易学的特性,为人民群众所喜闻乐见,又有深奥的技巧和高水平的国际性比赛;它的棋文化源渊流长,具有东方的神秘和西方的直观;既有“场”的概念,亦有“点”的连接。它是中西文化的交流点,是古今哲理的结晶。
第二章 需求分析
2.1 可行性研究
在很早以前五子棋软件就已经被开发出来了,当时的五子棋软件仅提供了“人机模式”与“双人模式”。“人机模式”是指,人与计算机进行对弈,计算机按照事先编写好的算法程序来进行下棋;“双人模式”是指,两个人通过交替使用同一台计算机来进行下棋。无论是选择哪一种模式,所有的操作都必须在同一台计算机上来往完成,棋局无法在异地计算机之间来进行,故而也叫单机版五子棋软件。
2.2需求分析
2.2.1功能需求
l 能通过网络进行下棋
l 符合五子棋的基本规则
l 提供水平坐标和垂直坐标功能
2.2.2 环境需求
l 10/10Mbps共享式HUB一台
l 装有Windows95/98/NT/XP操作系统的计算机两台
l 计算机的CPU不低于PII450,内存不小于64M
l 每台计算机都应配置有TCP/IP协议
第三章总体设计
3.1 系统设计思想
本系统的功能能够实现一个在网络上供客户进行对战的五子棋网络游戏,客户只要登陆到服务器上,就能选择任何其它用户已创建好的游戏,进行五子棋对战游戏,是C/S 模式的网络游戏。在C/S 模式游戏中,Server 一般提供所有用户的全局信息,并能提供客户之间的信息转发,客户之间的通讯必须通过Server进行。因为在多个客户能够连接到同一台Server上,所以Server必须用Thread 负责每个用户的通讯和消息处理。
服务端程序通过一个Thread 监听客户端的连接,一旦客户连接,为该客户建立连接并启动一个特定的客户thread,利用该连接不断从客户读取数据,实现客户和服务器或者客户与客户之间的信息的交互。
3.2 系统总体设计
系统使用Socket 技术以及VC 多线程机制结合在进行客户与服务端之间信息的交互,但一个真正实用程序必须针对具体应用定制一套协议用于用户程序之间进行交互,而该协议的定制往往是编写程序的关键也是核心内容,该协议的完善决定程序是否能够正常运行。所谓协议就是程序之间交互的信息的格式规定, 服务端和客户端都遵循该协议才能够进行对话, 通俗讲是人类之间的语言。
3.3 游戏截图
图1开始画面
图2黑子赢了
第四章 程序源代码
package wuziqi1;
import java.applet.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.Color;
import java.awt.event.*;
publicclass wuziqi extends Applet implements ActionListener,MouseListener,
MouseMotionListener,ItemListener
{
int color_Qizi=0;/////////////////////////////旗子的颜色标识 0:白子 1:黑子
int gamestart=0;///////////////////////////////游戏开始标志 0未开始 1游戏中
int gamebody[][]=newint[16][16]; ////设置棋盘棋子状态 0 无子 1 白子 2 黑子
Button b1=new Button("游戏开始");
Button b2=new Button("重置游戏");
Button b3=new Button("退出游戏");
Label lblWin=new Label("");////////////////////状态标签
Checkbox ckbHB[]=new Checkbox[2];/////////////起始复选框
CheckboxGroup ckgHB=new CheckboxGroup();////////复选框组
publicvoid init()
{
resize(420,360);
setLayout(null);
addMouseListener(this);
add(b1);
b1.setBounds(330,100,70,30);
b1.addActionListener(this);
add(b2);
b2.setBounds(330,140,70,30);
b2.addActionListener(this);
add(b3);
b3.setBounds(330,180,70,30);
b3.addActionListener(this);
ckbHB[0]=new Checkbox("白子先",ckgHB,false);
ckbHB[0].setBounds(330,30,70,30);
ckbHB[1]=new Checkbox("黑子先",ckgHB,false);
ckbHB[1].setBounds(330,60,70,30);
add(ckbHB[0]);
add(ckbHB[1]);
ckbHB[0].addItemListener(this);
ckbHB[1].addItemListener(this);
add(lblWin);
lblWin.setBounds(330,280,70,30);
setBackground(Color.gray);
setBounds(100,100,320,280);
setVisible(true);
start();
}
publicvoid itemStateChanged(ItemEvent e)
{
if (ckbHB[0].getState()) ////////////////////////判断黑子先还是白子先
{
color_Qizi=0;
}
else
{
color_Qizi=1;
}
}
if (x1%20>10)
{
x1+=20;
}
if(y1%20>10)
{
y1+=20;
}
x1=x1/20*20;
y1=y1/20*20;
set_Qizi(x1,y1);
}
publicvoid mousePressed(MouseEvent e){}
publicvoid mouseEntered(MouseEvent e){}
publicvoid mouseExited(MouseEvent e){}
publicvoid mouseReleased(MouseEvent e){}
publicvoid mouseDragged(MouseEvent e){}
publicvoid mouseMoved(MouseEvent e){}
publicvoid paint(Graphics g)
{
qipan(g);
}
publicvoid set_Qizi(int x,int y) /////////////////////////////落子
{
if (gamestart==0) ///////////////////////////////////判断游戏是否开始
{
return;
}
if (gamebody[x/20][y/20]!=0)
{
return;
}
Graphics g=getGraphics();
if (color_Qizi==1)///////////////////////////////////判断黑子还是白子
{
g.setColor(Color.black);
color_Qizi=0;
}
else
{
g.setColor(Color.white);
color_Qizi=1;
}
g.fillOval(x-10,y-10,20,20);
gamebody[x/20][y/20]=color_Qizi+1;
if (Game_win_1(x/20,y/20)) ////////////////////////////////判断输赢1 横向
{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
gamestart=0;
}
if (Game_win_2(x/20,y/20)) ////////////////////////////////判断输赢2 竖向
{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
gamestart=0;
}
if (Game_win_3(x/20,y/20)) ////////////////////////////////判断输赢3 左斜
{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
gamestart=0;
}
if (Game_win_4(x/20,y/20)) ////////////////////////////////判断输赢4 右斜
{
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
gamestart=0;
}
}
public String Get_qizi_color(int x)///////////////////////返回棋子颜色
{
if (x==0)
{
return "黑子";
}
else
{
return "白子";
}
}
publicvoid qipan(Graphics G) ///////////////////////////画棋盘 15*15
{
G.setColor(Color.gray);
G.fill3DRect(10,10,300,300,true);
G.setColor(Color.black);
for(int i=1;i<16;i++)
{
G.drawLine(20,20*i,300,20*i);
G.drawLine(20*i,20,20*i,300);
}
}
publicvoid Game_btn_enable(boolean e) /////////////////设置组件初始状态
{
b1.setEnabled(e);
b2.setEnabled(e);
b3.setEnabled(e);
ckbHB[0].setEnabled(e);
ckbHB[1].setEnabled(e);
}
publicvoid start() /////////////////////////////////////游戏开始初始化
{
gamestart=0;
Game_btn_enable(true);
b2.setEnabled(false);
b3.setEnabled(false);
ckbHB[0].setState(true);
for (int i=0;i<16 ;i++ )
{
for (int j=0;j<16 ;j++ )
{
gamebody[i][j]=0;
}
}
lblWin.setText("胜负状态");
}
publicvoid Game_start() /////////////////////////////////////游戏开始
{
gamestart=1;
Game_btn_enable(false);
b2.setEnabled(true);
b3.setEnabled(true);
}
publicvoid Game_re() ////////////////////////////////////游戏重新开始
{
repaint();
start();
repaint();
start();
}
publicvoid Game_stop()//////////////////////////////////////退出游戏
{
new MyFrame();
}
class MyFrame extends Frame implements ActionListener
{
Button b4,b5,b6;
MyFrame()
{
super("MY WINDOWS");
b4=new Button("\"退出\"将被判为\"输\"是否继续游戏?");
setLayout(new FlowLayout());
add(b4);
b4.addActionListener(this);
setLayout(new FlowLayout());
b5=new Button("是");
add(b5);
b5.addActionListener(this);
setLayout(new FlowLayout());
b6=new Button("否");
add(b6);
b6.addActionListener(this);
addWindowListener(new closeWin());
setSize(220,100);
setVisible(true);
}
publicvoid actionPerformed(ActionEvent e)
{
if(e.getActionCommand()=="关闭")
{
dispose();
}
if (e.getSource()==b5)
{
dispose();
}
elseif(e.getSource()==b6)
{
dispose();
lblWin.setText(Get_qizi_color(color_Qizi)+"赢了!");
}
else
{
return;
}
}
}
class closeWin extends WindowAdapter
{
publicvoid windowClosing(WindowEvent e)
{
Window w=e.getWindow();
w.dispose();
}
}
publicboolean Game_win_1(int x,int y) /////////////////////////判断输赢 横
{
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ )
{
if (x1>15)
{
break;
}
if (gamebody[x1+i][y1]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
for (int i=1;i<5 ;i++ )
{
if (x1<1)
{
break;
}
if(gamebody[x1-i][y1]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
if (t>4)
{
returntrue;
}
else
{
returnfalse;
}
}
publicboolean Game_win_2(int x,int y) /////////////////////////判断输赢 竖
{
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ )
{
if (x1>15)
{
break;
}
if (gamebody[x1][y1+i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
for (int i=1;i<5 ;i++ )
{
if (x1<1)
{
break;
}
if(gamebody[x1][y1-i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
if (t>4)
{
returntrue;
}
else
{
returnfalse;
}
}
publicboolean Game_win_3(int x,int y) ////////////////////判断输赢 左斜
{
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ )
{
if (x1>15)
{
break;
}
if (gamebody[x1+i][y1-i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
for (int i=1;i<5 ;i++ )
{
if (x1<1)
{
break;
}
if(gamebody[x1-i][y1+i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
if (t>4)
{
returntrue;
}
else
{
returnfalse;
}
}
publicboolean Game_win_4(int x,int y) ////////////////////判断输赢 右斜
{
int x1,y1,t=1;
x1=x;
y1=y;
for (int i=1;i<5 ;i++ )
{
if (x1>15)
{
break;
}
if (gamebody[x1+i][y1+i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
for (int i=1;i<5 ;i++ )
{
if (x1<1)
{
break;
}
if(gamebody[x1-i][y1-i]==gamebody[x][y])
{
t+=1;
}
else
{
break;
}
}
if (t>4)
{
returntrue;
}
else
{
returnfalse;
}
}
}
第五章工作总结
理论与实践有很大的差别,通过这次课程设计实践,我对Java的事件处理机制,容器与布局管理,常用GUI标准组件等图形用户界面编程更加熟悉。在这个游戏的实践过程中,出现了一些问题。
首先是棋子与坐标的对应关系,摸索了好一阵时间,最后还参考了别人的信息。才使得下起来更合理,舒适。也使得整个画面,简洁,美观。
其次是 老是忘记某些按钮,接口要注册,有时对应的监听者也搞不清,所以要常练习。
最后是窗口弹出与消去有点问题,我通过找书上例题参考和使用API文档及在百度知道提问给解决了。
虽然我没有完成题目的所有要求,但我通过自己的双手做出了一个可以玩的游戏,心里的确很高兴。这次课程设计让我学会了很多东西。
首先是实践是检验真理的唯一标准。无论理论知识学的多么好,Java等计算机语言是一门实践性很强的课程,不通过实践,一切都是空谈。我之前有一阵子上机实践较少,这次课设开始时几乎忘记怎么初始化数组。
其次是基础很重要。调试过程中,有些困扰我好一阵子的“大问题”,后来发现大部分都是一些基础小问题引起的 。
最后是要善于自己解决问题,每个人的时间都很宝贵,程序员尤其如此,出现问题后自己要独立去解决,大学生不就应该要锻炼这方面的能力吗?这次课设过程中出现的问题大部分都是我通过API文档,课本,还有网上论坛,提问等等方式解决了。
知道是一回事,能不能做又是另一回事。只有熟能生巧,没有巧而能熟。
致 谢
当写这个致谢的时候,也意味着我即将进入大四,在大学生活中不断的学习成长,谢谢陪我一起生活的朋友们,因有你们的支持和鼓励让我的大学过的不再孤单而丰富多彩。特别感谢计算机网络的杨老师,在计算机课堂上我学会了很多,从一个对计算机什么都不懂,就会操作下电脑玩游戏上网,到现在对计算机有一定了解。还要感谢我可爱的同学们,没有你们的帮助我此次课程设计也不会那么顺利。这是一次令人难忘的课程设计。
参考文献
1.孙家广,《软件工程---理论、方法与实践》.清华大学出版社.20##年.
2.王珊、萨师煊,《数据库系统概》第三版.高等教育出版.20##年
3.丁振凡Java语言实用教程.北京邮电大学出版社,20##年8月第一版第2次印刷
4.叶核亚 陈道蕾.《java2程序设计实用教程》,电子工业出版社 20##年1月第二版