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:[email protected] 

    > 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:[email protected]

  > 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

你可能感兴趣的:(linux)