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

📄 greedy.c

📁 支持网络和单机的麻将游戏
💻 C
📖 第 1 页 / 共 4 页
字号:
  }  return 1;}/* do something when it's our turn. */static void do_something(void) {  int i;  MJSpecialHandFlags mjspecflags;  mjspecflags = 0;  if ( game_get_option_value(the_game,GOSevenPairs,NULL) )    mjspecflags |= MJSevenPairs;  /* if the game is paused, and we haven't said we're ready, say so */  if ( the_game->paused ) {    if ( !the_game->ready[our_seat] ) {      PMsgReadyMsg pm;      pm.type = PMsgReady;      send_packet(&pm);    }    return;  }  /* if the game state is handcomplete, do nothing */  if ( the_game->state == HandComplete ) return;  /* If the game state is discarded, then it must mean this has     been called in response to a StartPlay message after resuming     an old hand. So actually we want to check the discard, unless     of course we are the discarder, or we have already claimed. */  if ( the_game->state == Discarded ) {    if ( the_game->player != our_seat	 && the_game->claims[our_seat] == UnknownClaim )      check_discard(our_player,&curstrat);    return;  }  /* If the game state is Dealing, then we should not do anything.   */  if ( the_game->state == Dealing ) return;  /* if we're called in declaring specials or discarding, but it's     not our turn, do nothing */  if ( (the_game->state == DeclaringSpecials	|| the_game->state == Discarding)       && the_game->player != our_seat ) return;  /* if we're waiting to draw another tile, do nothing */  if ( the_game->needs != FromNone ) return;  /* if we have a special, declare it. N.B. we'll     be called again as a result of this, so only look for first.  */  for ( i=0; i < our_player->num_concealed	  && ! is_special(our_player->concealed[i]) ; i++);  if ( i < our_player->num_concealed ) {    PMsgDeclareSpecialMsg m;    m.type = PMsgDeclareSpecial;    m.tile = our_player->concealed[i];    send_packet(&m);    return;  }  /* OK, no specials */  if ( the_game->state == DeclaringSpecials ) {    PMsgDeclareSpecialMsg m;    m.type = PMsgDeclareSpecial;    m.tile = HiddenTile;    send_packet(&m);    /* and at this point, we should decide our strategy */    maybe_switch_strategy(&curstrat);    return;  }  /* if the game is in the mahjonging state, and our hand is not declared,     then we should declare a set. */  if ( the_game->state == MahJonging ) {    TileSet *tsp;    PMsgUnion m;    if ( pflag(our_player,HandDeclared) ) return;    /* as courtesy, if we're not the winner, we shouldn't score until       the winner has */    if ( our_seat != the_game->player	 && ! pflag(the_game->players[the_game->player],HandDeclared) ) return;    /* get the list of possible decls */    tsp = client_find_sets(our_player,			   (the_game->player == our_seat			    && the_game->mjpending)			   ? the_game->tile : HiddenTile,			   the_game->player == our_seat,			   (PlayerP *)0,mjspecflags);    if ( !tsp && our_player->num_concealed > 0 ) {      m.type = PMsgShowTiles;      send_packet(&m);      return;    }    /* just do the first one */    switch ( tsp->type ) {    case Kong:      /* we can't declare a kong now, so declare the pung instead */    case Pung:      m.type = PMsgPung;      m.pung.discard = 0;      break;    case Chow:      m.type = PMsgChow;      m.chow.discard = 0;      m.chow.cpos = the_game->tile - tsp->tile;      break;    case Pair:      m.type = PMsgPair;      break;    case ClosedPung:      m.type = PMsgFormClosedPung;      m.formclosedpung.tile = tsp->tile;      break;    case ClosedChow:      m.type = PMsgFormClosedChow;      m.formclosedchow.tile = tsp->tile;      break;    case ClosedPair:      m.type = PMsgFormClosedPair;      m.formclosedpair.tile = tsp->tile;      break;    case Empty: /* can't happen, just to suppress warning */    case ClosedKong: /* ditto */      ;    }    send_packet(&m);    return;  }      /* if we can declare MahJong, do it */  if ( player_can_mah_jong(our_player,HiddenTile,mjspecflags) ) {    PMsgMahJongMsg m;    m.type = PMsgMahJong;    m.discard = 0;    send_packet(&m);    return;  } else if ( the_game->whence != FromDiscard ) {    /* check for concealed kongs and melded kongs. Just declare them. */    int i;    double val;    Player pc;    val = evalhand(our_player,&curstrat);    /* a side effect of the above call is that our concealed tiles        are sorted (in reverse order), so we can avoid duplicating effort */    for (i=0;i<our_player->num_concealed;i++) {      /* don't look at same tile twice */      if ( i && our_player->concealed[i] == our_player->concealed[i-1] ) continue;      if ( player_can_declare_closed_kong(our_player,our_player->concealed[i]) ) {	PMsgDeclareClosedKongMsg m;	copy_player(&pc,our_player);	player_declares_closed_kong(&pc,our_player->concealed[i]);	if ( evalhand(&pc,&curstrat) > val ) {	  m.type = PMsgDeclareClosedKong;	  m.tile = our_player->concealed[i];	  send_packet(&m);	  return;	}      }    }    /* Now check for pungs we can meld to */    for (i=0;i<MAX_TILESETS;i++) {      if ( our_player->tilesets[i].type == Pung	   && player_can_add_to_pung(our_player,our_player->tilesets[i].tile) ) {	PMsgAddToPungMsg m;	copy_player(&pc,our_player);	player_adds_to_pung(&pc,our_player->tilesets[i].tile);	if ( evalhand(&pc,&curstrat) > val ) {	  m.type = PMsgAddToPung;	  m.tile = our_player->tilesets[i].tile;	  send_packet(&m);	  return;	}      }    }  }  /* if we get here, we have to discard */  {    PMsgDiscardMsg m;    Tile t;        /* strategy switching only after drawing tile from wall */    if ( the_game->whence != FromDiscard || !strategy_chosen) {      maybe_switch_strategy(&curstrat);    }      t = decide_discard(our_player,NULL,&curstrat);    m.type = PMsgDiscard;    m.tile = t;    m.calling = 0; /* we don't bother looking for original call */    send_packet(&m);    return;  }}/* Check if we want the discard, and claim it.   Arg is strategy.   Also called to check whether a kong can be robbed */static void check_discard(PlayerP p, strategy *strat) {  PMsgUnion m;  double bestval,val;  int canmj;  char buf[100];  MJSpecialHandFlags mjspecflags;  mjspecflags = 0;  if ( game_get_option_value(the_game,GOSevenPairs,NULL) )    mjspecflags |= MJSevenPairs;  if ( the_game->state == Discarding        || the_game->state == DeclaringSpecials ) {    /* this means we're being called to check whether a kong       can be robbed. Since robbing a kong gets us an extra double,       this is probably always worth doing, unless we're trying for       some limit hand */    if ( player_can_mah_jong(p,the_game->tile,mjspecflags) ) {      m.type = PMsgMahJong;      m.mahjong.discard = the_game->serial;    } else {      m.type = PMsgNoClaim;      m.noclaim.discard = the_game->serial;    }    send_packet(&m);    return;  }  if ( debugeval ) {    player_print_tiles(buf,p,0);    printf("Hand: %s  ; discard %s\n",buf,tile_code(the_game->tile));  }  bestval = evalhand(p,strat);  if ( debugeval ) {    printf("Hand value before claim %.3f\n",bestval);  }  canmj = player_can_mah_jong(p,the_game->tile,mjspecflags);  m.type = PMsgNoClaim;  m.noclaim.discard = the_game->serial;  if ( player_can_kong(p,the_game->tile) ) {      Player pc;      copy_player(&pc,p);      player_kongs(&pc,the_game->tile);      val = evalhand(&pc,strat);      /* we won't discard a tile here */      if ( debugeval ) {	printf("Hand after kong  %.3f\n",val);      }      if ( val > bestval ) {	m.type = PMsgKong;	m.kong.discard = the_game->serial;	bestval = val;      }      else 	if ( debugeval ) {	  printf("Chose not to kong\n");	}  }   if ( player_can_pung(p,the_game->tile) ) {    Player pc;    copy_player(&pc,p);    player_pungs(&pc,the_game->tile);    decide_discard(&pc,&val,&curstrat);    if ( debugeval ) {      printf("Hand after pung  %.3f\n",val);    }    if ( val > bestval ) {      m.type = PMsgPung;      m.pung.discard = the_game->serial;      bestval = val;    }    else       if ( debugeval ) {	printf("Chose not to pung\n");      }    }  if ( (canmj || our_seat == (the_game->player+1)%NUM_SEATS)       && is_suit(the_game->tile) ) {    ChowPosition cpos = (unsigned) -1;    Player pc;    int chowposs = 0;    Tile t = the_game->tile;    copy_player(&pc,p);    if ( player_chows(&pc,t,Lower) ) {      decide_discard(&pc,&val,&curstrat);      if ( debugeval ) {	printf("Hand after lower chow: %.3f\n",val);      }      chowposs = 1;      if ( val > bestval ) {	bestval = val;	cpos = Lower;      }      copy_player(&pc,p);    }    if ( player_chows(&pc,t,Middle) ) {      decide_discard(&pc,&val,&curstrat);      if ( debugeval ) {	printf("Hand after middle chow: %.3f\n",val);      }      chowposs = 1;      if ( val > bestval ) {	bestval = val;	cpos = Middle;      }      copy_player(&pc,p);    }    if ( player_chows(&pc,t,Upper) ) {      chowposs = 1;      decide_discard(&pc,&val,&curstrat);      if ( debugeval ) {	printf("Hand after upper chow: %.3f\n",val);      }      if ( val > bestval ) {	bestval = val;	cpos = Upper;      }      copy_player(&pc,p);    }    if ( cpos != (unsigned)-1 ) {      m.type = PMsgChow;      m.chow.discard = the_game->serial;      m.chow.cpos = cpos;    }     else      if ( debugeval ) {	if ( chowposs ) fprintf(stdout,"chose not to chow\n");      }  }  /* mah jong */  if ( canmj ) {    m.type = PMsgMahJong;    m.mahjong.discard = the_game->serial;#if 1    /* if we're following a concealed strategy, and we still have       four chances (ex?cluding this one) of going out, then       don't claim */    /* instead of four chances, make it depend on number of tiles left */    /* test: if hidden >1, then never claim */    if ( (strat->hiddenness > 1.0) || (strat->hiddenness*chances_to_win(p) 	 * (the_game->wall.live_end-the_game->wall.live_used)	 / (the_game->wall.dead_end-the_game->wall.live_used) 	 >= 1.5) ) {      m.type = PMsgNoClaim;      m.noclaim.discard = the_game->serial;    }#endif    if ( m.type != PMsgNoClaim ) {      if ( debugeval && strat->hiddenness > 0.0 ) printf("claiming mahjong on hidden strategy\n");      m.type = PMsgMahJong;      m.mahjong.discard = the_game->serial;    } else {      if ( debugeval ) {	printf("CHOSE NOT TO MAHJONG\n");      }    }  }  if ( debugeval ) {    printf("Result: %s",encode_pmsg((PMsgMsg *)&m));  }  send_packet(&m);

⌨️ 快捷键说明

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