C语言实现简单网络版五子棋(服务器与客户端)

本小游戏是在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;                                                                                                                           
}

  • 部分结果演示

客户端先下棋
这里写图片描述
下了一会儿以后。。。

客户端:
这里写图片描述

服务器:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/IT_xiaoye/article/details/80381439