本小遊戲是在Linux下實現的(因爲我不會Windows網絡編程),這次實現的僅僅是服務器與客戶端之間進行互動,彼此只要互相發送下點的座標就ok,用結構體存放座標,各自收到座標後進行下子,以及判斷結果。
本篇文章裏只涉及部分代碼,更多是步驟介紹,實現方法以及思路
源碼在這裏()->https://github.com/Xiaoyejun/learngit/commit/44caec515cb7194eb8119ba4c4b3d75473e729d1(綠色部分)
小遊戲介紹
五子棋大家肯定都玩過,無非就是你下子來我來賭,能贏全靠運氣(這裏說的是本人)。要想實現一個簡易的五子棋小遊戲,需要的也就是三點 : 1、棋盤 2、黑子/白子(這裏我們用兩個不同的字符區分黑白方) 3、遊戲規則
遊戲實現
- 首先我們打印一張棋盤,範圍自己控制,我這裏是10*10的棋盤,打印前進行初始化
void InitBoard(char board[ROWS][COLS],int row, int col)
{
//每個座標的初始值我用空格代替
memset(board,' ',row*col*sizeof(char));
}
//打印棋盤
void PrintBoard(char board[ROWS][COLS],int row,int col)
{
int i = 0;
printf(" 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10\n");
for(; i < row;i++)
{
printf("%2d ",i+1);
int j = 0;
for(; j < col;j++)
{
if( j == col-1 )
{
printf(" %c \n",board[i][j]);
if(i != row-1)
printf(" ---|---|---|---|---|---|---|---|---|---\n");
break;
}
printf(" %c ",board[i][j]);
printf("|");
}
}
}
結果
- 遊戲規則:
- 不能下到邊界外
- 不能下到已有子處
- 有一方贏遊戲就結束,或者雙方平局
看起來是不是很簡單,實際上它就是很簡單,因爲這只是1.0版本的,以後我會努力推出高級版本,大家拭目以待。
玩家移動代碼:
//移動
void CommonMove(char board[ROWS][COLS],Point* point,char ch)
{
if(point == NULL)
{
return;
}
int x = point->row;
int y = point->col;
//如果棋盤滿了的話就退出循環,也就是不能再下子了
while(1)
{
if(x >= 0 && x < ROWS && y >= 0 && y < COLS){
if(board[x][y] == ' ')
{
board[x][y] = ch;
point->row = x;
point->col = y;
break;
}
else
{
printf("座標輸入有誤,請重新輸入座標: ");
scanf("%d%d",&x,&y);
x--;
y--;
}
}
else{
printf("座標輸入有誤,請重新輸入座標: ");
scanf("%d%d",&x,&y);
x--;
y--;
}
}
}
//客戶端移動
void ClientMove(char board[ROWS][COLS],Point* point)
{
CommonMove(board,point,'X');
}
//服務器移動
void ServerMove(char board[ROWS][COLS],Point* point)
{
CommonMove(board,point,'O');
}
客戶端和服務器下棋的具體操作是一樣的,只不過需要傳入不一樣的標誌。
- 輸贏判斷
- 實現網絡版
我用的是tcp套接字編程,客戶端和服務器建立連接後,客戶端顯示遊戲菜單,進入遊戲後,客戶端先下棋,然後把下子的座標通過一個結構體發給服務器,服務器向客戶端發送座標時也是如此。
server.c
int main(int argc, char* argv[])
{
if(argc != 3)
{
printf("Usage: ./server [ip] [port]\n");
exit(1);
}
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
perror("socket");
exit(1);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
int ret = bind(sock,(const struct sockaddr*)&server,sizeof(server));
if(ret < 0)
{
perror("bind");
exit(2);
}
ret = listen(sock,5);
if(ret < 0)
{
perror("listen");
exit(3);
}
for(;;)
{
struct sockaddr_in client;
socklen_t len;
int client_sock = accept(sock,(struct sockaddr*)&client,&len);
if(client_sock < 0)
{
continue;
}
ssize_t s;
Point point_server,point_client;
char board[ROWS][COLS];
InitBoard(board,ROWS,COLS);
int x,y;
while(1){
s = read(client_sock,(void*)&point_client,sizeof(point_client));
if(s == 0)
{
printf("Client quit...\n");
close(client_sock);
}
ClientMove(board,&point_client);
PrintBoard(board,ROWS,COLS);
if(GameState(board,&point_client) == 'X')
{
printf("Client win!\n");
break;
}
else if(GameState(board,&point_client) == 'p')
{
printf("平局!\n");
break;
}
printf("請下子(輸入座標)> ");
scanf("%d%d",&x,&y);
point_server.row = x-1;
point_server.col = y-1;
ServerMove(board,&point_server);
PrintBoard(board,ROWS,COLS);
write(client_sock,(void*)&point_server,sizeof(point_server));
if(GameState(board,&point_client) == 'O')
{
printf("You win!\n");
break;
}
else if(GameState(board,&point_client) == 'p')
{
printf("平局!\n");
break;
}
}//遊戲下完了
}
close(sock);
return 0;
}
client.c
void Menu()
{
printf("==================================\n");
printf("|| 1.開始遊戲 0.退出遊戲 ||\n");
printf("==================================\n");
}
void Game(int sock)
{
Point point_server,point_client;
char board[ROWS][COLS];
InitBoard(board,ROWS,COLS);
PrintBoard(board,ROWS,COLS);
ssize_t s;
int x,y;
while(1){
printf("請下子(輸入座標)> ");
scanf("%d%d",&x,&y);
point_client.row = x-1;
point_client.col = y-1;
ClientMove(board,&point_client);
PrintBoard(board,ROWS,COLS);
write(sock,(void*)&point_client,sizeof(point_client));
if(GameState(board,&point_client) == 'X')
{
printf("You win!\n");
break;
}
else if(GameState(board,&point_client) == 'p')
{
printf("平局!\n");
break;
}
s = read(sock,(void*)&point_server,sizeof(point_server));
if(s == 0)
{
printf("Server quit\n");
return;
}
ServerMove(board,&point_server);
PrintBoard(board,ROWS,COLS);
if(GameState(board,&point_server) == 'O')
{
printf("Server win!\n");
break;
}
else if(GameState(board,&point_server) == 'p')
{
printf("平局!\n");
break;
}
}
}
int main(int argc, char* argv[])
{
if(argc != 3)
{
printf("Usage: ./server [ip] [port]\n");
exit(1);
}
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0)
{
perror("socket");
exit(1);
}
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_addr.s_addr = inet_addr(argv[1]);
client.sin_port = htons(atoi(argv[2]));
int ret = connect(sock,(const struct sockaddr*)&client,sizeof(client));
if(ret < 0)
{
perror("connect");
exit(2);
}
Menu();
int state;
while(1)
{
printf("請做出你的選擇> ");
scanf("%d",&state);
if(state == 1)
{
Game(sock);
}else if(state == 0)
{
break;
}
else
{
printf("選擇錯誤\n");
Menu();
sleep(2);
}
}
close(sock);
return 0;
}
- 部分結果演示
客戶端先下棋
下了一會兒以後。。。
客戶端:
服務器: