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

📄 client.c

📁 支持网络和单机的麻将游戏
💻 C
字号:
/* $Header: /home/jcb/newmj/RCS/client.c,v 11.3 2003/03/23 18:02:01 jcb Rel $ * client.c * Provides generic client support. It connects to the controller, * and maintains a game data structure in response to the Controller * messages. After updating the game structure, it (will) invokes a callback * installed by its user. *//****************** COPYRIGHT STATEMENT ********************** * This file is Copyright (c) 2000 by J. C. Bradfield.       * * Distribution and use is governed by the LICENCE file that * * accompanies this file.                                    * * The moral rights of the author are asserted.              * *                                                           * ***************** DISCLAIMER OF WARRANTY ******************** * This code is not warranted fit for any purpose. See the   * * LICENCE file for further information.                     * *                                                           * *************************************************************/static const char rcs_id[] = "$Header: /home/jcb/newmj/RCS/client.c,v 11.3 2003/03/23 18:02:01 jcb Rel $";#include "sysdep.h"#include <assert.h>#include "client.h"/* client_init: establish a connection to a controller */Game *client_init(char *address) {  int fd;  int i;  Game *g;  if ( strcmp("-",address) == 0 ) {    fd = STDOUT_FILENO;  } else {    fd = connect_to_host(address);    if ( fd == INVALID_SOCKET ) {      perror("client_init: connect_to_host failed");      return 0;    }  }  /* alloc the structures */  g = (Game *) malloc(sizeof(Game));  if ( g == NULL ) {    warn("Couldn't malloc game structure");    exit(1);  }  memset((void *)g,0,sizeof(Game));  for ( i=0 ; i < NUM_SEATS ; i++ ) {    if ( (g->players[i]	  = (PlayerP) malloc(sizeof(Player)))	 == NULL ) {      warn("couldn't malloc player structure");      exit(1);    }    memset((void *)g->players[i],0,sizeof(Player));  }    g->fd = fd;  g->cseqno = 0;  return g;}/* client_connect: take an id and a name, and send a connect message.   Return 1 on success, or 0 on failure. */int client_connect(Game *g, int id, char *name) {  PMsgConnectMsg cm;  cm.type = PMsgConnect;  cm.pvers = PROTOCOL_VERSION;  cm.last_id = id;  cm.name = name;  client_send_packet(g,(PMsgMsg *)&cm);  /* stash info in our own player record */  assert(g->players[0]);  initialize_player(g->players[0]);  set_player_id(g->players[0],id);  set_player_name(g->players[0],name);  return 1;}/* close connection and free storage */Game *client_close(Game *g) {  int i;  close_socket(g->fd);  for ( i = 0; i < NUM_SEATS; i++ ) {    set_player_name(g->players[i],NULL);    free((void *)(g->players[i]));  }  free(g);  g->fd = INVALID_SOCKET;  return NULL;}/* client_send_packet: send the given packet out on the game fd.   Return sequence number of packet. */int client_send_packet(Game *g, PMsgMsg *m) {  char *l;  if ( ! g ) {    warn("client_send_packet: null game");    return 0;  }  l = encode_pmsg(m);  if ( l == NULL ) {    /* this shouldn't happen */    warn("client_send_packet: protocol conversion failed");    return 0;  }  if ( put_line(g->fd,l) < 0 ) {    warn("client_send_packet: write failed");    /* maybe we should shutdown the descriptor here? */    return 0;  }  return ++g->cseqno;}/* see client.h for spec. */TileSet *client_find_sets(PlayerP p, Tile d, int mj, PlayerP *pcopies,			  MJSpecialHandFlags flags) {  static TileSet ts[14]; /* should be safe, but FIXME */  static Player copies[14];  TileSet *tsp = ts;  Tile t;  PlayerP cp = copies;  char seen[MaxTile]; /* to note tile denominations already done */  int j;  /* check the discard */  if ( d != HiddenTile ) {    /* Can we kong? */    if ( !mj && player_can_kong(p,d) ) {      tsp->type = Kong;      tsp->tile = d;      tsp++; cp++;    }    /* Can we pung it? */    copy_player(cp,p);    if ( player_pungs(cp,d) && (!mj || player_can_mah_jong(cp,HiddenTile,flags)) ) {      tsp->type = Pung;      tsp->tile = d;      tsp++; cp++;    }        /* Can we chow it? */    for ( j = Lower; j <= Upper; j++ ) {      copy_player(cp,p);      if ( player_chows(cp,d,j) && (!mj || player_can_mah_jong(cp,HiddenTile,flags))) {	tsp->type = Chow;	tsp->tile = make_tile(suit_of(d),value_of(d)-j);	tsp++; cp++;      }    }    /* Can we pair it? */    copy_player(cp,p);    if ( player_pairs(cp,d) && (!mj || player_can_mah_jong(cp,HiddenTile,flags)) ) {      tsp->type = Pair;      tsp->tile = d;      tsp++; cp++;    }  } else {    /* no discard. Look for closed sets */    /* Because we should return pungs, then chows, then pairs,       we have to go through the tiles three times, which is tedious. */    for (j=0; j < MaxTile; j++) seen[j] = 0;    for (j=0; j < p->num_concealed; j++) {      t = p->concealed[j];      if ( seen[t]++ ) continue; /* don't enter sets twice */      copy_player(cp,p);      if ( player_forms_closed_pung(cp,t) && (!mj || player_can_mah_jong(cp,HiddenTile,flags))) {	tsp->type = ClosedPung;	tsp->tile = t;	tsp++; cp++;      }    }        for (j=0; j < MaxTile; j++) seen[j] = 0;    for (j=0; j < p->num_concealed; j++) {      t = p->concealed[j];      if ( seen[t]++ ) continue; /* don't enter sets twice */      copy_player(cp,p);      if ( player_forms_closed_chow(cp,t,Lower) && (!mj || player_can_mah_jong(cp,HiddenTile,flags))) {	tsp->type = ClosedChow;	tsp->tile = t;	tsp++; cp++;      }    }        for (j=0; j < MaxTile; j++) seen[j] = 0;    for (j=0; j < p->num_concealed; j++) {      t = p->concealed[j];      if ( seen[t]++ ) continue; /* don't enter sets twice */      copy_player(cp,p);      if ( player_forms_closed_pair(cp,t) && (!mj || player_can_mah_jong(cp,HiddenTile,flags))) {	tsp->type = ClosedPair;	tsp->tile = t;	tsp++; cp++;      }    }  }  /* have we found anything? */  if ( tsp == ts ) return (TileSet *)0;    tsp->type = Empty;  if ( pcopies ) *pcopies = copies;  return ts;}

⌨️ 快捷键说明

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