zoukankan      html  css  js  c++  java
  • Linux网络编程10——使用UDP实现五子棋对战

    思路

    1. 通信

    为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置。msg结构体如下:

    /* 用于发给对方的信息 */
    typedef struct tag_msg
    {
        int msg_type;   /* 悔棋? */
        int msg_color;
        int msg_row;
        int msg_col;
    }MSG, *pMSG;

    2. 悔棋

    用链表头插法来模拟栈,链表记录了双方下子的轨迹。结构如下:

    /* 记录每一步的轨迹 */
    typedef struct tag_trace
    {
        int tr_cow;
        int tr_col;
        char tr_before[4]; /* 记录原来该位置的内容。注意要存下之前的!! */
        struct tag_trace* tr_next;
    }TRACE, *pTRACE;

    使用两个链表,一个链表用于记录自己下棋的轨迹,便于自己悔棋;另一个链表用于记录对方下棋的轨迹,便于对方悔棋。

    3. 判断胜负

    以水平方向为例:需要判断该棋子(包括该子)左边有多少相同颜色的棋子相连,以及右边有多少相同颜色的棋子相连,两者相加如果和大于等于5,则判赢。其余3个方向类似。具体可以参加代码。

    4. 本代码用到了Linux网络编程9——对TCP与UDP的简易封装2.0中的动态库文件。

    代码

    chess.h

    #ifndef __MY_CHESS_H__
    #define __MY_CHESS_H__
    #include "my_socket.h"
    #include <pthread.h>
    
    #define MSG_NORMAL 1
    #define MSG_BACK  2
    #define CH_BLACK 1
    #define CH_WHITE 2
    #define ROW 19
    #define COL 19
    #define WHITE_CHESS    "○"
    #define BLACK_CHESS     "●"
    
    typedef struct tag_msg
    {
        int msg_type ;
        int msg_color ;
        int msg_row ;
        int msg_col ;
    }MSG, *pMSG ;
    
    typedef struct tag_trace
    {
        int tr_row ;
        int tr_col ;
        char tr_before[4] ;
        struct tag_trace* tr_next ;
    }TRACE, *pTRACE;
    
    void chess_show(char ch[][COL][4], int row);
    int chess_win(char arr[][COL][4], int row, int pos_x, int pos_y, char* color);
    
    #endif

    chess.c

    /*************************************************************************
        > File Name: chess.c
        > Author: KrisChou
        > Mail:zhoujx0219@163.com 
        > Created Time: Wed 03 Sep 2014 09:35:57 PM CST
     ************************************************************************/
    #include "chess.h"
    
    void chess_show(char arr[][COL][4], int row_cnt)
    {
        int row, col  ; 
        printf("   ");
        for(col = 0; col < COL ; col ++)
        {
            printf("%2d", col + 1);
        }
        printf("
    ");
        for(row = 0; row < row_cnt ; row ++)
        {
            printf("%3d ", row + 1);
            for(col = 0; col < COL ; col ++)
            {
                printf("%s",  arr[row][col]);
                if(col != row_cnt  -1 )
                {
                    printf("-");
                }
            }
            printf("
    ");
        }
        printf("
    ");
        
    }
    int chess_win(char arr[][COL][4], int row, int pos_x, int pos_y, char* color)
    {    
        // level
        int cnt1, cnt2 ;
        int index_x, index_y ;
        for(cnt1 = 0,index_x = pos_x, index_y = pos_y; index_y < COL; index_y ++)
        {
            if(strcmp(arr[index_x][index_y], color) == 0)
            {
                cnt1 ++ ;
            }else
            {
                break ;
            }
        }
        for(cnt2 = 0, index_x = pos_x , index_y = pos_y - 1 ; index_y >= 0; index_y --)
        {
            if(strcmp(arr[index_x][index_y], color) == 0)
            {
                cnt2 ++ ;
            }else
            {
                break ;
            }
        }
        if(cnt1 + cnt2 >= 5)
        {
            return 1 ;
        }
        // vertical
        for(cnt1 = 0,index_x = pos_x, index_y = pos_y; index_x >= 0; index_x --)
        {
            if(strcmp(arr[index_x][index_y], color) == 0)
            {
                cnt1 ++ ;
            }else
            {
                break ;
            }
        }
        for(cnt2 = 0, index_x = pos_x + 1 , index_y = pos_y  ; index_x < row ; index_x ++)
        {
            if(strcmp(arr[index_x][index_y], color) == 0)
            {
                cnt2 ++ ;
            }else
            {
                break ;
            }
        }
        if(cnt1 + cnt2 >= 5)
        {
            return 1 ;
        }
        // + ==
        int sum = pos_x + pos_y ;
        for(cnt1 = 0, index_x = pos_x; index_x >= 0 && sum - index_x < COL; index_x --)
        {
            if(strcmp(arr[index_x][sum - index_x], color) == 0)
            {
                cnt1 ++ ;
            }else
            {
                break ;
            }
        }
        for(cnt2 = 0, index_x = pos_x + 1; index_x < row && index_x <= sum ; index_x ++ )
        {
            if(strcmp(arr[index_x][sum - index_x], color) == 0)
            {
                cnt2 ++ ;
            }else 
            {
                break ;
            }
        }
        if(cnt1 + cnt2 >= 5)
        {
            return 1 ;
        }
        // abs - ==
        int delt ;
        if(pos_x > pos_y)
        {
            delt = pos_x - pos_y ;
            for(cnt1 = 0 , index_x = pos_x; index_x >=0 && index_x >= delt; index_x --)
            {
                if(strcmp(arr[index_x][index_x - delt], color) == 0)
                {
                    cnt1 ++ ;
                }else 
                {
                    break ;
                }
            }
            for(cnt2 = 0, index_x = pos_x + 1; index_x < row ; index_x ++)
            {
                if(strcmp(arr[index_x][index_x - delt], color) == 0)
                {
                    cnt2 ++ ;
                }else 
                {
                    break ;
                }
            }
        }else// pos_y >= pos_x 
        {
            delt = pos_y - pos_x ;
            for(cnt1 = 0 , index_x = pos_x; index_x >=0 ; index_x --)
            {
                if(strcmp(arr[index_x][index_x +  delt], color) == 0)
                {
                    cnt1 ++ ;
                }else 
                {
                    break ;
                }
            }
            for(cnt2 = 0, index_x = pos_x + 1; index_x < row && index_x + delt < COL ; index_x ++)
            {
                if(strcmp(arr[index_x][index_x + delt], color) == 0)
                {
                    cnt2 ++ ;
                }else 
                {
                    break ;
                }
            }
        }
        if(cnt1 + cnt2 >= 5)
        {
            return 1 ;
        }
        return 0;
    }

    main.c

    /*************************************************************************
      > File Name: main.c
      > Author: KrisChou
      > Mail:zhoujx0219@163.com
      > Created Time: Wed 03 Sep 2014 10:04:07 PM CST
     ************************************************************************/
    #include "chess.h"
    #define B_IP "127.0.0.1"
    #define B_PORT 8888
    #define W_IP "127.0.0.1"
    #define W_PORT 6666
    #define POS_TRANS(pos)  (pos -1)
    #define IS_OK(row, col) (  row >= 0 && col >= 0 && col <= 18 &&row <= 18 &&strcmp(my_chess[row][col], WHITE_CHESS) != 0 && strcmp(my_chess[row][col], BLACK_CHESS) != 0)
    int main(int argc, char* argv[])
    {
        char my_chess[ROW][COL][4] = 
        {
            "","","","","","","","","","","","","","","","","","","" , 
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","","" ,
            "","","","","","","","","","","","","","","","","","",""   
    
        };
        int sfd ;
        pTRACE my_tr, peer_tr, pStep, pTmp ;
    
        my_tr = NULL ;
        peer_tr = NULL ;
    #ifdef FIRST
        my_socket(&sfd, MY_UDP, B_IP, B_PORT);
    #else
        my_socket(&sfd, MY_UDP, W_IP, W_PORT);
    #endif
        int row, col ;
        MSG my_msg ;
    #ifdef FIRST
        chess_show(my_chess, ROW);
        while(1)// 0, 0
        {
            do
            {
                printf(">>");
                scanf("%d%d", &row, &col);
                if(row == 0 || col == 0)
                {
                    break ;
                }
            }while( !IS_OK(POS_TRANS(row), POS_TRANS(col))) ;
            if(row !=0 && col != 0)// normal
            {
                my_msg.msg_type = MSG_NORMAL ;
                my_msg.msg_color = CH_BLACK ;
                my_msg.msg_row = POS_TRANS(row) ;
                my_msg.msg_col = POS_TRANS(col) ;
                my_sendto(NULL, sfd, &my_msg, sizeof(MSG), W_IP, W_PORT);
    
                pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                pStep ->tr_row = POS_TRANS(row) ;
                pStep ->tr_col = POS_TRANS(col) ;
                strcpy(pStep ->tr_before, my_chess[POS_TRANS(row)][POS_TRANS(col)]) ;
    
                pStep -> tr_next = my_tr ;
                my_tr = pStep ;
    
                strcpy(my_chess[POS_TRANS(row)][POS_TRANS(col)], BLACK_CHESS);
    
    
                system("clear");
                chess_show(my_chess, ROW);
                if(chess_win(my_chess, ROW, POS_TRANS(row), POS_TRANS(col), BLACK_CHESS))
                {
                    printf("black win !");
                    exit(1);
                }
            }else 
            {
                if(my_tr == NULL)
                {
                    continue ;
                }else
                {
                    memset(&my_msg, 0, sizeof(MSG));
                    my_msg.msg_type = MSG_BACK ;
                    my_sendto(NULL, sfd, &my_msg, sizeof(MSG), W_IP, W_PORT);
                    strcpy(my_chess[my_tr -> tr_row][my_tr -> tr_col], my_tr ->tr_before);
                    system("clear");
                    chess_show(my_chess, ROW);
    
                    pTmp = my_tr ;
                    my_tr = my_tr -> tr_next ;
                    free(pTmp);
                    pTmp = NULL ;
    
                    /* 本方悔棋后,需要在下一次 */
                    do{
                        printf(">>");
                        scanf("%d%d", &row, &col);
                    }while( !IS_OK(POS_TRANS(row), POS_TRANS(col))) ;
    
    
                    my_msg.msg_type = MSG_NORMAL ;
                    my_msg.msg_color = CH_BLACK ;
                    my_msg.msg_row = POS_TRANS(row) ;
                    my_msg.msg_col = POS_TRANS(col) ;
                    my_sendto(NULL, sfd, &my_msg, sizeof(MSG), W_IP, W_PORT);
    
                    pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                    pStep ->tr_row = POS_TRANS(row) ;
                    pStep ->tr_col = POS_TRANS(col) ;
                    strcpy(pStep ->tr_before, my_chess[POS_TRANS(row)][POS_TRANS(col)]) ;
    
                    pStep -> tr_next = my_tr ;
                    my_tr = pStep ;
    
                    strcpy(my_chess[POS_TRANS(row)][POS_TRANS(col)], BLACK_CHESS);
    
    
                    system("clear");
                    chess_show(my_chess, ROW);
                    if(chess_win(my_chess, ROW, POS_TRANS(row), POS_TRANS(col), BLACK_CHESS))
                    {
                        printf("black win !");
                        exit(1);
                    }
    
                }
            }
    
            memset(&my_msg, 0, sizeof(MSG));
            my_recvfrom(NULL, sfd, &my_msg, sizeof(MSG), NULL, NULL);    
            if(my_msg.msg_type == MSG_NORMAL)
            {
                pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                pStep ->tr_row = my_msg.msg_row ;
                pStep ->tr_col = my_msg.msg_col ;
                strcpy(pStep ->tr_before, my_chess[my_msg.msg_row][my_msg.msg_col]) ;
                pStep -> tr_next = peer_tr; 
                peer_tr = pStep ;
    
    
                strcpy(my_chess[my_msg.msg_row][my_msg.msg_col], WHITE_CHESS);
                system("clear");
                chess_show(my_chess, ROW);
                if(chess_win(my_chess, ROW, my_msg.msg_row, my_msg.msg_col, WHITE_CHESS))
                {
                    printf("white win !");
                    exit(1);
                }
            }else if(my_msg.msg_type == MSG_BACK)
            {
                    strcpy(my_chess[peer_tr -> tr_row][peer_tr -> tr_col], peer_tr ->tr_before);
                    system("clear");
                    chess_show(my_chess, ROW);
    
                    pTmp = peer_tr ;
                    peer_tr = peer_tr -> tr_next ;
                    free(pTmp);
                    pTmp = NULL ;
                    
                    /* 对方悔棋后,本方需要再收一次 */
                    memset(&my_msg, 0, sizeof(MSG));
                    my_recvfrom(NULL, sfd, &my_msg, sizeof(MSG), NULL, NULL);    
    
                    pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                    pStep ->tr_row = my_msg.msg_row ;
                    pStep ->tr_col = my_msg.msg_col ;
                    strcpy(pStep ->tr_before, my_chess[my_msg.msg_row][my_msg.msg_col]) ;
                    pStep -> tr_next = peer_tr; 
                    peer_tr = pStep ;
    
                    strcpy(my_chess[my_msg.msg_row][my_msg.msg_col], WHITE_CHESS);
                    system("clear");
                    chess_show(my_chess, ROW);
                    if(chess_win(my_chess, ROW, my_msg.msg_row, my_msg.msg_col, WHITE_CHESS))
                    {
                        printf("white win !");
                        exit(1);
                    }
            }
        }
    #else
        {
            chess_show(my_chess, ROW);
            while(1)
            {
                memset(&my_msg, 0, sizeof(MSG));
                my_recvfrom(NULL, sfd, &my_msg, sizeof(MSG), NULL, NULL);
                if(my_msg.msg_type == MSG_NORMAL)
                {
    
                    pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                    pStep ->tr_row = my_msg.msg_row ;
                    pStep ->tr_col = my_msg.msg_col ;
                    strcpy(pStep ->tr_before, my_chess[my_msg.msg_row][my_msg.msg_col]) ;
                    pStep -> tr_next = peer_tr; 
                    peer_tr = pStep ;
    
    
    
                    strcpy(my_chess[my_msg.msg_row][my_msg.msg_col], BLACK_CHESS);
                    system("clear");
                    chess_show(my_chess, ROW);
                    if(chess_win(my_chess, ROW, my_msg.msg_row, my_msg.msg_col, BLACK_CHESS))
                    {
                        printf("black win !");
                        exit(1);
                    }
    
                }else if(my_msg.msg_type ==  MSG_BACK)
                {
                    strcpy(my_chess[peer_tr -> tr_row][peer_tr -> tr_col], peer_tr ->tr_before);
                    system("clear");
                    chess_show(my_chess, ROW);
    
                    pTmp = peer_tr ;
                    peer_tr = peer_tr -> tr_next ;
                    free(pTmp);
                    pTmp = NULL ;
    
                    memset(&my_msg, 0, sizeof(MSG));
                    my_recvfrom(NULL, sfd, &my_msg, sizeof(MSG), NULL, NULL);    
    
                    pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                    pStep ->tr_row = my_msg.msg_row ;
                    pStep ->tr_col = my_msg.msg_col ;
                    strcpy(pStep ->tr_before, my_chess[my_msg.msg_row][my_msg.msg_col]) ;
                    pStep -> tr_next = peer_tr; 
                    peer_tr = pStep ;
    
                    strcpy(my_chess[my_msg.msg_row][my_msg.msg_col], BLACK_CHESS);
                    system("clear");
                    chess_show(my_chess, ROW);
                    if(chess_win(my_chess, ROW, my_msg.msg_row, my_msg.msg_col, BLACK_CHESS))
                    {
                        printf("black win !");
                        exit(1);
                    }
    
    
                }
    
                    do{
                        printf(">>");
                        scanf("%d%d", &row, &col);
                        if(row == 0 || col == 0)
                        {
                            break ;
                        }
                    }while(!IS_OK(POS_TRANS(row), POS_TRANS(col))) ;
                    if(row != 0 && col != 0 )//normal
                    {
                        my_msg.msg_type = MSG_NORMAL ;
                        my_msg.msg_color = CH_WHITE ;
                        my_msg.msg_row = POS_TRANS(row) ;
                        my_msg.msg_col = POS_TRANS(col) ;
                        my_sendto(NULL, sfd, &my_msg, sizeof(MSG), B_IP, B_PORT);
    
    
                        pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                        pStep ->tr_row = POS_TRANS(row) ;
                        pStep ->tr_col = POS_TRANS(col) ;
                        strcpy(pStep ->tr_before, my_chess[POS_TRANS(row)][POS_TRANS(col)]) ;
    
                        pStep -> tr_next = my_tr ;
                        my_tr = pStep ;
    
                        strcpy(my_chess[POS_TRANS(row)][POS_TRANS(col)], WHITE_CHESS);
                        system("clear");
                        chess_show(my_chess, ROW);
                        if(chess_win(my_chess, ROW, POS_TRANS(row), POS_TRANS(col), WHITE_CHESS))
                        {
                            printf("white win !");
                            exit(1);
                        }
    
                    }else
                    {
                        if(my_tr == NULL)
                        {
                            continue ;
                        }else
                        {
                            memset(&my_msg, 0, sizeof(MSG));
                            my_msg.msg_type = MSG_BACK ;
                            my_sendto(NULL, sfd, &my_msg, sizeof(MSG), B_IP, B_PORT);
                            strcpy(my_chess[my_tr -> tr_row][my_tr -> tr_col], my_tr ->tr_before);
                            system("clear");
                            chess_show(my_chess, ROW);
    
                            pTmp = my_tr ;
                            my_tr = my_tr -> tr_next ;
                            free(pTmp);
                            pTmp = NULL ;
                            
                            do{
                                printf(">>");
                                scanf("%d%d", &row, &col);
                            }while(!IS_OK(POS_TRANS(row), POS_TRANS(col)) );
                                
                        my_msg.msg_type = MSG_NORMAL ;
                        my_msg.msg_color = CH_WHITE ;
                        my_msg.msg_row = POS_TRANS(row) ;
                        my_msg.msg_col = POS_TRANS(col) ;
                        my_sendto(NULL, sfd, &my_msg, sizeof(MSG), B_IP, B_PORT);
    
    
                        pStep = (pTRACE)calloc(1, sizeof(TRACE)) ;
                        pStep ->tr_row = POS_TRANS(row) ;
                        pStep ->tr_col = POS_TRANS(col) ;
                        strcpy(pStep ->tr_before, my_chess[POS_TRANS(row)][POS_TRANS(col)]) ;
    
                        pStep -> tr_next = my_tr ;
                        my_tr = pStep ;
    
                        strcpy(my_chess[POS_TRANS(row)][POS_TRANS(col)], WHITE_CHESS);
                        system("clear");
                        chess_show(my_chess, ROW);
                        if(chess_win(my_chess, ROW, POS_TRANS(row), POS_TRANS(col), WHITE_CHESS))
                        {
                            printf("white win !");
                            exit(1);
                        }
    
                        }
                        
                    }
            }
    
        }
    #endif
        return 0 ;
    }

    编译如下:

    gcc -o black *.c -DFIRST -lmy_socket -I/home/purple/include
    gcc -o white *.c -lmy_socket -I/home/purple/include
  • 相关阅读:
    HTTPS的七个误解(译文)
    WebLogic 11g重置用户密码
    IT项目管理工具
    Encrypt and Decrypt
    Tomcat Introduction
    浅谈https\ssl\数字证书
    What is POID
    数字签名和数字证书
    Apache Axis2 Practice
    Web Performance Tips
  • 原文地址:https://www.cnblogs.com/jianxinzhou/p/3956892.html
Copyright © 2011-2022 走看看