Beispiel #1
0
static mrb_value mrb_rand(mrb_state* mrb, mrb_value self)
{
  int i;
  mrb_value max;
  mrb_value seed;

  max = get_opt(mrb);
  if (mrb_nil_p(self)) {
    seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY));
    i = NEXT_SEED(seed);
    mrb_gv_set(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY), mrb_fixnum_value(i));
  } else {
    seed = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, INSTANCE_RAND_SEED_KEY));
    i = NEXT_SEED(seed);
    mrb_iv_set(mrb, self, mrb_intern_lit(mrb, INSTANCE_RAND_SEED_KEY), mrb_fixnum_value(i));
  }
  if (mrb_nil_p(max) || mrb_fixnum(max) == 0) {
    return mrb_float_value(mrb, NEXT_RAND(i) / 32767.0);
  }
  return mrb_float_value(mrb, NEXT_RAND(i) % mrb_fixnum(max));
}
Beispiel #2
0
//*****************************************************************************
//
// Scroll the tunnel image one column to the left and add a new column of
// tunnel on the right side of the display.
//
//*****************************************************************************
static void
UpdateBackground(unsigned long ulGap)
{
    unsigned long ulCount, ulIdx;

    //
    // Loop through the array of mines.
    //
    for(ulIdx = 0; ulIdx < 5; ulIdx++)
    {
        //
        // Skip this mine if it is disabled.
        //
        if((g_pcMines[ulIdx][0] == (char)-1) &&
           (g_pcMines[ulIdx][1] == (char)-1) &&
           (g_pcMines[ulIdx][2] == (char)-1))
        {
            continue;
        }

        //
        // Stop searching if this mine is near or on the right side of the
        // display.
        //
        if(g_pcMines[ulIdx][1] > 91)
        {
            break;
        }
    }

    //
    // Get a random number based on the collected entropy.
    //
    ulCount = RandomNumber();

    //
    // If the top part of the tunnel is not at the top of the display, then
    // move it up 18.75% of the time.
    //
    if((ulCount < 0x30000000) && (g_pucOffset[0] != 0))
    {
        g_pucOffset[0]--;
    }

    //
    // If the top part of the tunnel is not too close to the bottom part of the
    // tunnel, and there is no mine on the right side of the display or the top
    // part of the tunnel is far enough away from the mine, then move it down
    // 18.75% of the time.
    //
    if((ulCount > 0xd0000000) && ((g_pucOffset[0] + ulGap) < g_pucOffset[1]) &&
       ((ulIdx == 5) || ((g_pcMines[ulIdx][2] - g_pucOffset[0]) > 1)))
    {
        g_pucOffset[0]++;
    }

    //
    // Get a new pseudo random number based on the original random number (no
    // new entropy will have been collected, so it will return the exact same
    // random number, which isn't so random).
    //
    ulCount = NEXT_RAND(ulCount);

    //
    // If the bottom part of the tunnel is not too close to the top part of the
    // tunnel, and there is no mine on the right side of the display or the
    // bottom part of the tunnel is far enough away from the mine, then move it
    // up 18.75% of the time.
    //
    if((ulCount < 0x30000000) && ((g_pucOffset[1] - ulGap) > g_pucOffset[0]) &&
       ((ulIdx == 5) || ((g_pucOffset[1] - g_pcMines[ulIdx][2]) > 5)))
    {
        g_pucOffset[1]--;
    }

    //
    // If the bottom part of the tunnel is not at the bottom of the display,
    // then move it down 18.75% of the time.
    //
    if((ulCount > 0xd0000000) && (g_pucOffset[1] != 16))
    {
        g_pucOffset[1]++;
    }

    //
    // Move the background image one column to the left.
    //
    for(ulCount = 0; ulCount < 192; ulCount++)
    {
        g_pucBackground[ulCount] = g_pucBackground[ulCount + 1];
    }

    //
    // Generate a new column on the right side of the background image.
    //
    g_pucBackground[95] = 0xff >> (8 - g_pucOffset[0]);
    g_pucBackground[191] = 0xff << (g_pucOffset[1] - 8);

    //
    // Copy the background image to the local frame buffer.
    //
    for(ulCount = 0; ulCount < 192; ulCount += 4)
    {
        *(unsigned long *)(g_pucFrame + ulCount) =
            *(unsigned long *)(g_pucBackground + ulCount);
    }
}