⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fives.c

📁 internet高级编程项目作业之网络五子棋_完整项目发布(文档+程序)20070102
💻 C
📖 第 1 页 / 共 2 页
字号:
//gcc fives.c -o fives#include <fcntl.h>#include <netinet/in.h>#include <unistd.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <sys/select.h>#include <sys/types.h>/////////////////////////////////////#define MAXLEN 1024#define PROTOCOLLEN 24            //协议数据包固定常度(待所有协议确定长度后选定一个最长的,目前最长数据包是24)#define BACKLOG 3#define PORT 55555                //五子棋游戏服务器程序端口#define ROWCOL 20                 //棋盘行列数量,每个棋子所占空格空间,屏幕宽度,屏幕高度-这四个常量定义有关系                                 //棋子放在横竖线的焦点上#define USER1 0                   //用户1编号#define USER2 1                   //用户2编号#define USER_NAME_LEN 5          //用户名字符串长度#define QIPAN_NULL 'N'             //棋盘空位#define QIZI_SIZE 20              //每个棋子所占空格空间#define COLOR_BG  255,255,128      //棋盘背景颜色-黄色#define COLOR_LINE  0,0,0          //棋盘划线颜色-黑色#define COLOR_USER1 255,0,0        //用户1棋子颜色-红色#define COLOR_USER2 0,0,255        //用户2棋子颜色-蓝色#define SCREEN_W 420             //屏幕宽度#define SCREEN_H 420             //屏幕高度#define OFFSET_X QIZI_SIZE        //棋盘划线偏移量x#define OFFSET_Y QIZI_SIZE        //棋盘划线偏移量y#define TITLE_LEN 128             //标题缓冲区长度//服务器端协议编号处理函数定义#define REGIST_USER_NAME 1001     //注册用户姓名p_1001#define SET_QIZI_POSITION 1002     //设置棋子位置p_1002#define GAME_CONTINUE 1003        //继续新一轮游戏p_1003#define NOTE_SERVER_START 1004   //通知服务器游戏可以开始了p_1004//客户端协议编号处理函数定义#define NOTE_USER_OVERFLOW 2001       //提示用户已满u_2001#define NOTE_USER_GAMESTART 2002      //提示用户游戏开始u_2002#define NOTE_USER_WAITFOROTHER 2003   //通知用户连接成功,等待另一个用户连接u_2003#define NOTE_USER_ANOTHEREXIT 2004    //一个用户退出游戏,重设游戏变量,通知另一个用户等待新用户u_2004#define NOTE_USER_RESULT 2005         //通知两个用户本回合棋盘落子情况和获胜情况                                     //若游戏结束,等待用户确认重新开始u_2005#define NOTE_USER_START 2006          //通知用户游戏可以开始了u_2006//游戏状态定义#define GAME_READY 0#define GAME_RUN 1#define GAME_OVER 2///////////////////////////////////////系统变量定义int qipan[ROWCOL][ROWCOL], currentuser;      //棋盘,本回合落子用户int user_fd[2], user_flag[2];                //用户连接号,用户同步等待标志char user_name[2][USER_NAME_LEN];          //用户名字int game_state;                           //游戏状态int *protocol_num;                         //协议编号指针char *protocol_context;                     //协议内容指针int fd_max, fd_listen, fd_conn, selectn, len; //以下是处理用户连接发送命令用的系统变量fd_set set_temp, set_all;char receive_buf[MAXLEN], *temp;char send_buf[MAXLEN];struct sockaddr_in addr_c, addr_s;struct timeval timeout;/////////////////////////////////////////////////系统函数////////////////////////////////////////////////////////处理不同命令请求的代理程序//客户端每增加新的处理请求都需要在双方程序开始增加一个1000开始的协议编号的定义,并在此增加该协议的处理函数void s_delegate(int user, char *buf){  protocol_num=(int *)buf;  switch (*protocol_num)  {    case REGIST_USER_NAME : {//注册用户姓名p_1001                             p_1001(user, buf);                             break;                           }    case SET_QIZI_POSITION : {//设置棋子位置p_1002                             p_1002(user, buf);                             break;                           }    case GAME_CONTINUE :    {//继续新一轮游戏p_1003                             p_1003(user, buf);                             break;                           }    case NOTE_SERVER_START: {//通知服务器游戏可以开始了p_1004                             p_1004(user, buf);                             break;                           }    default : { break;}  }}///////////////////////////////////////初始化游戏s_init(){  memset(qipan, QIPAN_NULL, sizeof(int)*ROWCOL*ROWCOL);//棋盘置空  user_flag[USER1]=0;//用户继续游戏的同步标志  user_flag[USER2]=0;  game_state=GAME_READY;//游戏状态}///////////////////////////////////////////////////游戏处理函数///////////////////////////////////////////////////判断游戏输赢平int g_result(){  //分析棋盘布局,判断游戏输赢平的结果qipan[ROWCOL][ROWCOL]  //若有输赢,返回获胜用户的编号(0,1),若平局返回2,未决出胜负平结果返回-1  int result, row, col;  //默认是平局,平局返回2;如果棋盘还有空白说明肯定未决出胜负,未决出胜负返回-1  result=2;  for(row=0; row<=ROWCOL; row++){    for(col=0; col<=ROWCOL; col++){      if(!(qipan[row][col]==USER1) && !(qipan[row][col]==USER2)){          result=-1;          break;      }    }    if(result==-1) break;  }  //判断双方是否有已经连接成功5个棋子的情况决定是否有胜出者  //横向判断  for(row=0; row<ROWCOL; row++){    for(col=0; col<ROWCOL - 5 + 1; col++){      if((qipan[row][col]==USER1) && (qipan[row][col+1]==USER1) && (qipan[row][col+2]==USER1) \                          && (qipan[row][col+3]==USER1) && (qipan[row][col+4]==USER1))        {result=USER1; return result;}//USER1胜出      if((qipan[row][col]==USER2) && (qipan[row][col+1]==USER2) && (qipan[row][col+2]==USER2) \                          && (qipan[row][col+3]==USER2) && (qipan[row][col+4]==USER2))        {result=USER2; return result;}//USER2胜出    }  }  //纵向判断  for(row=0; row<ROWCOL - 5 + 1; row++){    for(col=0; col<ROWCOL; col++){      if((qipan[row][col]==USER1) && (qipan[row+1][col]==USER1) && (qipan[row+2][col]==USER1) \                          && (qipan[row+3][col]==USER1) && (qipan[row+4][col]==USER1))        {result=USER1; return result;}//USER1胜出      if((qipan[row][col]==USER2) && (qipan[row+1][col]==USER2) && (qipan[row+2][col]==USER2) \                          && (qipan[row+3][col]==USER2) && (qipan[row+4][col]==USER2))        {result=USER2; return result;}//USER2胜出    }  }  //撇向判断  for(row=0; row<ROWCOL - 5 + 1; row++){    for(col=0 + 5 - 1; col<ROWCOL; col++){      if((qipan[row][col]==USER1) && (qipan[row+1][col-1]==USER1) && (qipan[row+2][col-2]==USER1) \                          && (qipan[row+3][col-3]==USER1) && (qipan[row+4][col-4]==USER1))        {result=USER1; return result;}//USER1胜出      if((qipan[row][col]==USER2) && (qipan[row+1][col-1]==USER2) && (qipan[row+2][col-2]==USER2) \                          && (qipan[row+3][col-3]==USER2) && (qipan[row+4][col-4]==USER2))        {result=USER2; return result;}//USER2胜出    }  }  //那向判断  for(row=0; row<ROWCOL - 5 + 1; row++){    for(col=0; col<ROWCOL - 5 + 1; col++){      if((qipan[row][col]==USER1) && (qipan[row+1][col+1]==USER1) && (qipan[row+2][col+2]==USER1) \                          && (qipan[row+3][col+3]==USER1) && (qipan[row+4][col+4]==USER1))        {result=USER1; return result;}//USER1胜出      if((qipan[row][col]==USER2) && (qipan[row+1][col+1]==USER2) && (qipan[row+2][col+2]==USER2) \                          && (qipan[row+3][col+3]==USER2) && (qipan[row+4][col+4]==USER2))        {result=USER2; return result;}//USER2胜出    }  }  //双方都没有获胜的,返回开始默认的平局或者未决出胜负关系  return result;}///////////////////////////////////////////////////用户处理函数///////////////////////////////////////////////////提示用户已满,不能在连接到游戏服务器u_2001(int user_fd){//本函数发送实际有用数据长度是:sizeof(int)=4  protocol_num=(int *)send_buf;  *protocol_num=NOTE_USER_OVERFLOW;//协议号码sizeof(int)  write(user_fd, send_buf, PROTOCOLLEN);  fsync(user_fd);  close(user_fd);}//通知用户游戏开始u_2002(int user){//本函数发送数据长度是:sizeof(int)+sizeof(int)+sizeof(int)+USER_NAME_LEN=22  protocol_num=(int *)send_buf;  *protocol_num=NOTE_USER_GAMESTART;//协议号码sizeof(int)  protocol_num=protocol_num+1;  *protocol_num=user;//分配一个用户编号sizeof(int)  protocol_num=protocol_num+1;  *protocol_num=currentuser;//本回合落子的用户编号sizeof(int)  protocol_num=protocol_num+1;  protocol_context=(char *)protocol_num;  if(user==USER1) bcopy(user_name[USER2], protocol_context, USER_NAME_LEN);//对方姓名USER_NAME_LEN    else bcopy(user_name[USER1], protocol_context, USER_NAME_LEN);  write(user_fd[user], send_buf, PROTOCOLLEN);  fsync(user_fd[user]);}//通知用户连接成功,等待另一个用户连接u_2003(int user){//本函数发送数据长度是:sizeof(int)=4  protocol_num=(int *)send_buf;  *protocol_num=NOTE_USER_WAITFOROTHER;//协议号码sizeof(int)  write(user_fd[user], send_buf, PROTOCOLLEN);  fsync(user_fd[user]);}//一个用户退出游戏,重新设置用户和游戏变量,通知另一个用户等待新的用户到来u_2004(int user){//本函数发送数据长度是:sizeof(int)=4  protocol_num=(int *)send_buf;  *protocol_num=NOTE_USER_ANOTHEREXIT;//协议号码sizeof(int)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -