Java Dice Statistics
Code

import java.text.NumberFormat;
import java.lang.String;
/*
** All the number crunching is in this class.
** I/O, Events and formatting are in the other file.
** Implementation of the 3 loop method with protections
** to prevent unneeded rebuilding of the main array.
*/
public class DiceStuff
{
/*
** Maximum sizes of dice to prevent math overflow and limit memory use.
*/
static final int max_sides = 15 ;
static final int max_dice = 15 ;
static final int max_roll = max_sides * max_dice ;
/*
** The main array.
*/
static long wayray[][] = new long[max_dice + 1][max_roll + 1] ;
/*
** Flags to indicate how many sides the array is currently using...
** and the max number of dice the array is currently initialized to handle.
*/
static int way_ray_sides = 0 ;
static int way_ray_filled = 0 ;
/*
** Tis a shame to have a constructor with nothing to construct.
** A non-static variable just for the heck of it.
*/
int waste ;
/*
** In an object oriented language, you need an object to manipulate
** before one can call code to do anything. This is a "constructor"
** class which returns an instance of DiceStuff so that the DiceStuff
** public procedures can be accessed.
*/
public DiceStuff()
{
waste = 1 ;
}
/*
** Initializes the static array which holds all the numbers.
** Up to date using correct dice size and up to the requested
** number of dice.
*/
private void initwayray(int count_in, int sides_in)
{
/* How much of the matrix has to be rebuilt. */
int first_rebuild ;
int last_rebuild ;
/* Scratch variables used in the rebuilding. */
int build_this ;
int last_min ;
int last_max ;
int target_sum ;
int from_index ;
int to_index ;
long adding_this ;
if (way_ray_sides != sides_in)
{
/*
** Operator changed dice sizes.
** Nothing we have is any good.
** Start from the beginning.
*/
first_rebuild = 1 ;
last_rebuild = count_in ;
/*
** Save current state of the array for next time.
*/
way_ray_sides = sides_in ;
way_ray_filled = count_in ;
/*
** Assume 1 way to roll
** a zero on zero dice.
** Otherwise, table for 1 dice doesn't build right.
*/
wayray[0][0] = 1 ;
}
else if ( count_in > way_ray_filled)
{
/*
** Array partially built.
** Keep what is already built.
** Add on more dice.
*/
first_rebuild = way_ray_filled + 1 ;
last_rebuild = count_in ;
/*
** Remember what was built so we don't have to build it
** again next time.
*/
way_ray_filled = count_in ;
}
else
{
/*
** Same size dice.
** Same number or fewer dice.
** Table is already good enough.
** No need to rebuild.
*/
return ;
}
/*
** What columns have we got to build?
** Loop through each column.
*/
for (build_this = first_rebuild ; build_this <= last_rebuild ; build_this++)
{
/*
** Clear any old contents in the rebuilding row.
*/
for (to_index = 0 ; to_index < max_roll ; to_index++)
{
wayray[build_this][to_index] = 0 ;
}
/*
** What is the range of non-zero results in prior existing row?
** Each old content must be added into sides_in new entries
** in the row we are building.
*/
last_min = (build_this - 1) ;
last_max = (build_this - 1) * sides_in ;
/*
** Loop through the last row, adding contents into new row.
*/
for ( from_index = last_min ; from_index <= last_max ; from_index++ )
{
/*
** This number has to be added to a bunch of numbers in the
** new column.
*/
adding_this = wayray[build_this - 1][from_index] ;
/*
** Which new numbers must be added to?
** Let us set up the loop.
*/
for (to_index = from_index + 1 ; to_index <= from_index + sides_in ; to_index++)
{
wayray[build_this][to_index] += adding_this ;
}
}
}
}
/*
** Returns number of ways to hit target.
** Checks range.
** Makes sure way ray is up to date.
** Returns ways to role this target on count dice
** with sides sides.
*/
public long intwayray(int count, int sides, int target)
{
/* Range check. */
if (( sides > max_sides) || (count > max_dice) || (target > max_roll))
{
return 0 ;
}
/* Bring statistic array up to date. */
initwayray(count, sides) ;
/* Ways to roll this number */
long ways_to_roll = wayray[count][target] ;
return ways_to_roll ;
}
/*
** Returns the sum of the ways to roll all of the numbers
** less than or equal to target.
*/
public long sumwayray(int count_in, int sides, int target)
{
long sum = 0 ;
int index ;
/* Range check. */
if (( sides > max_sides) || (count_in > max_dice) || (target > max_roll))
{
return 0 ;
}
/* Bring statistic array up to date. */
initwayray(count_in, sides) ;
for (index = count_in ; index <= target ; index++)
{
sum += wayray[count_in][index] ;
}
return sum ;
}
}
Dice
Teaser - C
Recursive - C
3 loop - Java
Applet - Java
Applet Source
