Esempio n. 1
0
image_contents_t *diskcontents_block_read(vdrive_t *vdrive)
{
    image_contents_t *contents;
    BYTE buffer[256];
    int retval;
    image_contents_file_list_t *lp;

    machine_drive_flush();

    if (vdrive == NULL)
        return NULL;

    retval = vdrive_bam_read_bam(vdrive);

    if (retval < 0) {
        vdrive_internal_close_disk_image(vdrive);
        return NULL;
    }

    contents = image_contents_new();

    memcpy(contents->name, vdrive->bam + vdrive->bam_name,
           IMAGE_CONTENTS_NAME_LEN);
    contents->name[IMAGE_CONTENTS_NAME_LEN] = 0;

    memcpy(contents->id, vdrive->bam + vdrive->bam_id, IMAGE_CONTENTS_ID_LEN);
    contents->id[IMAGE_CONTENTS_ID_LEN] = 0;

    contents->blocks_free = (int)vdrive_bam_free_block_count(vdrive);

    vdrive->Curr_track = vdrive->Dir_Track;
    vdrive->Curr_sector = vdrive->Dir_Sector;

    lp = NULL;
    contents->file_list = NULL;

    circular_check_init();

    while (1) {
        BYTE *p;
        int j;

        retval = vdrive_read_sector(vdrive, buffer,
                                        vdrive->Curr_track,
                                        vdrive->Curr_sector);

        if (retval != 0
            || circular_check(vdrive->Curr_track, vdrive->Curr_sector)) {
            /*image_contents_destroy(contents);*/
            vdrive_internal_close_disk_image(vdrive);
            circular_check_free();
            return contents/*NULL*/;
        }

        for (p = buffer, j = 0; j < 8; j++, p += 32)
            if (p[SLOT_TYPE_OFFSET] != 0) {
                image_contents_file_list_t *new_list;
                int i;

                new_list = lib_malloc(sizeof(image_contents_file_list_t));
                new_list->size = ((int)p[SLOT_NR_BLOCKS]
                                  + ((int)p[SLOT_NR_BLOCKS + 1] << 8));

                for (i = 0; i < IMAGE_CONTENTS_FILE_NAME_LEN; i++)
                        new_list->name[i] = p[SLOT_NAME_OFFSET + i];

                new_list->name[IMAGE_CONTENTS_FILE_NAME_LEN] = 0;

                new_list->name[i] = 0;

                sprintf((char *)new_list->type, "%c%s%c",
                        (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_CLOSED ? ' ' : '*'),
                        cbmdos_filetype_get(p[SLOT_TYPE_OFFSET] & 0x07),
                        (p[SLOT_TYPE_OFFSET] & CBMDOS_FT_LOCKED ? '<' : ' '));

                new_list->next = NULL;

                if (lp == NULL) {
                    new_list->prev = NULL;
                    contents->file_list = new_list;
                    lp = contents->file_list;
                } else {
                    new_list->prev = lp;
                    lp->next = new_list;
                    lp = new_list;
                }
            }

        if (buffer[0] == 0)
            break;

        vdrive->Curr_track = (int)buffer[0];
        vdrive->Curr_sector = (int)buffer[1];
    }

    vdrive_internal_close_disk_image(vdrive);
    circular_check_free();
    return contents;
}
Esempio n. 2
0
File: mlr.c Progetto: ddugovic/nngs
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);
}