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

📄 scoring.c

📁 支持网络和单机的麻将游戏
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: /home/jcb/newmj/RCS/scoring.c,v 11.8 2003/04/13 18:49:51 jcb Rel $ * scoring.c  * This file contains the routines to handle the scoring * of hands. *//****************** 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/scoring.c,v 11.8 2003/04/13 18:49:51 jcb Rel $";#include "tiles.h"#include "player.h"#include "controller.h"#include "scoring.h"#include "sysdep.h"int no_special_scores = 0; /* disable scoring of flowers and seasons *//* score_of_tileset: takes a TileSetP, and returns a score. *   It needs to know the wind of this player, and the prevailing wind.   It puts the left text, score and right text in the following ptrs; they   are valid until the next call */static char *tsltext,*tsrtext; static int tsscore;static int score_of_tileset(Game *g, TileSetP tp, TileWind own, TileWind prevailing) {  static char buf[100];  static char tmp[50] ;  int n,d;  buf[0] = 0;  tmp[0] = 0;  if ( tp->type == Empty ) {    /* I don't think this should happen */    warn("score_of_tileset: called on Empty tileset");    tsltext = NULL; tsrtext = NULL;    return 0;  }  d = is_major(tp->tile) ? 2 : 1;  n = 0;  switch ( tp->type ) {  case Chow:  case ClosedChow:    n = 0; break;  case Pung:    n = 2*d;    strcat(tmp,"open pung of ");    strcat(tmp, (d==2) ? "majors" : "minors");    break;  case ClosedPung:    n = 4*d;    strcat(tmp,"closed pung of ");    strcat(tmp, (d==2) ? "majors" : "minors");    break;  case Kong:    n = 8*d;    /* if we are using Millington's kong rules, we should distinguish       claimed and annexed kongs here */    if ( game_get_option_value(g,GOKongHas3Types,NULL) ) {      if ( tp->annexed )	strcat(tmp,"annexed kong of ");      else	strcat(tmp,"claimed kong of ");    } else {      strcat(tmp,"open kong of ");    }    strcat(tmp, (d==2) ? "majors" : "minors");    break;  case ClosedKong:    n = 16*d;    strcat(tmp,"closed kong of ");    strcat(tmp, (d==2) ? "majors" : "minors");    break;  case Pair:  case ClosedPair:    n = 0;    if ( is_dragon(tp->tile) ) {      n = 2;      strcat(tmp,"pair of dragons");    } else if ( is_wind(tp->tile)		&& (TileWind)value_of(tp->tile) == own ) {      if ( own == prevailing ) {	n = 4;	strcat(tmp,"pair of own and prevailing wind");      } else {	n = 2;	strcat(tmp,"pair of own wind");      }    } else if ( is_wind(tp->tile)		&& (TileWind)value_of(tp->tile) == prevailing ) {      n = 2;      strcat(tmp,"pair of prevailing wind");    }    break;  case Empty: break; /* to suppress warning */  }  tsltext = tileset_string(tp);  tsscore = n;  tsrtext = tmp;  return n;}/* score_of_hand: score the given seat in the given game.   In addition, set the danger flags to indicate if the player   achieved any of the dangerous hands. */Score score_of_hand(Game *g, seats s) {  Score tot;  /* there are three buffers in which scoring info is built up:     a points buffer, a doubles buffer, and a limit buffer */  static char buf[2048], dblsbuf[1024], limsbuf[1024];  char tbuf[100];  PlayerP p;  int limit, nolimit;  int winner;  int i,doubles,centilims;  MJSpecialHandFlags mjspecflags;  Tile eyestile; int claimedpair;  int numchows,numpairs,numpungs,numkongs,allclosed,noscore,allhonours,    allmajors,allterminals,dragonsets,windsets,dragonpairs,windpairs,    numclosedpks,allgreen,allbamboo,allcharacter,allcircle,    allbamboohonour,allcharacterhonour,allcirclehonour;    p = g->players[s];  assert(g->state == MahJonging);  limit = (int)game_get_option_value(g,GOScoreLimit,NULL);  nolimit = (int)game_get_option_value(g,GONoLimit,NULL);  mjspecflags = 0;  if ( game_get_option_value(g,GOSevenPairs,NULL) )    mjspecflags |= MJSevenPairs;  buf[0] = 0;  tot.explanation = buf;  tot.value = 0;  dblsbuf[0] = 0;  limsbuf[0] = 0;  doubles = 0;  centilims = 0;  /* This macro takes three args: text for left,     score, and text for right. It then looks at the score     and adds appropriate bits to the relevant buffers and     scoring info */#define doscore(ltext,score,rtext) \  { int pts, dbls, clims; \    pts = (score) % 10000; \    dbls = ((score) / 10000) % 100; \    clims = ((score) / 1000000); \    if ( (!clims || nolimit) && pts ) { \      tot.value += pts; sprintf(tbuf,"%-12s %2d (%s)\n",ltext,pts,rtext); \      strcat(buf,tbuf); \    } \    if ( (!clims || nolimit) && dbls ) { \      doubles += dbls; sprintf(tbuf,"%-12s  %1d dbl (%s)\n",ltext,dbls,rtext); \      strcat(dblsbuf,tbuf); \    } \    if ( clims && !(nolimit && (pts || dbls)) ) { \      if ( clims > centilims ) centilims = clims; \      if ( clims == 100 ) { \        sprintf(tbuf,"%-10s %4d (%s)\n","Limit Hand",limit,rtext); \      } else { \        sprintf(tbuf,"%4g Limit %4d (%s)\n",clims*1.0/100,clims*limit/100,rtext); \      } \      strcat(limsbuf,tbuf); \    } \  }  /* and a couple of defines for hard-coded scores */#define DBLS *10000#define LIMIT 100000000  /* variables for detecting special hands */  numchows = 0;  numkongs = 0;  numpairs = 0;  numpungs = 0;  allclosed = 1;  noscore = 1;  allterminals = 1;  allhonours = 1;  allmajors = 1;  windsets = 0;  dragonsets = 0;  windpairs = 0;  dragonpairs = 0;  allgreen = 1;  allbamboo = 1;  allcharacter = 1;  allcircle = 1;  allbamboohonour = 1;  allcharacterhonour = 1;  allcirclehonour = 1;  numclosedpks = 0; /* closed pungs/kongs */  eyestile = HiddenTile; claimedpair = 0;  /* Basic points */  winner = 0;  if ( s == g->player ) {    doscore("basic",(int)game_get_option_value(g,GOMahJongScore,NULL),	    "going Mah Jong");    winner = 1;  }  if ( winner ) {     presetdflags(p,s);    psetdflags(p,s,DangerEnd);  }  /* Now, get the points for the tilesets */  /* Also, stash information for doubles */  for ( i = 0; i < MAX_TILESETS; i++ ) {    TileSetP t = (TileSetP) &p->tilesets[i];    if ( t->type == Empty ) continue;    score_of_tileset(g,t,p->wind,g->round);    if ( tsscore ) {      noscore = 0;      doscore(tsltext,tsscore,tsrtext);    }        if ( t->type == Chow )      numchows++,allclosed=0,allterminals=allhonours=allmajors=0;    if ( t->type == ClosedChow )      numchows++,allterminals=allhonours=allmajors=0;    if ( t->type == Pung ) allclosed=0,numpungs++;    if ( t->type == ClosedPung ) numpungs++,numclosedpks++;    if ( t->type == Kong ) {      numkongs++ ;      /* in Millington's rules, a claimed kong counts as a closed	 kong for doubling purposes */      if ( game_get_option_value(g,GOKongHas3Types,NULL)	&& ! t->annexed ) {	numclosedpks++;      } else {	allclosed=0;      }    }    if ( t->type == ClosedKong ) numkongs++,numclosedpks++;    if ( t->type == Pair ) {      numpairs++;      allclosed=0;      claimedpair = 1 ;      eyestile = t->tile; /* this fails for seven pairs, but we don't care */    }    if ( t->type == ClosedPair ) {      numpairs++;      eyestile = t->tile; /* this fails for seven pairs, but we don't care */    }    if ( num_tiles_in_set(t) >= 3 ) {      dragonsets += is_dragon(t->tile);      windsets += is_wind(t->tile);    } else {      dragonpairs += is_dragon(t->tile);      windpairs += is_wind(t->tile);    }    switch ( suit_of(t->tile) ) {    case BambooSuit:      allcharacter = allcharacterhonour = 0;      allcircle = allcirclehonour = 0;      switch ( t->type ) {      case Chow:      case ClosedChow:	if ( !is_green(t->tile) 	  || !is_green(t->tile+1)	  || !is_green(t->tile+2) ) allgreen = 0;	break;      default:	if ( !is_green(t->tile) ) allgreen = 0;      }      break;    case CharacterSuit:      allbamboo = allbamboohonour = 0;      allcircle = allcirclehonour = 0;      allgreen = 0;      break;    case CircleSuit:      allbamboo = allbamboohonour = 0;      allcharacter = allcharacterhonour = 0;      allgreen = 0;      break;    case DragonSuit:      allbamboo = allcharacter = allcircle = 0;      if ( !is_green(t->tile) ) allgreen = 0;      break;    case WindSuit:      allbamboo = allcharacter = allcircle = 0;      allgreen = 0;      break;    default:      warn("Strange suit seen in hand");    }    if ( !is_honour(t->tile) ) allhonours = 0;    if ( !is_terminal(t->tile) ) allterminals = 0;    if ( !is_major(t->tile) ) allmajors = 0;  }  /* now go through the concealed tiles, in case we're playing some     weird game where losers are allowed to score for pure and concealed     hands. Seems a pity to duplicate all this code, but there we are */  /* There's another reason to go through the concealed tiles: the     existence of special hands, where the concealed tiles are     a declared set */  for ( i = 0; i < p->num_concealed; i++ ) {    Tile ti = p->concealed[i];    switch ( suit_of(ti) ) {    case BambooSuit:      allcharacter = allcharacterhonour = 0;      allcircle = allcirclehonour = 0;      if ( !is_green(ti) ) allgreen = 0;      break;    case CharacterSuit:      allbamboo = allbamboohonour = 0;      allcircle = allcirclehonour = 0;      allgreen = 0;      break;    case CircleSuit:      allbamboo = allbamboohonour = 0;      allcharacter = allcharacterhonour = 0;      allgreen = 0;      break;    case DragonSuit:      allbamboo = allcharacter = allcircle = 0;      if ( !is_green(ti) ) allgreen = 0;      break;    case WindSuit:      allbamboo = allcharacter = allcircle = 0;      allgreen = 0;      break;    default:      warn("Strange suit seen in hand");    }    if ( !is_honour(ti) ) allhonours = 0;    if ( !is_terminal(ti) ) allterminals = 0;    if ( !is_major(ti) ) allmajors = 0;  }  /* if we have seven pairs, give the base points */  if ( numpairs == 7 ) {    doscore("basic points",(int)game_get_option_value(g,GOSevenPairsVal,NULL),"seven pairs");    noscore = 0;  }  /* Now points for flowers and seasons (which don't count     to stop a noscore hand) */  if ( p->num_specials > 0 && ! no_special_scores ) {    char s[16];    sprintf(s,"%d special%s",p->num_specials,p->num_specials > 1 ? "s" : "");    doscore(s,4*p->num_specials,"flowers and seasons");  }  /* odds and sods */  if ( winner       && g->whence == FromWall ) {    doscore("extra",2,"winning from wall");  }  /* fishing the eyes: if we claimed a pair to go out, then     the tile had better match the discard.     Otherwise, the tiles of the (necessarily closed) pair     had better match the tile drawn from the wall.     We don't give this for seven pairs (or other multi pair hands).  */  if ( winner && eyestile == g->tile       && numpairs == 1       && ( claimedpair 	    || g->whence == FromWall || g->whence == FromLoose ) ) {    doscore("extra",is_major(eyestile) ? 4 : 2,"fishing the eyes");  }

⌨️ 快捷键说明

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