首页 > 代码库 > Linux网络编程10——使用UDP实现五子棋对战

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("\n");    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("\n");    }    printf("\n");    }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/includegcc -o white *.c -lmy_socket -I/home/purple/include

Linux网络编程10——使用UDP实现五子棋对战