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

📄 bnserver.c

📁 网络战船游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Batalla Naval (c) 1995,1996,1997 Ricardo Quesada  * (rquesada@dc.uba.ar) *  * Servidor para Linux * version: 0.60 *   * Modificaciones para adaptar cliente Win16 por: * Horacio Pe馻 ( horape@balug.org.ar ) *  *//* INCLUDES */#include <ncurses.h>                   /* new on v0.41 */#include <sys/types.h>#include <sys/socket.h>#include <sys/resource.h>#include <unistd.h>#include <netinet/in.h>#include <stdio.h>#include <syslog.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <stdarg.h>                    /* new on v0.41 */#include "../share/protocol.h"         /* definicion del protocolo */#ifdef WDEBUG#include <sys/stat.h>#include <fcntl.h>#endif/* DEFINES */#define BN_SVER  "0.60"#define BNVERH 0#define BNVERL 60#define MAXPLAYER 5/* VARIABLES GLOBALES y STRUCT y TYPEDEF y ... */WINDOW *windows[MAXPLAYER];WINDOW *titles[MAXPLAYER];WINDOW *title;typedef struct tabla_typ {   int  x,y;   char p[10][10];} tabla,*tabla_ptr;struct datos {   char server_name[50];       /* server name */   int port;                   /* donde va el port */   int debug;                  /* debug mode */   int nro_tot[MAXPLAYER];     /* 1 int por jugador */   int nro_fd[MAXPLAYER];      /* 1 file descriptor por jugador */   int hits[MAXPLAYER];        /* how many hits has a player received */   tabla table[MAXPLAYER];   char names[MAXPLAYER][MAXNAMELEN]; /* other players's name  new on v0.36 */} usuario,*usuario_ptr;fd_set test_set, ready_set;     /* here is new on v0.35 */int temp;                       /* variable temporal */char tempbuf[MSGMAXLEN];        /* varible general *//***************************************************************************** *                                   FUNCIONES *****************************************************************************//*****************************************************************************  *                           funciones TCP/IP ***************************************************************************/void bnwrite(int fde,char *buf,char tip0,char tip1,char tip2,char jugyo ) {   int i;   struct protocolo proto;      proto.bnptip0=tip0;   proto.bnptip1=tip1;   proto.bnptip2=tip2;   proto.jugador=jugyo;   for(i=0;i<MSGMAXLEN;i++)     proto.bnpmsg[i]=buf[i];   strcpy(proto.bnphead,BNPHEAD);   proto.bnpver=BNPVER;   write(fde,&proto,MAXLEN);}/* manda el mensaje msg a todos los que cumplan nro_tot>=yes menos a no */void broadcast(char *msg,char tip0,int yes, int no,char tip1,char tip2,char jugyo) {         /* new on v0.34 */   char msgnew[MSGMAXLEN];   int i;      for(i=0;i<MSGMAXLEN;i++)     msgnew[i]=msg[i];      for(i=0;i<MAXPLAYER;i++)      {	if(i!=no) 	  {	     if(usuario.nro_tot[i]>=yes) 	       {		  bnwrite(usuario.nro_fd[i],msg,tip0,tip1,tip2,jugyo);	       }	  }     }}/*****************************************************************************  *                              CHEQUEO DE ALGORITOMO ****************************************************************************//* points to next pos.return TRUE . FALSE in case there are no more ships *//* this rutine uses global x,y */int nextbarco(int num_jug) {   if(usuario.table[num_jug].x==9)      {	usuario.table[num_jug].x=0;	usuario.table[num_jug].y++;     }   else      usuario.table[num_jug].x++;   if( usuario.table[num_jug].y==10 )      return FALSE;   else      return TRUE;}    	/* return TRUE if in (x,y) hay barco. else FALSE *//* this rutine uses local x,y */int haybarco( int x, int y,int num_jug) {   if( (x < 0) || ( x > 9 ) || (y < 0) || (y >9 ) )     return FALSE;   if( usuario.table[num_jug].p[x][y]>=BARCO ) /* new on v0.45 */     return TRUE;   if( usuario.table[num_jug].p[x][y]<=NOBARCO )     return FALSE;   return FALSE;}/* return TRUE if table is OK .else return FALSE  */int algoritmo(int num_jug)  {   int i,xx,yy,barcos,subarco;   int barquitos[4];      for(i=0;i<4;i++)      barquitos[i]=0;      /* global x,y */   usuario.table[num_jug].x=0;   usuario.table[num_jug].y=0;   barcos=0;      for(;;)      {	if(haybarco(usuario.table[num_jug].x,usuario.table[num_jug].y,num_jug)==FALSE) 	  {	     if(nextbarco(num_jug)==FALSE) 	       {		  if( (barquitos[3]==1) && (barquitos[2]==2) && (barquitos[1]==3) && (barquitos[0]==4) ) 		    {		       return TRUE;         /* tabla bien puesta */		    }		  else 		    {		       return FALSE;		    }	       }	  }	else 	  { 	     if( haybarco(usuario.table[num_jug].x,usuario.table[num_jug].y,num_jug)==TRUE )  	       {		  if( (haybarco(usuario.table[num_jug].x,usuario.table[num_jug].y-1,num_jug)==FALSE) && (haybarco(usuario.table[num_jug].x-1,usuario.table[num_jug].y,num_jug)==FALSE) ) 		    {		       subarco=1;		       barcos++;		       xx=usuario.table[num_jug].x;yy=usuario.table[num_jug].y;		       		       for(;;) 			 {			    if( (haybarco(usuario.table[num_jug].x-1,usuario.table[num_jug].y+1,num_jug)==TRUE) || (haybarco(usuario.table[num_jug].x+1,usuario.table[num_jug].y+1,num_jug)==TRUE) ) 			      {				 return FALSE;			      }			    if( (haybarco(usuario.table[num_jug].x+1,usuario.table[num_jug].y,num_jug)==FALSE) && (haybarco(usuario.table[num_jug].x,usuario.table[num_jug].y+1,num_jug)==FALSE) ) 			      {				 usuario.table[num_jug].x=xx;				 usuario.table[num_jug].y=yy;          /* restauro pos */				 barquitos[subarco-1]++; /* update cantidad de tama;os de barcos */				 break;			      }			    else if( haybarco(usuario.table[num_jug].x+1,usuario.table[num_jug].y,num_jug) == TRUE ) 			      {				 subarco++;				 barcos++;				 usuario.table[num_jug].x++;			      }          			    else if( haybarco(usuario.table[num_jug].x,usuario.table[num_jug].y+1,num_jug) == TRUE ) 			      {				 usuario.table[num_jug].y++;				 barcos++;				 subarco++;			      }			    if( subarco > 4) 			      {				 return FALSE;			      }			 } /* for(;;) */		    } /* if(haybarco(x,y-1)==FALSE) */	       } /* if(haybarco(x,y)==TRUE) */	     if(nextbarco(num_jug)==FALSE) 	       {		  if( (barquitos[3]==1) && (barquitos[2]==2) && (barquitos[1]==3) && (barquitos[0]==4) ) 		    {		       return TRUE;         /* tabla bien puesta */		    }		  else 		    {		       return FALSE;		    }	       } /* if nextbarco()==FALSE) */	  } /* else */     } /* for(;;) */} /* void algoritomo() *//*************************************************************************** *            FUNCIONES RELACIONADAS CON LAS TABLAS y WPRINTD ***************************************************************************/void wprintd(WINDOW *win, char *fmt,...) {   va_list ap;   va_start(ap,fmt);   if(usuario.debug==TRUE)       {	vwprintw(win,fmt,ap);	wrefresh(win);     }   va_end(ap);}/* write to  board */int wtable( int jug,struct protocolo *proto ) {   int i,x,y;   x=0;y=0;   for(i=0;i<100;i++)      {	usuario.table[jug].p[x][y]=proto->bnpmsg[i];	x++;	if(x>=10) 	  {	     x=0;	     y++;	  }     }   return( algoritmo(jug));}/* read from board */void rtable( char outbuf[],int jug,char sup) {   int i,x,y;   x=0;y=0;   for(i=0;i<100;i++)      {	if(sup==BNSUP)	  outbuf[i]=usuario.table[jug].p[x][y];	else 	  {	     if(usuario.table[jug].p[x][y]==1)	       outbuf[i]=0;	     else	       outbuf[i]=usuario.table[jug].p[x][y];	  }	x++;	if(x>=10) 	  {	     x=0;	     y++;	  }     }}/* clean board */void ctable( int jug) {   int i,x,y;   x=0;y=0;   for(i=0;i<100;i++)      {	usuario.table[jug].p[x][y]=0;	x++;	if(x>=10) 	  {	     x=0;	     y++;	  }     }}/* tablero de un muerto */void mtable( int jug ) {   int i,x,y;   x=0;y=0;   for(i=0;i<100;i++)      {	if(usuario.table[jug].p[x][y]==NOBARCO)	  usuario.table[jug].p[x][y]=AGUA;	x++;	if(x>=10) 	  {	     x=0;	     y++;	  }     }}/***************************************************************************** *                EL BARCO ESTA HUNDIDO ? y todo tipo de funciones *****************************************************************************/int quebarco( int i,int x, int y) {   if( (x < 0) || ( x > 9 ) || (y < 0) || (y >9 ) )     return 0;   return( usuario.table[i].p[x][y]);}/* 1 funciones recursiva para chequear si esta hundido */void goudlr( int i,int x,int y,int xx,int yy) {   if (quebarco(i,x,y)==2)     goudlr(i,x+xx,y+yy,xx,yy);   else if(quebarco(i,x,y)==1)     temp+=1;}/* 1 funcion recursiva para pintar al barco hundido */void pgoudlr( int i,int x,int y,int xx,int yy) {   if(quebarco(i,x,y)==2) {      usuario.table[i].p[x][y]=HUNDIDO;         /* 3 means hundido (sunk) */      tempbuf[0]=(char)x;      tempbuf[1]=(char)y;      tempbuf[2]=HUNDIDO;                       /* hundido */      bnwrite(usuario.nro_fd[i],tempbuf,BNHIT,0,0,i+1);      pgoudlr(i,x+xx,y+yy,xx,yy);   }}/* i assume that quebarco(i,x,y)==2 o 1 */int eshundido(int i,int x,int y) {   int xx,yy;                           /* direccion a buscar */   if(quebarco(i,x,y) <= 0)             /* IDIOTA, COMO VA A SER HUNDIDO */     return FALSE;   if(quebarco(i,x,y)==3)               /* estaba hundido de antes idiota */     return TRUE;   usuario.table[i].p[x][y]=2;            /* tocado por ahora*/   temp=0;   xx=-1;yy=0;goudlr(i,x,y,xx,yy);   xx=0;yy=-1;goudlr(i,x,y,xx,yy);   xx=1;yy=0;goudlr(i,x,y,xx,yy);   xx=0;yy=1;goudlr(i,x,y,xx,yy);      if(temp==0)      {	xx=-1;yy=0;pgoudlr(i,x,y,xx,yy);	xx=0;yy=-1;pgoudlr(i,x,y-1,xx,yy);	xx=1;yy=0;pgoudlr(i,x+1,y,xx,yy);	xx=0;yy=1;pgoudlr(i,x,y+1,xx,yy);	usuario.hits[i]++;	if(usuario.hits[i]==10)  	  {	     bnwrite(usuario.nro_fd[i],tempbuf,BNLOS,0,0,i+1);	     usuario.nro_tot[i]=PERDIO; /* nuevo en 0.48 */	     /*	 usuario.hits[i]=0; */ /* comentado en la 0.48 */	     /*	 usuario.names[i][0]=0; */	     /*	 ctable(i);*/	     mtable(i); 	     sprintf(tempbuf,"Player %i is dead.",i+1); /* new on v0.32 */	     broadcast(tempbuf,BNEXT,1,i,i+1,1,0);      /* informs that i is dead */	     wprintd(windows[i],"\nPlayer was killed");	     wprintd(windows[i],"\n- - - - -");	     /* 	      * no hace falte volver a poner el nombre 	      */	     /* wprintd(titles[i],"\nPlayer %i, name:'%s'",i+1,usuario.names[i]); */	  }	return TRUE;     }   return FALSE;}/*****************************************************************************  *                           funciones CONTROL DE CHILD Y JUEGO ***************************************************************************//*  * Funcion bnexit() introducida en v0.50 * ya que no voy a repetir el codigo * Porque se puede salir de dos manera */void bnexit( int num_jug, int modo_quit ){   char outbuf[MSGMAXLEN];   int i;      /*     * Si el tipo que abandona es el que tiene el turno tiene     * que pasar al siguiente    */   if(usuario.nro_tot[num_jug]==4)     {         	for(i=num_jug;i<MAXPLAYER;i++)	  { 	     if(usuario.nro_tot[i]==3)	       break;	  }	if(i==MAXPLAYER) 	  { 	     for(i=0;i<MAXPLAYER;i++) 	       {		  if(usuario.nro_tot[i]==3)		    break;	       }	  }	if(i!=MAXPLAYER)	  {       	     usuario.nro_tot[i]=4;                     	     bnwrite(usuario.nro_fd[i],outbuf,BNTRN,0,0,i+1);	     wprintd(windows[i],"\nIt is my turn");	     sleep(1);                              	  }     }   usuario.nro_tot[num_jug]=0;   usuario.hits[num_jug]=0;   ctable(num_jug);     usuario.nro_fd[num_jug]=0;   usuario.names[num_jug][0]=0;   if(modo_quit==0)     {	sprintf(outbuf,"Player %i quits the game.",num_jug+1);	wprintd(windows[num_jug],"\nQuitting the game...");     }   else if(modo_quit==1)     {	sprintf(outbuf,"Player %i aborts the game.",num_jug+1);	wprintd(windows[num_jug],"\nAborting the game...");     }      broadcast(outbuf,BNEXT,3,num_jug,num_jug+1,0,0);   wprintd(windows[num_jug],"\n- - - - -");

⌨️ 快捷键说明

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