001 package com.croftsoft.core.math; 002 003 import java.util.Random; 004 005 /********************************************************************* 006 * Random number generation methods. 007 * 008 * @version 009 * 2003-04-21 010 * @since 011 * 1999-01-31 012 * @author 013 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 014 *********************************************************************/ 015 016 public class RandomLib 017 ////////////////////////////////////////////////////////////////////// 018 ////////////////////////////////////////////////////////////////////// 019 { 020 021 /** Seeded off of the current time. */ 022 private static Random random = new Random ( ); 023 024 ////////////////////////////////////////////////////////////////////// 025 ////////////////////////////////////////////////////////////////////// 026 027 /********************************************************************* 028 * Test method; prints roll(arg0, arg1, arg2). 029 *********************************************************************/ 030 public static void main ( String [ ] args ) 031 ////////////////////////////////////////////////////////////////////// 032 { 033 long multiplier = Long.parseLong ( args [ 0 ] ); 034 035 long base = Long.parseLong ( args [ 1 ] ); 036 037 long offset = Long.parseLong ( args [ 2 ] ); 038 039 System.out.println ( roll ( multiplier, base, offset ) ); 040 } 041 042 /********************************************************************* 043 * Returns a long between 0 (inclusive) and n (exclusive). 044 * 045 * @throws IllegalArgumentException 046 * 047 * If n is negative. 048 *********************************************************************/ 049 public static long nextLong ( long n ) 050 ////////////////////////////////////////////////////////////////////// 051 { 052 if ( n < 0 ) 053 { 054 throw new IllegalArgumentException ( "negative n: " + n ); 055 } 056 057 // Suppose n = 9. 058 // Numbers to be generated are 0 to 8 inclusive. 059 // Suppose Long.MAX_VALUE is 22. 060 // Factor is then 22/9 = 2. 061 // Max is then 2*9 = 18. 062 // Rolling will generate numbers between 0 and 17. 063 // Returned values will be between 0 and 8 inclusive. 064 065 long factor = Long.MAX_VALUE / n; 066 067 long max = factor * n; 068 069 long roll = -1; 070 071 while ( ( roll < 0 ) 072 || ( roll >= max ) ) 073 { 074 roll = random.nextLong ( ); 075 } 076 077 return roll % n; 078 } 079 080 /********************************************************************* 081 * Rolls an n-sided die a specified number of times and adds an offset. 082 * For example, to roll a 6-sided die 3 times and add 4 (3d6+4), 083 * the multiplier would be 3, the base 6, and the offset 4. 084 * 085 * @param multiplier 086 * The number of times to roll the die. Must be non-negative. 087 * @param base 088 * The number of sides on the die, e.g., six. 089 * @param offset 090 * A final adjustment to add to the sum after all rolls have been 091 * made. 092 * @return 093 * Returns the sum of the rolls plus the offset. 094 * The overflow condition is not handled. 095 *********************************************************************/ 096 public static long roll ( 097 long multiplier, 098 long base, 099 long offset ) 100 ////////////////////////////////////////////////////////////////////// 101 { 102 if ( multiplier < 0 ) 103 { 104 throw new IllegalArgumentException ( 105 "negative multiplier: " + multiplier ); 106 } 107 108 long sum = 0; 109 110 for ( long i = 0; i < multiplier; i++ ) 111 { 112 sum += nextLong ( base ) + 1; 113 } 114 115 return sum + offset; 116 } 117 118 /********************************************************************* 119 * Returns a double uniformly distributed between min (inclusive) and 120 * max (exclusive). 121 *********************************************************************/ 122 public static double uniform ( double min, double max ) 123 ////////////////////////////////////////////////////////////////////// 124 { 125 return min + ( max - min ) * random.nextDouble ( ); 126 } 127 128 ////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////// 130 }