本小游戏是在Linux下实现的(因为我不会Windows网络编程),这次实现的仅仅是服务器与客户端之间进行互动,彼此只要互相发送下点的坐标就ok,用结构体存放坐标,各自收到坐标后进行下子,以及判断结果。
本篇文章里只涉及部分代码,更多是步骤介绍,实现方法以及思路
源码在这里()->https://github.com/Xiaoyejun/learngit/commit/44caec515cb7194eb8119ba4c4b3d75473e729d1(绿色部分)
五子棋大家肯定都玩过,无非就是你下子来我来赌,能赢全靠运气(这里说的是本人)。要想实现一个简易的五子棋小游戏,需要的也就是三点 : 1、棋盘 2、黑子/白子(这里我们用两个不同的字符区分黑白方) 3、游戏规则
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;
}