int ways(int to_hit, int sides, int count) /* ** Calculates the number of ways to roll to_hit ** on count dice with sides sides. ** ** Recursive subroutine. Recursion is a software ** term for a subroutine which calls itself. ** Recursion is not a moral risk, but is a risk to the ** sanity of a programmer not used to the method. ** ** Entering zero or negative numbers for to_hit, ** sides, or count should not hang the routine, ** but no metaphysical comment is intended on the ** true meaning of rolling negative numbers of dice. ** This routine is intended for dice statistics, not ** as a Zen teaching tool. ;-) */ { int sum ; int index ; /*
** The lowest number that can be rolled is count. ** The highest is count times sides. ** If to_hit is outside this range, can't roll it. */ if (to_hit < count) return 0 ; if (to_hit > (count * sides)) return 0 ; /* ** To_hit can be rolled. ** If there is only one die, it can only ** be rolled one way. ** ** Requests for zero or negative dice count ** return one just to make sure no infinite ** recursive call sequences can hang things up. ** In normal operation, count will always be positive. */ if (count <= 1) return 1 ; /* ** It is possible to roll this number. ** There are two or more dice being rolled. ** No instant answer. We are going recursive. ** Initialize sum counter. */ sum = 0 ; /* ** One of the dice has sides possible ways to fall. ** Loop through each possibility. */ for (index = 1 ; index <= sides ; index++) { /* ** Index holds how one of the dice has fallen. ** How many ways can the rest of the dice fall ** such that when index is added, the total is to_hit? ** ** As the call requests fewer dice and a smaller total, ** the recursive calls do close. Recursion is not magic. ** It only works by breaking down big problems ** into smaller problems. Ways keeps ** calling ways with smaller and smaller parameters until ** to_hit is out of range or count becomes one. ** A zero or one is then returned, and added into sum. ** ** Recursion only works in languages where every time a ** routine is called, new storage is allocated for that ** invocation's variables. If 12 dice are being rolled, ** up to twelve copies of index and sum might be set up ** in the computer's memory. */ sum += ways(to_hit - index, sides, count - 1) ; } return sum ; }