Пример #1
0
int main () {                    // ***** main *****
  char *pj, *pq, *pr;            // buffer pointers: inp,out,/out
  char *jjj = malloc(JBFSIZE);   // allocate input line buffer
  char *qqq = malloc(QBFSIZE);   // output buffer (dyn. size)
  char *pqstop = qqq+QBFSIZE;    // end-of-buffer pointer
  char xtab[256] = VALL;         // char conversion table

  if (!jjj || !qqq)
    return errex("Buffer allocation", !jjj + !qqq);
  pj = fgets(jjj,JBFSIZE,stdin);         // fetch 1st line
  if (!pj)
    return errex("No input data",0);
  if (*jjj != '>')
    return errex("1st char not '>'", 0);

  while (pj) {                           // MAIN LOOP: process data
    fputs(jjj, stdout);                  // output ID line

    for (pq=qqq+1, pr=pqstop; ; pq++) {  // LOOP: fill output buffer
      pj = fgets(jjj, JBFSIZE, stdin);   // get line from stdin
      if (!pj || (*jjj=='>'))  break;    // EOF or new ID line
      if (pr <= (pq+61)) {               // need to resize buffer
        char *newstop = pqstop + 12777888;
        char *newptr  = realloc(qqq, newstop-qqq);
        if (!newptr)
          return errex("Out of memory", 0);
        if (newptr != qqq) {             // new base: adj. pointers
          size_t x = newptr-qqq;         // offset for pointer update
          pq+=x;  pr+=x;  qqq+=x;
          newstop+=x;  pqstop+=x;
        }
        pr = __builtin_memmove(newstop-(pqstop-pr), pr, pqstop-pr);
        pqstop = newstop;                // buffer resize complete
      }
      while (*pj) {                      // LOOP: conv. & revert line
        char c = xtab[(unsigned char)(*pj++)];
        if (c)                           // conversion valid
          *(--pr) = c;
      }
    }

    for (pq = qqq; pr<pqstop; ) {        // LOOP: format output
      size_t x = (pqstop-pr)<60 ? pqstop-pr : 60;
      __builtin_memmove(pq,pr,x);        // move line to free space
      pr+=x;  pq+=x;  *(pq++) = 0xA;     // adjust pointers, add LF
    }
    fwrite(qqq, 1, pq-qqq, stdout);      // output converted data
  }
  return 0;
}
Пример #2
0
static char *bx2a(boolx bxval)
{
	switch (bxval) {
	case TRUE:
		return "T\n";
	case FALSE:
		return "F\n";
	case UN_KNOWN:
		return "U\n";
	default:
		errex(SWERR, "file.c: bx2a");
	}			/* end switch */
	/* NOTREACHED */
}				/* bx2a */
Пример #3
0
void
mlrate(double mean, FILE *fdiag)
{
  double maxchange;		/* The max change of one turn. */
  size_t pcount, gcount, rcount; /* Player, game, and removed counters. */
  size_t wcount, lcount;	/* Win/loss counters. */
  double wsum, lsum;		/* Weighted sums. */
  size_t globturns = 0;		/* Counts the turns of the outer loop. */
  size_t hcount[10];		/* Handicap game counters. */
  player_t p;			/* A player. */
  piter_t piter;		/* An iterator over players. */
  char *pflags;

  assert(0.0 < mean && mean < RANK_MAXIMUM);

  pflags = (char *)malloc(player_count());
  if (pflags == NULL)
    errex("malloc(%lu) failed", player_count());
  memset(pflags, 0, player_count());

  /* Assign a start rating for every player. */
  player_start(&piter);
  while ((p = player_next(&piter)) != NO_PLAYER)
    if (!player_get_rated(p) && !player_get_ignore(p))
    {
      player_set_rank(p, mean);
      player_set_rated(p, 1);
    }

  /* Remove players with no wins or no losses against other rated 
  ** players; then again and again, until no more can be removed.
  ** While we're at it, count some statistics as well.
  */
  do {
    pcount = gcount = rcount = 0;
    hcount[0] = hcount[1] = hcount[2] = hcount[3] = hcount[4] =
      hcount[5] = hcount[6] = hcount[7] = hcount[8] = hcount[9] = 0;
    player_start(&piter);
    while ((p = player_next(&piter)) != NO_PLAYER)
      if (player_get_rated(p) && !player_get_ignore(p))
      {
	game_t g;
	giter_t giter;
	unsigned oppcount = 0;

	wcount = lcount = 0;
	wsum = lsum = 0.0;

	player_games_start(p, &giter);
	while ((g = player_games_next(&giter)) != NO_GAME)
	  if (game_weight(g) > 0.0)
	  {
	    double a = game_advantage(g);

	    if (a >= 10.0)
	      hcount[0] += 1;
	    else if (a >= 1.0)
	      hcount[(unsigned)floor(a)] += 1;
	    if (p == game_winner(g) && player_get_rated(game_loser(g)))
	    {
	      wcount += 1;
	      wsum += game_weight(g);
	      if (!pflags[game_loser(g)])
	      {
		pflags[game_loser(g)] = 1;
		oppcount += 1;
	      }
	    }
	    else if (p == game_loser(g) && player_get_rated(game_winner(g)))
	    {
	      lcount += 1;
	      lsum += game_weight(g);
	      if (!pflags[game_winner(g)])
	      {
		pflags[game_winner(g)] = 1;
		oppcount += 1;
	      }
	    }
	    else
	      game_set_weight(g, 0.0);
	  }
	  else
	    game_set_weight(g, 0.0);

	if (wsum < 0.25 || lsum < 0.25 || oppcount < 3)
	{
	  player_set_rated(p, 0);
	  rcount += 1;
	}
	else
	{
	  pcount += 1;
	  gcount += wcount + lcount;
	}
	player_set_ratedgames(p, wcount, lcount);
	player_set_wratedgames(p, wsum, lsum);

	/* Clear flags. */
	player_games_start(p, &giter);
	while ((g = player_games_next(&giter)) != NO_GAME)
	  pflags[game_loser(g)] = pflags[game_winner(g)] = 0;
      }
  } while (rcount > 0);

  player_gc_games();

  if (fdiag)
  {
    int i;

    fprintf(fdiag, "\nRemaining:\n%6lu players\n%6lu games\n\n",
	    (unsigned long)pcount, (unsigned long)gcount/2);
    for (i = 1 ; i <= 9 ; i++)
      fprintf(fdiag, "Advantage   %2d: %5lu games\n",
	      i, (unsigned long)hcount[i]);
    fprintf(fdiag,   "Advantage >=10: %5lu games\n\n",
	    (unsigned long)hcount[0]);
  }
  if (pcount == 0 || gcount == 0)
    errex("No player or no games");

  /*
  ** The outer loop.
  */
  do {	/* while (maxchange > CHANGE_LIMIT && globturns < GLOBAL_TURNS_MAX); */

    int maxp = 0;
    pcount = 0;
    maxchange = 0.0;
    globturns += 1;

    /*
    **  Loop over all players.
    */
    player_start(&piter);
    while ((p = player_next(&piter)) != NO_PLAYER)
    {
      /*
      **  We use bisection to find the root of the derivative (the maximum).
      */
      irank_t r, oldrank;
      irank_t ileft = RANK_MINIMUM, iright = RANK_MAXIMUM;

      if (!player_get_rated(p) || player_get_ignore(p))
	continue;

      /*
      ** Inner (bisection) loop.
      */
      pcount += 1;
      r = oldrank = player_get_rank(p);
      do {			/*  while (iright - ileft > CLOSE_ENOUGH); */
	game_t g;
	double sum = 0.0;
	giter_t giter;

	player_games_start(p, &giter);
	while ((g = player_games_next(&giter)) != NO_GAME)
	{
	  player_t opp;
	  double diff;

	  if (p == game_winner(g))
	  {
	    opp = game_loser(g);

	    if (player_get_rated(opp))
	    {
	      diff = RANK_DIFF(r, player_get_rank(opp))
		+ game_advantage(g);
	      sum += dP(diff, 1) * game_weight(g);
	    }
	  }
	  else
	  {
	    opp = game_winner(g);

	    if (player_get_rated(opp))
	    {
	      diff = RANK_DIFF(r, player_get_rank(opp))
		- game_advantage(g);
	      sum += dP(diff, 0) * game_weight(g);
	    }
	  }
	}

	if (sum > 0.0)
	  iright = r;		/* Root's somewhere to the left. */
	else
	  ileft = r;		/* Root's somewhere to the right. */
	r = (iright + ileft)/2;

      } while (iright - ileft > CLOSE_ENOUGH);

      if (r > oldrank)
      {
	if (r - oldrank > maxchange)
	{
	  maxchange = r - oldrank;
	  maxp = p;
	}
      }
      else
      {
	if (oldrank - r > maxchange)
	{
	  maxchange = oldrank - r;
	  maxp = p;
	}
      }
      player_set_rank(p, r);

    }	/* while ((p = player_next())) */

#ifdef MAXP
    fprintf(stderr, "\n--- Maxp: %s rank=%g ww=%g wl=%g w=%u l=%u rg=%u\n",
	    player_get_name(maxp),
	    player_get_rank(maxp),
	    player_get_wwins(maxp),
	    player_get_wlosses(maxp),
	    player_get_wins(maxp),
	    player_get_losses(maxp),
	    player_get_ratedgames(maxp));
#endif

    if (globturns > 100)
      circular_check(maxp);

    if (fdiag)
    {
      fprintf(fdiag, " %3lu: %6.3f", (unsigned long)globturns, maxchange);
      if (globturns % 5)
	fflush(fdiag);
      else
	fputc('\n', fdiag);
    }

  } while (maxchange > CHANGE_LIMIT && globturns < GLOBAL_TURNS_MAX);

  if (fdiag)
  {
    if (globturns % 5)
      fputc('\n', fdiag);
    fputc('\n', fdiag);
  }
  if (globturns == GLOBAL_TURNS_MAX)
    errex("Aborted after maximum %u turns\n", GLOBAL_TURNS_MAX);

  if (pflags != NULL)
    free(pflags);
}