File: rolldice.c

package info (click to toggle)
rolldice 1.10-4
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 96 kB
  • ctags: 40
  • sloc: ansic: 237; makefile: 60
file content (141 lines) | stat: -rw-r--r-- 3,515 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/**
 * rolldice.c - v1.10 - 25 Nov 2001
 * (c) Stevie Strickland, 1999-2001
 * 
 * This program has been placed under the GPL.  Any bugfixes or enhancements
 * will be greatly appreciated :)
 *
 * Stevie Strickland - sstrickl@cc.gatech.edu
 */

#include "rolldice.h"

// File pointer for random device
static FILE* ran_dev;

void init_random(rand_type rand_file) {
    if(rand_file == RANDOM) {
	if((ran_dev = fopen("/dev/random", "r")) == NULL) {
	    fprintf(stderr, "Error in opening /dev/random!\n");
	    exit(EXIT_FAILURE);
	}
    }
    else if((ran_dev = fopen("/dev/urandom", "r")) == NULL) {
	fprintf(stderr, "Error in opening /dev/urandom!\n");
	exit(EXIT_FAILURE);
    }
}

static int get_random(int sides) {
    unsigned int ret_value;

    unsigned int max = UINT_MAX;

    max -= max % sides;
again:
    if(!(fread(&ret_value, sizeof(unsigned int), 1, ran_dev) == 1)) {
	printf("Error in reading random device!\n");
	exit(EXIT_FAILURE);
    }
    if (ret_value >= max)
        goto again;
    return (int)(ret_value % sides);
}

/* rolldie() - Rolls a single die
 *
 * Parameters: int num_sides - number of sides of the die to roll
 * Returns: int - the result of the roll
 */
int rolldie ( int num_sides ) {

    return (1 + get_random(num_sides));
}

/* parse_string() - Parses a string for dice rolling attributes
 *
 * Parameters: char *dice_string - string to parse
 * Returns: int * - array of nums describing the different aspects of the 
 * dice to be rolled
 */
int *parse_string(char *dice_string) {
    int temp_int = -1, *dice_nums;

    if((dice_nums = malloc ( DICE_ARRAY_SIZE * sizeof(int))) == NULL)
	return NULL;

    dice_nums[NUM_ROLLS] = 1;
    dice_nums[NUM_DICE] = 1;
    dice_nums[NUM_SIDES] = 6;
    dice_nums[MULTIPLIER] = 1;
    dice_nums[MODIFIER] = 0;
    dice_nums[NUM_DROP] = 0;

    while(*dice_string != '\0') {
	if( isdigit(*dice_string) ) {
	    sscanf(dice_string, "%d", &temp_int);
	    while(isdigit(*(++dice_string)));
	}
	else {
	    switch(*dice_string) {
	    case 'd':
		if(temp_int > 0 && temp_int < MAXSHORT)
		    dice_nums[NUM_DICE] = temp_int;
		dice_string++;
		if(*dice_string == '%')
		    dice_nums[NUM_SIDES] = 100;
		else if( (sscanf(dice_string, "%d", &temp_int) < 1 ) ||
			 (temp_int < 2) || (temp_int >= MAXSHORT) ) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[NUM_SIDES] = temp_int;
		break;
	    case 's':
		if( (sscanf(++dice_string, "%d", &temp_int) < 1) ||
		    (temp_int < 0) || (temp_int >= MAXSHORT)) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[NUM_DROP] = temp_int;
		break;
	    case 'x':
		if( ( temp_int < 1 ) || (temp_int >= MAXSHORT) ) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[NUM_ROLLS] = temp_int;
		dice_string++;
		break;
	    case '*':
		if( (sscanf(++dice_string, "%d", &temp_int) < 1) ||
		    (temp_int < 0) || (temp_int >= MAXSHORT)) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[MULTIPLIER] = temp_int;
		break;
	    case '+':
		if( (sscanf(++dice_string, "%d", &temp_int) < 1) ||
		    (temp_int < 0) || (temp_int >= MAXSHORT)) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[MODIFIER] = temp_int;
		break;
	    case '-':
		if( (sscanf(++dice_string, "%d", &temp_int) < 1) ||
		    (temp_int < 0) || (temp_int >= MAXSHORT)) {
		    free(dice_nums);
		    return NULL;
		} else dice_nums[MODIFIER] = -temp_int;
		break;
	    default:
		dice_string++;
		break;
	    }
	    temp_int = 0;
	}
    }
    
    return dice_nums;
}