这是一个专门用做会话类,它负责数据的发送和接受。她继承于CSocket,负责响应OnReceive和OnClose消息。另外,作为CSocket类的继承类,当然采用了串行化方式来处理网络数据。网络数据由CMessg对象构成。连接服务器所需参数通过对话框获得,如图4-4: 内容来自www.paper51.com copyright paper51.com 图4-4 客户端设置图 paper51.com CClientSocket类中需要数据串行化网络数据。类初始化成员Init函数负责Socket和串行化相关的初始化;成员函数GetIpAddress用于获得本地IP;成员函数GetLocalHostName用于获得本地计算机名称;当连接上服务器以后,使用SendMessage(CMessg * msg) 发送消息,或者使用OnReceive(intnErrorCode)接收对方发送过来的数据,并对数据进行处理。当关闭客户端Socket是使用成员函数CloseSocket关闭。 copyright paper51.com void CClientSocket::OnReceive(int nErrorCode) 内容来自www.paper51.com
{ paper51.com
CSocket::OnReceive(nErrorCode); 内容来自www.paper51.com do copyright paper51.com { 内容来自论文无忧网 www.paper51.com CMessgtemp; 内容来自论文无忧网 www.paper51.com temp.Serialize(*m_aSessionIn);//输入数据串行化 copyright paper51.com //判断对方发送过来的数据是否是落子的位置 if(m_view->m_match.CanDown(temp.m_x,temp.m_y,m_view->m_who%2+1)) paper51.com
{//是对方落子的信息 http://www.paper51.com m_view->m_turn=temp.m_turn;//轮到我下 paper51.com m_view->Invalidate(FALSE);//刷新视图,显示对方的走子位置 http://www.paper51.com if(m_view->m_match.IsWin(m_view->m_who%2+1,m_view->m_winpos)) 内容来自论文无忧网 www.paper51.com
{ paper51.com
m_view->m_bWin=TRUE;//对方赢 paper51.com m_view->m_bOver=TRUE; 内容来自www.paper51.com m_view->Invalidate(FALSE); 内容来自www.paper51.com AfxMessageBox("SORRY,你输了"); 内容来自论文无忧网 www.paper51.com } paper51.com } 内容来自论文无忧网 www.paper51.com } 内容来自论文无忧网 www.paper51.com while(!m_aSessionIn->IsBufferEmpty()); 内容来自论文无忧网 www.paper51.com } paper51.com BOOL CClientSocket::SendMessage(CMessg * msg) paper51.com { http://www.paper51.com if(m_aSessionOut != NULL) 内容来自www.paper51.com { copyright paper51.com
msg->Serialize(*m_aSessionOut);//输出串行化 内容来自www.paper51.com m_aSessionOut->Flush();//直接发送 内容来自www.paper51.com
returnTRUE; http://www.paper51.com } 内容来自论文无忧网 www.paper51.com else http://www.paper51.com { http://www.paper51.com
//对方关闭了连接 http://www.paper51.com m_bClose=true; paper51.com CloseSocket(); copyright paper51.com returnFALSE; copyright paper51.com
} paper51.com } http://www.paper51.com 4.3.3 网络信息——CMessg类的实现 内容来自www.paper51.com 这是一个数据类,继承于CObject.它主要负责串行化数据的作用。CMessg类主要的成员变量: paper51.com int m_turn; copyright paper51.com int m_x; 内容来自www.paper51.com
int m_y; paper51.com 其中m_turn表示轮到谁走棋;m_x 表示落子的水平位置;m_y表示落子的竖直位置。这3个数据就是网络要传的数据。 copyright paper51.com 其中数据串行化实现如下: copyright paper51.com void CMessg::Serialize(CArchive& ar) 内容来自论文无忧网 www.paper51.com { 内容来自www.paper51.com
if(ar.IsStoring()) 内容来自论文无忧网 www.paper51.com { 内容来自www.paper51.com ar<< m_turn; 内容来自www.paper51.com ar<< m_x; paper51.com ar<< m_y; copyright paper51.com
} http://www.paper51.com else http://www.paper51.com { copyright paper51.com ar>> m_turn; paper51.com ar>> m_x; paper51.com ar>> m_y; 内容来自论文无忧网 www.paper51.com } 内容来自论文无忧网 www.paper51.com
} 内容来自www.paper51.com 4.3.4 下棋算法——Match类的实现 paper51.com
这是一个规则类,它负责规则的处理。在Match中保存着一个当前的棋盘,用的一个chessboard[LW][LW]。如果数组元素为0,则表示没有棋子;如果为1,则表示有黑子,如果为2,则为白子。Match负责是否能下子,是否有人赢棋。 http://www.paper51.com Match中类LW定为19,表示有19行19列。既然Match中保存着一个当前棋盘,那就需要有一个判断的成员函数,只有chessboard为0时才能落子,类中使用成员函数CanDown(int x,int y,int who)判断能否落子。并且有一个判断是否赢的成员函数IsWin(int who,int pos[5][2]);其中pos[5][2]为记录赢的关键棋子。最后还有一个清除棋盘也就是把所有的chessboard全部设置为0的函数Clear。算法执行出来的结果,如图4-5: paper51.com
内容来自www.paper51.com
图4-5 赢棋图 http://www.paper51.com 五子棋的核心算法IsWin主要是判断了水平、垂直、东南、东北四个方向是否有五子相连;它们判定条件可以表示为; paper51.com 水平: http://www.paper51.com chessboard[i][j+1]==who&&chessboard[i][j+2]==who&&chessboard[i][j+3]==who&&chessboard[i][j+4]==who paper51.com
垂直: 内容来自www.paper51.com
chessboard[i+1][j]==who&&chessboard[i+2][j]==who&&chessboard[i+3][j]==who&&chessboard[i+4][j]==who paper51.com
东南: paper51.com chessboard[i+1][j+1]==who&&chessboard[i+2][j+2]==who&&chessboard[i+3][j+3]==who&&chessboard[i+4][j+4]==who http://www.paper51.com 东北: http://www.paper51.com chessboard[i-1][j+1]==who&&chessboard[i-2][j+2]==who&&chessboard[i-3][j+3]==who&&chessboard[i-4][j+4]==who paper51.com |