测试与调试

主代码

#include "stdafx.h" #include "FiveChess.h" #include "ServerSocket.h"  
#include "FiveChessView.h"  
#ifdef _DEBUG 
#define new DEBUG_NEW #undef THIS_FILE 
static char THIS_FILE[] = __FILE__; #endif  
///////////////////////////////////////////////////////////////////////////// // 

CServerSocket  
CServerSocket::CServerSocket() { }

CServerSocket::~CServerSocket() { }   
// Do not edit the following lines, which are needed by ClassWizard. #if 0 
BEGIN_MESSAGE_MAP(CServerSocket, CSocket)  //{{AFX_MSG_MAP(CServerSocket)  //}}

AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0  
///////////////////////////////////////////////////////////////////////////// // 

CServerSocket member functions 
BOOL CServerSocket::Init(UINT port,CFiveChessView*view) 

{  m_uPort=port;  m_view=view;  if(Create(m_uPort)==FALSE)

//创建socket  {   AfxMessageBox("Server Socket Create Error");   

return FALSE;  }  if(this->Listen()==FALSE)

//监听socket  {   AfxMessageBox("Server Listen Error");   return FALSE;  }  return TRUE; } 
void CServerSocket::OnAccept(int nErrorCode)

//接受客户端连接的消息 {  CSocket::OnAccept(nErrorCode);  m_view->ProcessPendingAccept();

//调用视图类中的接受连接处理函数 }

2)客户端套接字的实现   #include "stdafx.h" #include "FiveChess.h" #include "ClientSocket.h" #include"FiveChessView.h"

 4 
 
#ifdef _DEBUG 
#define new DEBUG_NEW #undef THIS_FILE 
static char THIS_FILE[] = __FILE__; #endif  
///////////////////////////////////////////////////////////////////////////// // CClientSocket  
CClientSocket::CClientSocket() {  m_aSessionIn=NULL;  m_aSessionOut=NULL;  m_sfSocketFile=NULL;  m_bInit=false;  m_bClose=false; }  
CClientSocket::~CClientSocket() {  if(m_aSessionIn)   delete m_aSessionIn;  if(m_aSessionOut)   delete m_aSessionOut;  if(m_sfSocketFile)   delete m_sfSocketFile; }   
// Do not edit the following lines, which are needed by ClassWizard. #if 0 
BEGIN_MESSAGE_MAP(CClientSocket, CSocket)  //{{AFX_MSG_MAP(CClientSocket)  //}}AFX_MSG_MAP END_MESSAGE_MAP() #endif // 0  
///////////////////////////////////////////////////////////////////////////// // CClientSocket member functions  
void CClientSocket::OnReceive(int nErrorCode)//数据接收消息的处理函数 {  CSocket::OnReceive(nErrorCode);

do

{   CMessg temp;   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()); } 
void CClientSocket::Init(CFiveChessView*view)//socket串行化数据的初始工作 {  m_sfSocketFile=new CSocketFile(this);  m_aSessionIn=new CArchive(m_sfSocketFile,CArchive::load);  m_aSessionOut=new CArchive(m_sfSocketFile,CArchive::store);  m_bClose=false;  this->m_view=view; } 
BOOL CClientSocket::SendMessage(CMessg*msg)//发送数据到对方 {  if(m_aSessionOut!=NULL)  { 
        msg->Serialize(*m_aSessionOut);//输出串行化         

m_aSessionOut->Flush();//直接发送

return TRUE;  }  else  { 
        //对方关闭了连接         

m_bClose=true;         CloseSocket();  

 // m_view->CloseSessionSocket();         return FALSE;  } } 
void CClientSocket::CloseSocket() {  if(m_aSessionIn)  {   delete m_aSessionOut;   m_aSessionIn=NULL;  } 

 if(m_sfSocketFile)  {   delete m_aSessionOut;   m_sfSocketFile=NULL;  }

  Close();  m_bInit=false;  m_bClose=true; } 
void CClientSocket::OnClose(int nErrorCode)//对方关闭了Socket的消息处理

 {  m_bClose=true;  CloseSocket();  CSocket::OnClose(nErrorCode); } 
int CClientSocket::GetLocalHostName(CString&sHostName)//获得本地计算机名称 {  char szHostName[256];  int nRetCode;  nRetCode=gethostname(szHostName,sizeof(szHostName)); 

 if(nRetCode!=0)  {   //产生错误   sHostName=_T("没有取得");    return GetLastError();  }

 7 
 
 sHostName=szHostName;  return 0; } 
int CClientSocket::GetIPAddress(const CString&sHostName,CString&slpAddress)//获得本地ip {  struct hostent FAR*lpHostEnt=gethostbyname(sHostName);  if(lpHostEnt==NULL)  {   //产生错误   slpAddress=_T("");   return GetLastError();  }  

//获取IP  LPSTR lpAddr=lpHostEnt->h_addr_list[0];  if(lpAddr)  {   struct in_addr inAddr;   memmove(&inAddr,lpAddr,4);   //转换为标准格式   slpAddress=inet_ntoa(inAddr);   if(slpAddress.IsEmpty())    slpAddress=_T("没有取得");  }  return 0; } 
int CClientSocket::GetIPAddress(const 
CString&sHostName,BYTE&f0,BYTE&f1,BYTE&f2,BYTE&f3)//获得本地IP {  struct hostent FAR*lpHostEnt=gethostbyname(sHostName);  if(lpHostEnt==NULL)  

{   //产生错误   f0=f1=f2=f3=0;   return GetLastError();  }  //获取IP  LPSTR lpAddr=lpHostEnt->h_addr_list[0];  if(lpAddr)  {   struct in_addr inAddr;   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;

 8 
 
  f3=inAddr.S_un.S_un_b.s_b4;     } 
 return 0; 
}

 8 
 
  f3=inAddr.S_un.S_un_b.s_b4;     } 
 return 0; 
}  
2、棋盘、棋子画法及服务器端、客户端处理函数的实现 
#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 
#define new DEBUG_NEW #undef THIS_FILE 
static char THIS_FILE[] = __FILE__;

 #endif

//////////////////////////////////////////////////////////////////////////// // CFiveChessView  
IMPLEMENT_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  // Standard printing commands  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()  
///////////////////////////////////////////////////////////////////////////// // 

CFiveChessView construction/destruction 

CFiveChessView::CFiveChessView() {  // TODO: add construction code here  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() { }  
BOOL CFiveChessView::PreCreateWindow(CREATESTRUCT& cs) {  // TODO: Modify the Window class or styles here by modifying  //  the CREATESTRUCT cs   return CView::PreCreateWindow(cs); }  
///////////////////////////////////////////////////////////////////////////// // CFiveChessView drawing   
///////////////////////////////////////////////////////////////////////////// // CFiveChessView printing  
BOOL CFiveChessView::OnPreparePrinting(CPrintInfo* pInfo) {  // default preparation  return DoPreparePrinting(pInfo); }  
void CFiveChessView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) {  // TODO: add extra initialization before printing }  
void CFiveChessView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)

{  // TODO: add cleanup after printing }  
///////////////////////////////////////////////////////////////////////////// // CFiveChessView diagnostics  
#ifdef _DEBUG 
void CFiveChessView::AssertValid() const {  CView::AssertValid(); }  
void CFiveChessView::Dump(CDumpContext& dc) const {  CView::Dump(dc); }  
CFiveChessDoc* CFiveChessView::GetDocument() // non-debug version is inline {  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFiveChessDoc)));  return (CFiveChessDoc*)m_pDocument; } 
#endif //_DEBUG  
///////////////////////////////////////////////////////////////////////////// // CFiveChessView message handlers   
void CFiveChessView::OnDraw(CDC*pDC) { 
    CFiveChessDoc *pDoc=GetDocument();  ASSERT_VALID(pDoc);  CBrush back(RGB(125,125,20));       //绘制棋盘的刷子  pDC->SelectObject((CBrush*)&back);  CRect rect;  rect.left=LEFTDIS;  rect.right=LEFTDIS+(LW-1)*gridWid;  rect.top=TOPDIS;  rect.bottom=TOPDIS+(LW-1)*gridWid;  pDC->FillRect(&rect,&back);            //绘制棋盘  CPen pen(PS_SOLID,2,RGB(25,25,255));   ////绘制网格线的笔  pDC->SelectObject((CPen*)&pen);  int  i,j;

CPoint pos;  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);  }  CBrush whitebrush(RGB(255,255,255));   //绘制黑棋的刷子  CBrush blackbrush(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);    }    else if(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);    }    else if(m_match.chessboard[i][j]==3)    {     CBrush redbrush(RGB(255,0,0));  //用红色的刷子显示关键的5个棋子     pDC->SelectObject((CBrush*)&redbrush);

 12 
 
    pDC->Ellipse(      j*gridWid+LEFTDIS-gridWid/2,      i*gridWid+TOPDIS-gridWid/2,      j*gridWid+LEFTDIS+gridWid/2,      i*gridWid+TOPDIS+gridWid/2);    }   }   CRect dst;   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); } 
void CFiveChessView::OnSetserver()   //菜单项"开启服务器"的消息处理函数 {  CServerDlg  dlg;  if(dlg.DoModal()==IDOK)        //服务器端口设置对话框  {     m_bIsClient=FALSE;         //做游戏的服务器端     m_bIsInit=TRUE;           //已经初始化     m_port=dlg.m_iPort;          //得到输入的端口号     m_ListenSocket.Init(m_port,this);     //开始监听端口  } }  
void CFiveChessView::OnSetclient()  //菜单项"连接服务器"的消息处理函数 { 
   CClientDlg dlg;      
   int ret=dlg.DoModal();            //设置服务器的IP和端口    if(ret==IDOK)                    //用户点击了"确定"    {     m_bIsClient=TRUE;         //做游戏的服务器端     m_bIsInit=TRUE;          //已经初始化     m_port=dlg.m_iPort;          //得到用户输入的服务器端的端口     for(int i=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("client connection  failed");     }    } } 
void  CFiveChessView::ProcessPendingAccept()           //处理客户端socket连接的函数 { 
   if(m_ListenSocket.Accept(m_ClientSocket)==FALSE)   //分配一个会话socket    {     AfxMessageBox("Sever Listen Socket Error");     return;    }    else    {     m_who=1;                            //服务器端用黑棋,黑棋先行             m_ClientSocket.Init(this);         //初始化会话socket     m_outputedit.SetWindowText("有人进来了");     AfxMessageBox("有人进来了");         } }  
void CFiveChessView::GetLocalIP()  //得到本机的IP地址,调用CClientSocket中的静态函数 {  static BOOL first=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;  } } 
void CFiveChessView::SendInputMsg(CString in)    //在聊天输入框中输入对话的消息函数 { 
// AfxMessageBox("Input Edit");  if(!m_bIsInit)                  //如果网络还没有连接好则不准输入  {   //AfxMessageBox("NO Connection");   

return; 

}  CMessg msg;  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);//发送聊天的内容到另外一端  }   } 
void CFiveChessView::OnInitialUpdate()      //初始化 {    CView::OnInitialUpdate();  static bool oninitialupdatchaving=false;    //只需要初始化调用一次  if(oninitialupdatchaving==false)  {   if(::AfxSocketInit()==FALSE)          //winsock 初始化   {    AfxMessageBox("socket init error");   }   GetLocalIP();                        //得到本机的IP地址   CRect rect;   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);  } } 
void CFiveChessView::OnLButtonDown(UINT nFlags,CPoint point) //处理鼠标左键按下的消息 {  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;       //轮到对方走棋    CMessg msg;    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");    }   }     }

 16 
 
 else  {    
        m_sMsgList+="不该你走棋\r\n"; 
        m_outputedit.SetWindowText(m_sMsgList);     } 
    CView::OnLButtonDown(nFlags,point); } 
void CFiveChessView::OnSize(UINT nType, int cx, int cy)  {  CView::OnSize(nType, cx, cy);    // TODO: Add your message handler code here }  
3、游戏规则及胜负判定 
#include "stdafx.h" #include "FiveChess.h" #include "Match.h"  
#ifdef _DEBUG #undef THIS_FILE 
static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif  
////////////////////////////////////////////////////////////////////// // Construction/Destruction 
//////////////////////////////////////////////////////////////////////  
Match::Match() {  for(int i=0;i<LW;i++)   for(int j=0;j<LW;j++)  {   chessboard[i][j]=0;  }  }  
Match::~Match() {

 17 
 

void Match::Clear() {  for(int i=0;i<LW;i++)   for(int j=0;j<LW;j++)  {   chessboard[i][j]=0;  } } 
BOOL Match::CanDown(int x,int y,int who)//判断在x,y位置是否能落子 {  CString str; 
// str.Format("x:%d    y:%d   chessboard:%d",x,y,chessboard[]); // AfxMessageBox(str);  if(x<0||x>=LW||y<0||y>=LW)   return FALSE;  if(chessboard[y][x]!=0)   return FALSE;  chessboard[y][x]=who;  return TRUE; } 
BOOL Match::IsWin(int who,int x,int y) {  int i=0;  int j=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++;   int count=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;//标记胜出的几颗棋子    return true;   }  }  //垂直方向  for(j=x,i=(y-4>=0?y-4:0);i<(y+4>=LW?LW-1:y+4);i++)  {

while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]!=who)    i++;   int count=0;   while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i++][j]==who)    count++;   if(count>=5)   {    i--;i--;    while(count--)     chessboard[i--][j]=3;//标记胜出的几颗棋子    return true;   }  }  //西北方向  for(j=(x-4>=0?x-4:0),i=(y-4>=0?y-4:0);j<(x+4>=LW?LW-1:x+4)&&i<(y+4>=LW?LW-1:y+4);i++,j++)  {   while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]!=who)    i++,j++;   int count=0;   while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]==who)   {    i++;    j++;    count++;   }   if(count>=5)   {    i--;          
             j--;    while(count--)    {     chessboard[i][j]=3;//标记胜出的几颗棋子     i--;     j--;    }    return true;   }  }  //东北方向  for(j=(x-4>=0?x-4:0),i=(y+4<LW?y+4:LW-1);j<(x+4>=LW?LW-1:x+4)&&i>=0;i--,j++)

{   while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]!=who)    i--,j++;   int count=0;   while(i>=0&&i<LW&&j>=0&&j<LW&&chessboard[i][j]==who)   {    i--;    j++;    count++;   }   if(count>=5)   {    j--;i++;    while(count--)    {     chessboard[i][j]=3;//标记胜出的几颗棋子     i++;     j--;    }    return true;   }  } 
 return false; 

 

posted on 2015-06-21 20:44  莫小兮  阅读(262)  评论(7编辑  收藏  举报