-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdie_roller.py
More file actions
166 lines (136 loc) · 6.77 KB
/
die_roller.py
File metadata and controls
166 lines (136 loc) · 6.77 KB
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# this code is designed to query a user for a die code, simulate that roll
# with pseudo random number generators, and save that output to a selected file
# initialize values
import random
import time
die_code = '0'
save_dir = raw_input("Save file name: ")
# start messages
print("Type 'help' in the die code to see examples\nOr 'stop' to end the program\n")
def get_die_code( die_code ):
# GET_DIE_CODE extracts X, Y, and Z from string 'X1dY1+X2dY2+...+Z'
# where X = (X1, X2, ..., XN) and same for Y
#
# also pulls out advantage or disadvantage into ADV, where
# 0 is no advantage, +1 means take the highest die, +2 means take
# the highest two dice, etc, and -1 means take the lowest die, -2
# means take the lowest two dice, etc
# advantage is 2d20h1 (takes highest one), disadvantage is 2d20l1
# remove comment for simplicity
hash_location = die_code.find('#')
if hash_location != -1:
COMMENT = die_code[hash_location+1:]
die_code = die_code[:hash_location]
die_code.replace(' ','')
#finds the location of +, d, h, and l in the code
plus_locations = [-1,] + [n for n in range(len(die_code)) if die_code.find('+',n) == n] + [n for n in range(len(die_code)) if die_code.find('-',n) == n]
plus_locations.sort()
d_locations = [n for n in range(len(die_code)) if die_code.find('d',n) == n]
lh_locations = [n for n in range(len(die_code)) if die_code.find('l',n) == n] + [n for n in range(len(die_code)) if die_code.find('h',n) == n]
#defines starting values of outputs
Z = 0
X = []
Y = []
ADV = []
COMMENT = ''
#if there aren't any dice being rolled, it's all just Z
if d_locations == []:
Z = int(die_code)
else:
#remove the Z from everything for simplicity
if d_locations[-1] < plus_locations[-1]:
Z = int(die_code[(plus_locations[-1]):])
die_code = die_code[:plus_locations[-1]]
#now we know how long X, Y, and ADV have to be
X = [0,]*len(d_locations)
Y = [0,]*len(d_locations)
ADV = [0,]*len(d_locations)
#redefine where the pluses and d's are
if die_code[0] != '-':
plus_locations = [-1,] + [n for n in range(len(die_code)) if die_code.find('+',n) == n] + [n for n in range(len(die_code)) if die_code.find('-',n) == n] + [len(die_code),]
else:
plus_locations = [n for n in range(len(die_code)) if die_code.find('+',n) == n] + [n for n in range(len(die_code)) if die_code.find('-',n) == n] + [len(die_code),]
plus_locations.sort()
d_locations = [n for n in range(len(die_code)) if die_code.find('d',n) == n] + [len(die_code),]
#for each type of die rolled
for i in range(len(d_locations)-1):
#get how many were rolled (all numbers before 'd')
if (plus_locations[i]+1-d_locations[i])!= 0:
X[i] = int(die_code[(plus_locations[i]+1):(d_locations[i])])
else:
X[i] = 1
if die_code[plus_locations[i]] == '-':
X[i] = -X[i]
#for each location with an l or h
for m in lh_locations:
#check if that location is in this type of die rolled
if d_locations[i]<m & m<d_locations[i+1]:
#extract how many sides there are and what the advantage was
Y[i] = int(die_code[(d_locations[i]+1):m]);
ADV[i] = int(die_code[(m+1):(plus_locations[i+1])]);
if die_code[m] == 'l':
ADV[i] = -ADV[i];
#if the roll wasn't with advantage, just get the number of sides
if ADV[i] == 0:
Y[i] = int(die_code[(d_locations[i]+1):(plus_locations[i+1])])
out = {'X':X, 'Y':Y, 'Z':Z, 'ADV':ADV, 'COMMENT':COMMENT}
return out
# run until the user is done
while (die_code != "stop"):
die_code = raw_input("\nDie code: ") # get raw_input
# user asked for help
if die_code == "help":
print("\nYou can enter a die code into the 'Die code' prompt. The program will then simulate the given roll and save it to the previously) specified file.\n\n")
print("To roll a single die with N sides, enter 'dN'")
print("To roll X dice with N sides and add them together, enter 'XdN'")
print("Or multiple dice with 'XdN+YdM+...'")
print("To then add B to the sum, enter 'XdN+B'\n")
print("To only count the highest H dice, type 'XdNhH'")
print("To only count the lowest L dice, type 'XdNlL'\n")
print("To add a comment to the save file, type '# <comment>' after the die code\n")
# user asked to stop
elif die_code == "stop":
print("Stopping")
# must be a die code if not help or stop
else:
#parse the die code
out = get_die_code(die_code)
X = out['X']
Y = out['Y']
Z = out['Z']
ADV = out['ADV']
COMMENT = out['COMMENT']
#roll the die code
roll_list = []
roll_total = 0
for i in range(len(X)): #for each die type
this_roll_list = []
this_roll_total = 0
#for each die in that type
for j in range(abs(X[i])):
this_roll = random.randint(1,Y[i]) #roll that die
this_roll_list = this_roll_list + [this_roll,] #add to list of rolls
if ADV[i] == 0:
this_roll_total = this_roll + this_roll_total #add to total roll
#do advantage
if ADV[i] > 0:
sorted_list = sorted(this_roll_list)
for k in sorted_list[-ADV[i]:]:
this_roll_total = this_roll_total + k
#do disadvantage
if ADV[i] < 0:
sorted_list = sorted(this_roll_list)
for k in sorted_list[:-ADV[i]]:
this_roll_total = this_roll_total + k
if X[i] < 0:
this_roll_total = -this_roll_total
this_roll_list = [-x for x in this_roll_list]
roll_list = roll_list + this_roll_list
roll_total = roll_total + this_roll_total
roll_total = roll_total + Z
#save the result
file = open(str(save_dir),"a")
file.write(time.ctime()+':\n"'+die_code+'":\n'+str(roll_total)+' '+str(roll_list)+' '+str(COMMENT)+'\n\n')
file.close()
#display the result
print(str(roll_total)+' '+str(roll_list))