五子棋 课程设计完整报告 C++版_第1页
五子棋 课程设计完整报告 C++版_第2页
五子棋 课程设计完整报告 C++版_第3页
五子棋 课程设计完整报告 C++版_第4页
五子棋 课程设计完整报告 C++版_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

课程设计的目的计算机网络课程设计是计算机网络原理课程之后的实践加强环节,通过本设计的训练使学生加深对网络协议的理解,并实践制定通信规则,同时通过实践,进一步掌握套接字编程方法,为大型网络编程打下坚实基础。通过本次课程设计的学习与实践,使学生能达到知识与技能两方面结合的目标。1.熟练掌握网络的基本概念和原理。2.熟练掌握网络编程接口Winsock概念及编程原理3.掌握基于TCP/IP的Internet编程技术。4.掌握软件开发的过程及思想。二.课程设计内容本课程设计的内容是通过对传输层协议TCP和UDP和客户/服务器数据通信的原理及方式的掌握,实现五子棋的局域网对战。(一)TCP连接的套接字的使用(1).服务器端套接字的实现1.创建socket2.绑定3.监听4.接受连接5.发送和接受数据6.关闭(2)客户端套接字的实现1.创建socket2.连接到服务器3.发送和接受数据4.断开连接(二)游戏规则:一、阳线和阴线1、阳线:棋盘上可见的横纵直线。

2、阴线:棋盘上无实线连接的隐形斜线。二、连:在棋阳线和阴线的任意一条线上形成的有5个或5个以上的同色棋子不间隔地紧紧相连。五连:在棋盘上形成的5个同色棋子的“连”。三、开发环境及实现所用语言开发环境:MicrosoftVisualC++6.0语言:C++四、程序流程图五、主要代码套接字的使用方法1)服务器端套接字的实现#include"stdafx.h"#include"FiveChess.h"#include"ServerSocket.h"#include"FiveChessView.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif///////////////////////////////////////////////////////////////////////////////CServerSocketCServerSocket::CServerSocket(){}CServerSocket::~CServerSocket(){}//Donoteditthefollowinglines,whichareneededbyClassWizard.#if0BEGIN_MESSAGE_MAP(CServerSocket,CSocket) //{{AFX_MSG_MAP(CServerSocket) //}}AFX_MSG_MAPEND_MESSAGE_MAP()#endif //0///////////////////////////////////////////////////////////////////////////////CServerSocketmemberfunctionsBOOLCServerSocket::Init(UINTport,CFiveChessView*view){ m_uPort=port; m_view=view; if(Create(m_uPort)==FALSE)//创建socket { AfxMessageBox("ServerSocketCreateError"); returnFALSE; } if(this->Listen()==FALSE)//监听socket { AfxMessageBox("ServerListenError"); returnFALSE; } returnTRUE;}voidCServerSocket::OnAccept(intnErrorCode)//接受客户端连接的消息{ CSocket::OnAccept(nErrorCode); m_view->ProcessPendingAccept();//调用视图类中的接受连接处理函数}2)客户端套接字的实现#include"stdafx.h"#include"FiveChess.h"#include"ClientSocket.h"#include"FiveChessView.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif///////////////////////////////////////////////////////////////////////////////CClientSocketCClientSocket::CClientSocket(){ m_aSessionIn=NULL; m_aSessionOut=NULL; m_sfSocketFile=NULL; m_bInit=false; m_bClose=false;}CClientSocket::~CClientSocket(){ if(m_aSessionIn) deletem_aSessionIn; if(m_aSessionOut) deletem_aSessionOut; if(m_sfSocketFile) deletem_sfSocketFile;}//Donoteditthefollowinglines,whichareneededbyClassWizard.#if0BEGIN_MESSAGE_MAP(CClientSocket,CSocket) //{{AFX_MSG_MAP(CClientSocket) //}}AFX_MSG_MAPEND_MESSAGE_MAP()#endif //0///////////////////////////////////////////////////////////////////////////////CClientSocketmemberfunctionsvoidCClientSocket::OnReceive(intnErrorCode)//数据接收消息的处理函数{ CSocket::OnReceive(nErrorCode); do { CMessgtemp; temp.Serialize(*m_aSessionIn);//输入数据的串行化 m_view->m_sMsgList+=temp.m_strText+"\r\n";//加入新的对话内容 //把新的对话内容显示在主视图窗口的一个edit控件中。 m_view->m_outputedit.SetWindowText(m_view->m_sMsgList); //把Edit窗口中显示的内容滚到当前的位置 m_view->m_iLineCurrentPos=m_view->m_outputedit.GetLineCount(); m_view->m_outputedit.LineScroll(m_view->m_iLineCurrentPos); //判断对方发送过来的数据是否是落子的位置 if(m_view->m_match.CanDown(temp.m_x,temp.m_y,m_view->m_who%2+1)) { //是对方发送的落子信息 m_view->m_turn=temp.m_turn;//该轮到我走棋了 m_view->Invalidate(FALSE);//刷新视图,显示对方的走子位置 //对方是否赢了 if(m_view->m_match.IsWin(m_view->m_who%2+1,temp.m_x,temp.m_y)) { m_view->m_bWin=TRUE;//对方赢了 m_view->m_bOver=TRUE; m_view->Invalidate(FALSE); AfxMessageBox("你输了");//显示输棋的对话框 m_view->m_outputedit.SetWindowText(m_view->m_sMsgList); m_view->m_iLineCurrentPos=m_view->m_outputedit.GetLineCount(); m_view->m_outputedit.LineScroll(m_view->m_iLineCurrentPos); } } } while(!m_aSessionIn->IsBufferEmpty());}voidCClientSocket::Init(CFiveChessView*view)//socket串行化数据的初始工作{ m_sfSocketFile=newCSocketFile(this); m_aSessionIn=newCArchive(m_sfSocketFile,CArchive::load); m_aSessionOut=newCArchive(m_sfSocketFile,CArchive::store); m_bClose=false; this->m_view=view;}BOOLCClientSocket::SendMessage(CMessg*msg)//发送数据到对方{ if(m_aSessionOut!=NULL) {msg->Serialize(*m_aSessionOut);//输出串行化m_aSessionOut->Flush();//直接发送returnTRUE; } else {//对方关闭了连接m_bClose=true;CloseSocket(); //m_view->CloseSessionSocket();returnFALSE; }}voidCClientSocket::CloseSocket(){ if(m_aSessionIn) { deletem_aSessionOut; m_aSessionIn=NULL; } if(m_sfSocketFile) { deletem_aSessionOut; m_sfSocketFile=NULL; } Close(); m_bInit=false; m_bClose=true;}voidCClientSocket::OnClose(intnErrorCode)//对方关闭了Socket的消息处理{ m_bClose=true; CloseSocket(); CSocket::OnClose(nErrorCode);}intCClientSocket::GetLocalHostName(CString&sHostName)//获得本地计算机名称{ charszHostName[256]; intnRetCode; nRetCode=gethostname(szHostName,sizeof(szHostName)); if(nRetCode!=0) { //产生错误 sHostName=_T("没有取得"); returnGetLastError(); } sHostName=szHostName; return0;}intCClientSocket::GetIPAddress(constCString&sHostName,CString&slpAddress)//获得本地ip{ structhostentFAR*lpHostEnt=gethostbyname(sHostName); if(lpHostEnt==NULL) { //产生错误 slpAddress=_T(""); returnGetLastError(); } //获取IP LPSTRlpAddr=lpHostEnt->h_addr_list[0]; if(lpAddr) { structin_addrinAddr; memmove(&inAddr,lpAddr,4); //转换为标准格式 slpAddress=inet_ntoa(inAddr); if(slpAddress.IsEmpty()) slpAddress=_T("没有取得"); } return0;}intCClientSocket::GetIPAddress(constCString&sHostName,BYTE&f0,BYTE&f1,BYTE&f2,BYTE&f3)//获得本地IP{ structhostentFAR*lpHostEnt=gethostbyname(sHostName); if(lpHostEnt==NULL) { //产生错误 f0=f1=f2=f3=0; returnGetLastError(); } //获取IP LPSTRlpAddr=lpHostEnt->h_addr_list[0]; if(lpAddr) { structin_addrinAddr; memmove(&inAddr,lpAddr,4); f0=inAddr.S_un.S_un_b.s_b1; f1=inAddr.S_un.S_un_b.s_b2; f2=inAddr.S_un.S_un_b.s_b3; f3=inAddr.S_un.S_un_b.s_b4; } return0;}棋盘、棋子画法及服务器端、客户端处理函数的实现#include"stdafx.h"#include"FiveChess.h"#include"FiveChessDoc.h"#include"FiveChessView.h"#include"ClientSocket.h"#include"ClientDlg.h"#include"ServerDlg.h"#include"MsgEdit.h"#ifdef_DEBUG#definenewDEBUG_NEW#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#endif///////////////////////////////////////////////////////////////////////////////CFiveChessViewIMPLEMENT_DYNCREATE(CFiveChessView,CView)BEGIN_MESSAGE_MAP(CFiveChessView,CView) //{{AFX_MSG_MAP(CFiveChessView) ON_COMMAND(ID_Setclient,OnSetclient) ON_COMMAND(ID_Setserver,OnSetserver) ON_WM_LBUTTONDOWN() ON_WM_SIZE() ON_WM_DESTROY() //}}AFX_MSG_MAP //Standardprintingcommands ON_COMMAND(ID_FILE_PRINT,CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT,CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView::OnFilePrintPreview)END_MESSAGE_MAP()///////////////////////////////////////////////////////////////////////////////CFiveChessViewconstruction/destructionCFiveChessView::CFiveChessView(){ //TODO:addconstructioncodehere m_bIsClient=FALSE; m_bIsInit=FALSE; m_bOver=FALSE; m_bWin=FALSE; m_turn=1;//服务器先走,黑棋 gridHeight=gridWid=30; this->m_inputedit.SetParent(this);}CFiveChessView::~CFiveChessView(){}BOOLCFiveChessView::PreCreateWindow(CREATESTRUCT&cs){ //TODO:ModifytheWindowclassorstylesherebymodifying //theCREATESTRUCTcs returnCView::PreCreateWindow(cs);}///////////////////////////////////////////////////////////////////////////////CFiveChessViewdrawing///////////////////////////////////////////////////////////////////////////////CFiveChessViewprintingBOOLCFiveChessView::OnPreparePrinting(CPrintInfo*pInfo){ //defaultpreparation returnDoPreparePrinting(pInfo);}voidCFiveChessView::OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/){ //TODO:addextrainitializationbeforeprinting}voidCFiveChessView::OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/){ //TODO:addcleanupafterprinting}///////////////////////////////////////////////////////////////////////////////CFiveChessViewdiagnostics#ifdef_DEBUGvoidCFiveChessView::AssertValid()const{ CView::AssertValid();}voidCFiveChessView::Dump(CDumpContext&dc)const{ CView::Dump(dc);}CFiveChessDoc*CFiveChessView::GetDocument()//non-debugversionisinline{ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFiveChessDoc))); return(CFiveChessDoc*)m_pDocument;}#endif//_DEBUG///////////////////////////////////////////////////////////////////////////////CFiveChessViewmessagehandlersvoidCFiveChessView::OnDraw(CDC*pDC){CFiveChessDoc*pDoc=GetDocument(); ASSERT_VALID(pDoc); CBrushback(RGB(125,125,20));//绘制棋盘的刷子 pDC->SelectObject((CBrush*)&back); CRectrect; rect.left=LEFTDIS; rect.right=LEFTDIS+(LW-1)*gridWid; rect.top=TOPDIS; rect.bottom=TOPDIS+(LW-1)*gridWid; pDC->FillRect(&rect,&back);//绘制棋盘 CPenpen(PS_SOLID,2,RGB(25,25,255));////绘制网格线的笔 pDC->SelectObject((CPen*)&pen); inti,j; CPointpos; for(i=0;i<LW;i++)//竖值的线 { pos.x=LEFTDIS+gridWid*i; pos.y=TOPDIS; pDC->MoveTo(pos); pos.y=TOPDIS+(LW-1)*gridWid; pDC->LineTo(pos); } for(i=0;i<LW;i++)//水平的线 { pos.x=LEFTDIS; pos.y=TOPDIS+gridWid*i; pDC->MoveTo(pos); pos.x=LEFTDIS+(LW-1)*gridWid; pDC->LineTo(pos); } CBrushwhitebrush(RGB(255,255,255));//绘制黑棋的刷子 CBrushblackbrush(RGB(0,0,0));//绘制白棋的刷子 for(i=0;i<LW;i++)//扫描整个棋盘 for(j=0;j<LW;j++) { if(m_match.chessboard[i][j]==1)//黑棋 { pDC->SelectObject((CBrush*)&blackbrush); pDC->Ellipse( j*gridWid+LEFTDIS-gridWid/2, i*gridWid+TOPDIS-gridWid/2, j*gridWid+LEFTDIS+gridWid/2, i*gridWid+TOPDIS+gridWid/2); } elseif(m_match.chessboard[i][j]==2)//白棋{pDC->SelectObject((CBrush*)&whitebrush); pDC->Ellipse( j*gridWid+LEFTDIS-gridWid/2, i*gridWid+TOPDIS-gridWid/2, j*gridWid+LEFTDIS+gridWid/2, i*gridWid+TOPDIS+gridWid/2); } elseif(m_match.chessboard[i][j]==3) { CBrushredbrush(RGB(255,0,0));//用红色的刷子显示关键的5个棋子 pDC->SelectObject((CBrush*)&redbrush); pDC->Ellipse( j*gridWid+LEFTDIS-gridWid/2, i*gridWid+TOPDIS-gridWid/2, j*gridWid+LEFTDIS+gridWid/2, i*gridWid+TOPDIS+gridWid/2); } } CRectdst; this->GetWindowRect(rect); //移动两个动态的CEdit控件,作为输入对话框和显示对话框 m_outputedit.MoveWindow(CRect(10,rect.bottom-200,rect.right-10,rect.bottom-140),false); m_inputedit.MoveWindow(CRect(10,rect.bottom-140,rect.right-10,rect.bottom-100),false);}voidCFiveChessView::OnSetserver()//菜单项"开启服务器"的消息处理函数{ CServerDlgdlg; if(dlg.DoModal()==IDOK)//服务器端口设置对话框 { m_bIsClient=FALSE;//做游戏的服务器端 m_bIsInit=TRUE;//已经初始化 m_port=dlg.m_iPort;//得到输入的端口号 m_ListenSocket.Init(m_port,this);//开始监听端口 }}voidCFiveChessView::OnSetclient()//菜单项"连接服务器"的消息处理函数{CClientDlgdlg;intret=dlg.DoModal();//设置服务器的IP和端口if(ret==IDOK)//用户点击了"确定"{ m_bIsClient=TRUE;//做游戏的服务器端 m_bIsInit=TRUE;//已经初始化 m_port=dlg.m_iPort;//得到用户输入的服务器端的端口 for(inti=0;i<4;i++) m_bIP[i]=dlg.m_bIP[i];//得到用户输入的服务器端的IP地址 this->m_ip.Format("%d.%d.%d.%d",dlg.m_bIP[0],dlg.m_bIP[1],dlg.m_bIP[2],dlg.m_bIP[3]); m_ClientSocket.Create();//创建会话socket if(m_ClientSocket.Connect(LPCSTR(m_ip),m_port))//连接到服务器端 { m_ClientSocket.Init(this);//初始化会话socket m_who=2;//客户端用白子 AfxMessageBox("成功的连接到服务器,可以开始游戏了"); } else { m_ClientSocket.Close();//连接失败 AfxMessageBox("clientconnectionfailed"); } }}voidCFiveChessView::ProcessPendingAccept()//处理客户端socket连接的函数{if(m_ListenSocket.Accept(m_ClientSocket)==FALSE)//分配一个会话socket{ AfxMessageBox("SeverListenSocketError"); return;}else{ m_who=1;//服务器端用黑棋,黑棋先行 m_ClientSocket.Init(this);//初始化会话socket m_outputedit.SetWindowText("有人进来了"); AfxMessageBox("有人进来了"); }}voidCFiveChessView::GetLocalIP()//得到本机的IP地址,调用CClientSocket中的静态函数{ staticBOOLfirst=TRUE; if(first==TRUE) {CClientSocket::GetLocalHostName(m_sLocalName);CClientSocket::GetIPAddress(m_sLocalName,m_bIP[0],m_bIP[1],m_bIP[2],m_bIP[3]);m_ip.Format("%d.%d.%d.%d",m_bIP[0],m_bIP[1],m_bIP[2],m_bIP[3]); first=FALSE; }}voidCFiveChessView::SendInputMsg(CStringin)//在聊天输入框中输入对话的消息函数{// AfxMessageBox("InputEdit"); if(!m_bIsInit)//如果网络还没有连接好则不准输入 { //AfxMessageBox("NOConnection"); return; } CMessgmsg; in.TrimRight(""); m_inputedit.SetWindowText(""); if(in.GetLength()>2) { m_sMsgList+=in+"\r\n";//添加聊天的内容 m_outputedit.SetWindowText(m_sMsgList);//输出到聊天显示框 m_iLineCurrentPos=m_outputedit.GetLineCount(); m_outputedit.LineScroll(m_iLineCurrentPos);//滚动到当前的位置 msg.m_strText=in; m_ClientSocket.SendMessage(&msg);//发送聊天的内容到另外一端 } }voidCFiveChessView::OnInitialUpdate()//初始化{ CView::OnInitialUpdate(); staticbooloninitialupdatchaving=false;//只需要初始化调用一次 if(oninitialupdatchaving==false) { if(::AfxSocketInit()==FALSE)//winsock初始化 { AfxMessageBox("socketiniterror"); } GetLocalIP();//得到本机的IP地址 CRectrect; this->GetWindowRect(rect); //创建两个动态的CEdit控件,作为输入对话框和显示对话框 m_outputedit.Create(ES_MULTILINE|WS_CHILD|WS_VISIBLE|WS_TABSTOP| WS_BORDER|ES_READONLY,CRect(10,rect.bottom-200,rect.right-10,rect.bottom-140),this,1); m_inputedit.Create(ES_MULTILINE|WS_CHILD|WS_VISIBLE|WS_TABSTOP| WS_BORDER|ES_AUTOVSCROLL,CRect(10,rect.bottom-140,rect.right-10,rect.bottom-100),this,2); }}voidCFiveChessView::OnLButtonDown(UINTnFlags,CPointpoint)//处理鼠标左键按下的消息{ if(m_bOver==TRUE)//比赛是否已经结束 { if(AfxMessageBox("你想要重新开始游戏吗",MB_YESNO)==IDYES) { //重新开始游戏 m_bIsClient=FALSE; m_bIsInit=FALSE; m_turn=1; m_bOver=false; m_match.Clear(); m_bWin=FALSE; Invalidate(FALSE); return; } } if(m_turn==m_who)//轮到本机走棋 { m_POS[0]=(int)((point.y-TOPDIS)/30.0+0.5); m_POS[1]=(int)((point.x-LEFTDIS)/30.0+0.5); if(m_match.CanDown(m_POS[1],m_POS[0],m_who)==TRUE)//这个位置是否可以落子 { Invalidate(FALSE);//重新绘制棋子和棋盘 m_turn=m_who%2+1;//轮到对方走棋 CMessgmsg; msg.m_turn=m_turn; msg.m_x=m_POS[1]; msg.m_y=m_POS[0]; m_ClientSocket.SendMessage(&msg);//发送落子的位置 if(m_match.IsWin(m_who,m_POS[1],m_POS[0]))//判断是否赢棋 { m_bWin=TRUE; m_bOver=TRUE; Invalidate(FALSE); AfxMessageBox("你赢了!"); m_sMsgList+="你赢了!"; m_outputedit.SetWindowText(m_sMsgList+"\r\n"); } } } else { m_sMsgList+="不该你走棋\r\n";m_outputedit.SetWindowText(m_sMsgList);}CView::OnLButtonDown(nFlags,point);}voidCFiveChessView::OnSize(UINTnType,intcx,intcy){ CView::OnSize(nType,cx,cy); //TODO:Addyourmessagehandlercodehere}3、游戏规则及胜负判定#include"stdafx.h"#include"FiveChess.h"#include"Match.h"#ifdef_DEBUG#undefTHIS_FILEstaticcharTHIS_FILE[]=__FILE__;#definenewDEBUG_NEW#endif////////////////////////////////////////////////////////////////////////Construction/Destruction//////////////////////////////////////////////////////////////////////Match::Match(){ for(inti=0;i<LW;i++) for(intj=0;j<LW;j++) { chessboard[i][j]=0; }}Match::~Match(){}voidMatch::Clear(){ for(inti=0;i<LW;i++) for(intj=0;j<LW;j++) { chessboard[i][j]=0; }}BOOLMatch::CanDown(intx,inty,intwho)//判断在x,y位置是否能落子{ CStringstr;// str.Format("x:%dy:%dchessboard:%d",x,y,chessboard[]);// AfxMessageBox(str); if(x<0||x>=LW||y<0||y>=LW) returnFALSE; if(chessboard[y][x]!=0) returnFALSE; chessboard[y][x]=who; returnTRUE;}BOOLMatch::IsWin(intwho,intx,inty){ inti=0; intj=0; //水平方向 for(i=y,j=(x-4>=0?x-4:0);j<(x+4>=LW?LW-1:x+4);j++) { while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]!=who) j++; intcount=0; while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j++]==who) count++; if(count>=5) { j--;j--; while(count--) chessboard[i][j--]=3;//标记胜出的几颗棋子 returntrue; } } //垂直方向 for(j=x,i=(y-4>=0?y-4:0);i<(y+4>=LW?LW-1:y+4);i++)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论