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)); }
//***************************************************************************** // // 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); } }