日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

windows网络版象棋的实现

發布時間:2024/7/23 windows 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 windows网络版象棋的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

要構建網絡版象棋,首先應該創建服務器與客戶端,建立socket連接

1) 開局,你是什么顏色
2)選擇棋子,
3)走棋
4)悔棋(悔棋悔兩步)
5)認輸

網絡實現:
1)建立連接
a.主機,建立監聽socket
b.accept
c.關閉監聽socket

a.客戶端,連接服務器

2)發送報文
1)服務器給客戶端發送開局報文

2)選棋 發送選棋報文
3)走棋 發送走棋報文

4)悔棋
5)認輸 重新開始

報文格式定義:

第一個字節表示命令字 0表示開具,1表示選其,2表示走棋,3表示悔棋,4表示認輸

開局報文 [0][0或者1] 收到0表示走黑棋,收到1表示走紅旗 [0][0] [0][1]
選棋報文 [1][0~31]
走棋報文 [2][0~31][x][y] x和y已經轉換好的
悔棋 [3]
認輸 [4][0或者1]

運行時設計
定義一個全局變量 char packet[4]用來保存報文
定義一個定時器,每秒去收socket

#ifndef _Net_H__#define _Net_H__#ifdef WIN32#include <WinSock2.h>#else//linux and android#endif // WIN32class Net{public:static SOCKET _server;static SOCKET _connet;static int _isConnected;static int _isRecvComplete;static char* _recvData;static bool Listen(short port=9999);static bool isConnected();static bool Connect(const char*ip,short port=9999);static int Send(const char*buffer,int len);//接收數據的接口static bool RecvStart();static bool isRecvComplete();static char *RecvData(int &len);static DWORD WINAPI AcceptThreadFunc(void *arg);static DWORD WINAPI RecvThreadFunc(void *arg);};#endif

首先,服務器需要listen函數,一直監聽,以得到與客戶端的連接

bool Net::Listen(short port){SOCKET sock=socket(AF_INET,SOCK_STREAM,0);if (sock==INVALID_SOCKET){return false;}struct sockaddr_in addr;addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.S_un.S_addr=INADDR_ANY;int ret=bind(sock,(struct sockaddr*)&addr,sizeof(addr));if (ret != 0){closesocket(sock);return false;}listen(sock,10); //10 means listen count//create a therad to accept socket_server = sock;_isConnected = 0;HANDLE hThread = CreateThread(NULL, 0, AcceptThreadFunc, NULL, 0, NULL);CloseHandle(hThread);return true;}DWORD Net::AcceptThreadFunc(void *arg){_connet = accept(_server, NULL, NULL);_isConnected = 1;return 0;}

客戶端則需要connect函數與服務器建立連接

bool Net::Connect(const char*ip,short port){_connet=socket(AF_INET,SOCK_STREAM,0);if (_connet==INVALID_SOCKET){return false;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.S_un.S_addr = inet_addr(ip);int ret = connect(_connet, (struct sockaddr*)&addr, sizeof(addr));if (ret != 0){closesocket(_connet);return false;}return true;}

如果建立連接成功,則可以互相傳遞數據了,此時服務器可以關閉連接監聽

void SceneGame::startServer(CCObject*){_bredSide=true;Net::Listen();schedule(schedule_selector(SceneGame::CheckListen));}void SceneGame::CheckListen(float){if (Net::isConnected()){unschedule(schedule_selector(SceneGame::CheckListen));//game start and do some initiate gameCCLog("server start game\n");}}

服務器與客戶端互相發送數據,需要send函數

int Net::Send(const char*buffer,int len){return send(_connet,buffer,len,0);}

接收數據需要receve函數保持監聽

bool Net::RecvStart(){_isRecvComplete=0;HANDLE hThread=CreateThread(NULL,0,RecvThreadFunc,NULL,0,NULL);CloseHandle(hThread);return true;}bool Net::isRecvComplete(){return _isRecvComplete;}char *Net::RecvData(int &len){len=0;_isRecvComplete=0;return _recvData;}DWORD Net::RecvThreadFunc(void *arg){static char buf[16];recv(_connet,buf,1,0);if (buf[0]==1){recv(_connet,&buf[1],1,0);}else if(buf[0]==2){for (int i=1;i<=3;i++){recv(_connet,&buf[i],1,0);}}//stop receve_recvData=buf;_isRecvComplete=1;return 0;}

在象棋中調用發送數據,發送完畢之后輪到對方走了,此時要打開接收數據監聽

//send stepStep* step = *_steps.rbegin();char buf[4];buf[0] = 2;buf[1] = step->moveid;buf[2] = step->rowTo;buf[3] = step->colTo;Net::Send(buf, 4);//receive messageNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));

接收到數據之后要關閉接收監聽,然后開始發送數據,象棋根據傳遞的報文判斷對方的信息,分別以1,2,3開頭,表示選擇,走棋,其中1與3還需要繼續接收數據,2可以關閉數據接收。

void SceneGame::CheckRecv(float){if (Net::isRecvComplete()){unschedule(schedule_selector(SceneGame::CheckRecv));int len;char *data=Net::RecvData(len);//accord to the data protocoal do some workif (data[0]==1){//selected _selectid=data[1];_selectSprite->setPosition(_s[_selectid]->fromPlate());_selectSprite->setVisible(true);//continue receiveNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));}else if(data[0]==2){//move stoneStone* s = _s[data[1]];int row = 9 - data[2];int col = 8 - data[3];int killid = getStoneFromRowCol(row, col);recordStep(_selectid, killid, _s[_selectid]->_row, _s[_selectid]->_col, row, col);// 移動棋子s->_row = row;s->_col = col;s->setPosition(s->fromPlate());if (killid != -1){Stone* ks = _s[killid];ks->_dead = true;ks->setVisible(false);}_selectid = -1;_selectSprite->setVisible(false);_bRedTurn = !_bRedTurn;}else if(data[0]==3){doRegret2();//continue receiveNet::RecvStart();schedule(schedule_selector(SceneGame::CheckRecv));}}}

總結

以上是生活随笔為你收集整理的windows网络版象棋的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。