首页 > 代码库 > 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实现五子棋对战
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。