dice-engine 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ from .die import Die
2
+ from .cdice import CDice
3
+ from .idice import IDice
dice_engine/cdice.py ADDED
@@ -0,0 +1,28 @@
1
+ from typing import Type, Any
2
+ class CDice:
3
+ def __init__(self, amount: int, classe: Type, sides: int = 6, **kwargs: Any):
4
+ self.sides = max(sides, 2)
5
+ self.amount = max(amount, 2)
6
+ kwargs["sides"] = self.sides
7
+ self.__dices = [classe(**kwargs) for _ in range(self.amount)]
8
+ def roll_all(self):
9
+ for i in self.__dices:
10
+ i.roll()
11
+ def specific_roll(self, index: int):
12
+ try:
13
+ self.__dices[index].roll()
14
+ except IndexError:
15
+ raise IndexError(f"Invalid Index: {index}")
16
+ def results(self):
17
+ totals = [0 for _ in range(self.sides)]
18
+ most_sides = 0
19
+ for i in self.__dices:
20
+ if i.sides > most_sides: most_sides = i.sides
21
+ for e in range(len(totals)):
22
+ totals[e] += i.get_results()[e]
23
+ print(f"Max Sides: {most_sides}")
24
+ for id, roll in enumerate(totals):
25
+ if roll > 1:
26
+ print(f"Total Rolls on {id + 1}: {roll}")
27
+ def get_dices(self):
28
+ return self.__dices
dice_engine/die.py ADDED
@@ -0,0 +1,15 @@
1
+ from random import randint
2
+ from typing import Any
3
+ class Die:
4
+ def __init__(self, sides: int = 6):
5
+ self.sides = max(sides, 2)
6
+ self._resultss = [0 for _ in range(self.sides)]
7
+ def roll(self) -> Any:
8
+ number = randint(1, self.sides)
9
+ self._resultss[number - 1] += 1
10
+ return number
11
+ def results(self):
12
+ for id, roll in enumerate(self._resultss):
13
+ print(f"Rolls on {id + 1}: {roll}")
14
+ def get_results(self):
15
+ return self._resultss
dice_engine/idice.py ADDED
@@ -0,0 +1,48 @@
1
+ from dice_engine.die import Die
2
+ class IDice:
3
+ def __init__(self, dices: list[Die]):
4
+ self.__dices = dices
5
+ def roll_all(self):
6
+ for i in self.__dices:
7
+ i.roll()
8
+ def specific_roll(self, index: int):
9
+ try:
10
+ self.__dices[index].roll()
11
+ except IndexError:
12
+ raise IndexError(f"Invalid Index: {index}")
13
+ def results(self, combine: bool = True):
14
+ if combine:
15
+ most_sides = 0
16
+ for i in self.__dices:
17
+ if i.sides > most_sides: most_sides = i.sides
18
+ totals = [0] * most_sides
19
+ for i in self.__dices:
20
+ for e in range(len(i.get_results())):
21
+ totals[e] += i.get_results()[e]
22
+ print(f"Max Sides: {most_sides}")
23
+ for id, total in enumerate(totals):
24
+ if total > 1:
25
+ print(f"Total Rolls on {id + 1}: {total}")
26
+ else:
27
+ indexNum = 1
28
+ for i in self.__dices:
29
+ rolled = []
30
+ res = i.get_results()
31
+ j = len(res)
32
+ for e in range(j):
33
+ if res[e] > 0:
34
+ rolled.append(e + 1)
35
+ rolled = str(rolled)
36
+ rolled = rolled.replace("[", "")
37
+ rolled = rolled.replace("]", "")
38
+ print(f"{i.__class__.__name__} {indexNum}(Rolled {rolled}): ")
39
+ print(f"Max sides: {i.sides}")
40
+ for id, rolls in enumerate(i.get_results()):
41
+ if rolls > 1:
42
+ print(f" Rolls on {id + 1}: {rolls}")
43
+ indexNum += 1
44
+ def get_dices(self):
45
+ return self.__dices
46
+ def see_dices(self):
47
+ for id, die in enumerate(self.__dices):
48
+ print(f"{id + 1}. {die.__class__.__name__}")
@@ -0,0 +1,389 @@
1
+ Metadata-Version: 2.4
2
+ Name: dice_engine
3
+ Version: 0.1.0
4
+ Summary: A lightweight Dice Engine that allows you to create infinite dice types
5
+ Author-email: Dillan Notice <noticedillan2@gmail.com>
6
+ License: MIT
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Dynamic: license-file
11
+
12
+ # Dice Engine
13
+ ***Dice Engine: Infinite Possibilities***
14
+
15
+ A lightweight Dice Engine that allows you to create infinite dice types
16
+ ## Features
17
+ - **Lightweight**: Only *3 core classes* and a total of **90 lines**
18
+
19
+ - **Extensive**: You can create `infinite` die classes using this framework
20
+
21
+ - **OOP-based**: Uses OOP for its core features
22
+
23
+ - **No external dependencies**: There are no external dependencies(only `randint` from `random` and `Any` from `typing`. These are things you get when installing python)
24
+
25
+ ## Installation
26
+ To install the dice engine, open your terminal and do:
27
+
28
+ ```bash
29
+ pip install dice_engine
30
+ ```
31
+ Thats it!
32
+ ## Importing
33
+ The Dice engine has 3 main Classes:
34
+
35
+ 1. `Die()`
36
+ 2. `CDice()`
37
+ 3. `IDice()`
38
+
39
+ To import the classes, do:
40
+
41
+ ```python
42
+ # importing Die()
43
+ from dice_engine import Die
44
+ # importing CDice()
45
+ from dice_engine import CDice
46
+ # importing IDice()
47
+ from dice_engine import IDice
48
+ ```
49
+ To import all classes, its **Recommended** you do `from dice_engine import Die, CDice, IDice` rather than `import dice_engine` so you dont need to do something like `dice_engine.Die()`
50
+ # Part 1: Classes of the Engine
51
+ ## Class 1: Die()
52
+ The base die class for creating **Die with a fixed number of Sides**
53
+
54
+ It is created like this:
55
+
56
+ ```python
57
+ Die(sides: int)
58
+ # example
59
+ die = Die(6) # creating a d6 die
60
+ # minimum sides: 2 sides
61
+ ```
62
+ ## Die Methods
63
+ # roll()
64
+ Quite simple, a method that ***Rolls the Die once***:
65
+
66
+ ```python
67
+ # example
68
+ die = Die(7) # a d7 Die
69
+ print(die.roll()) # eg, 5
70
+ ```
71
+ `roll()` returns the number that was rolled(between **1 and number of sides**)
72
+
73
+ # results()
74
+ Each `Die` object stores how much times a number was rolled(stored in a list), `results()` shows you how much times a number was rolled in a nice format.
75
+
76
+ ```python
77
+ die = Die(6) # a d6 die
78
+ for _ in range(5):
79
+ die.roll() # rolling 5 times(for loop)
80
+ die.results()
81
+ # example output:
82
+ # Rolls on 1: 0
83
+ # Rolls on 2: 1
84
+ # Rolls on 3: 1
85
+ # Rolls on 4: 1
86
+ # Rolls on 5: 1
87
+ # Rolls on 6: 1
88
+ ```
89
+ Doesnt return anything, prints directly
90
+ # get_results()
91
+ Returns the array of how much times a number was rolled
92
+
93
+ ```python
94
+ die = Die(9)
95
+ die.roll()
96
+ print(die.get_results()) # eg, [0,0,0,0,0,1,0,0,0]
97
+ ```
98
+
99
+ ## Class 2: CDice()
100
+ `CDice` is short for as `Class Dice`
101
+
102
+ A factory for **mass producing Dice with the same properties(sides, class and arguments)**.
103
+
104
+ It is Created like this:
105
+
106
+ ```python
107
+ from typing import Type, Any
108
+
109
+ CDice(amount: int, classe: Type, sides: int, **kwargs: Any)
110
+ # minimum amount: 2
111
+ # minimum sides: 2
112
+ # Type means it accepts a class reference
113
+ ```
114
+ ```python
115
+ # example
116
+ dice = CDice(20, Die, 6) # 20 d6 Dice/20 Die instances each having 6 sides
117
+ # kwargs appear later
118
+ ```
119
+ You only use kwargs in CDice when you give it **a class that accepts more than 1 arguments**, ***ignore*** **the kwargs when the class you give CDice only takes a sides argument**
120
+
121
+
122
+ ## CDice Methods
123
+ # roll_all()
124
+ Very simple, rolls **ALL** the dice inside the `CDice` instance **ONCE**
125
+
126
+ ```python
127
+ dice = CDice(10, Die, 5)
128
+ dice.roll_all()
129
+ dice.results() # remember from Die()?
130
+ # example output:
131
+ # Max Sides: 5
132
+ # Total Rolls on 1: 20
133
+ # Total Rolls on 2: 10
134
+ # Total Rolls on 4: 10
135
+ # Total Rolls on 5: 10
136
+ ```
137
+ **Note: Sides that were not rolled does not appear in** `results()`
138
+
139
+ `roll_all()` **doesnt return anything**
140
+ # specific_roll(index: int)
141
+ Finally a method that needs a parameter.
142
+
143
+ `specific_roll()` rolls a specific die at the index you put in.
144
+
145
+ ```python
146
+ specific_roll(index: int)
147
+ ```
148
+ ```python
149
+ dice = CDice(10, Die, 2)
150
+ dice.specific_roll(5) # rolling the die at index 5
151
+ dice.results()
152
+ # output(example):
153
+ # Max Sides: 2
154
+ # Total rolls on 2: 1
155
+ ```
156
+ **Note: Index value must be zero-based**
157
+
158
+ **Note 2: Putting an invalid index will raise an IndexError**
159
+
160
+ doesnt return anything
161
+
162
+ # results()
163
+ Shows you the amount of times a **Side was rolled in total**
164
+
165
+ you can see examples of `results()` in the previous examples above
166
+
167
+ doesnt return anything, prints directly
168
+
169
+ # get_dices()
170
+ Returns **the array of class instances stored inside the `CDice` instance**
171
+ ## Class 3: IDice()
172
+ `IDice` is short for ` Instance Dice`
173
+
174
+ This is used to manage **Different die types at the same time**, useful when wanting to roll and manage different kinds of dice
175
+
176
+ It is *Created like this:*
177
+ ```python
178
+ IDice(dices: list[Die]) # Accepts a list of Die objects or a list of Die subclass objects or both
179
+ ```
180
+ ```python
181
+ dice = IDice([Die(3), Die(7), Die(2)])
182
+ ```
183
+ ## IDice Methods
184
+ # roll_all()
185
+ *Very Simple*, rolls **All** the Dice in the IDice instance **ONCE**
186
+ ```python
187
+ dice = IDice([Die(6), Die(7)])
188
+ dice.roll_all() # rolls the 2 Die objects once
189
+ #dice.results()
190
+ ```
191
+ **DOESNT RETURN ANYTHING**
192
+ # specific_roll(index: int)
193
+ *Works exactly like the one in* `CDice`
194
+ ```python
195
+ dice = IDice([Die(8), Die(9), Die(10)])
196
+ dice.specific_roll(1) # rolls the Die(9)
197
+ #dice.results(False)
198
+ ```
199
+ **Revisit `specific_roll` in `CDice` for more understanding**
200
+
201
+ **Doesnt return anything**
202
+ # results(combine: bool)
203
+ This is *different* from the one in `CDice`
204
+
205
+ `results()` has 2 Modes:
206
+ - Mode 1: when **combine = True**(Default Mode)
207
+ - Mode 2: when **combine = False**
208
+
209
+ Both modes dont return anything
210
+ ## Mode 1: combine = True
211
+ This is *quite simple*, it combines the results from **All** dice in the `IDice` instance and displays the total number of times a side was rolled.
212
+
213
+ ***Excluding sides that were not rolled***
214
+
215
+ Works exactly like `results()` from `CDice`
216
+ ## Mode 2: combine = False
217
+ This mode is *precise*
218
+
219
+ This *mode* gives you the results of each dice *seperately*
220
+ ```python
221
+ dice = IDice([Die(2), Die(3), Die(4)])
222
+ dice.roll_all()
223
+ dice.results(False)
224
+ ```
225
+ ```python
226
+ # example output
227
+ # Die 1(Rolled 2):
228
+ # Max Sides: 2
229
+ # Rolls on 2: 1
230
+ # Die 2(Rolled 1):
231
+ # Max Sides: 3
232
+ # Rolls on 1: 1
233
+ # Die 3(Rolled 4):
234
+ # Max Sides: 4
235
+ # Rolls on 4: 1
236
+ ```
237
+ ```python
238
+ # General Format
239
+ # DieClassName X(Rolled nums, etc)
240
+ # Max Sides: Sides
241
+ # Rolls
242
+ ```
243
+ Use this Mode if you want to see the *results* for **Each Individual Die**
244
+ # get_dices()
245
+ returns the list of instances inside the `IDice` instance
246
+ # see_dices()
247
+ Lets you see what class each instance inside `IDice` belongs to, doesnt return anything
248
+ ```python
249
+ dice = IDice([Die(10), Die(100), Die(1000)])
250
+ dice.see_dices()
251
+ # Output
252
+ # 1. Die
253
+ # 2. Die
254
+ # 3. Die
255
+ ```
256
+ ```python
257
+ # General Format
258
+
259
+ # X. DieClassName
260
+ ```
261
+ Well, thats all the main classes. *The interesting part is just starting*
262
+
263
+ # Part 2: Creating Custom Dice
264
+ Welcome, this is a unique and interesting part of the engine. To create a custom die type, these *4 Criteria* **MUST BE MET**:
265
+
266
+ Die Idea: A die that rolls a certain amount of times, lets call it `MultiDie`
267
+
268
+ ## Criteria 1: Your Die type class must inherit from Die()
269
+ Yes, your custom die type must be a class.
270
+
271
+ example:
272
+ ```python
273
+ class MultiDie(Die):
274
+ ...
275
+ ```
276
+ ```python
277
+ # Generally:
278
+ class DieName(Die):
279
+ ```
280
+ ## Criteria 2: `__init__`must have `super().__init__(max(sides, 2))` and a sides parameter
281
+ Very simple, Inside `__init__` of your custom die class, it must have `super().__init__(max(sides, 2))` it serves 2 imporant reasons:
282
+
283
+ 1. Does `self.sides` for you
284
+ 2. Gives your class `self._resultss`(very important list)
285
+
286
+ Example
287
+
288
+ ```python
289
+ class MultiDie(Die):
290
+ def __init__(self, sides, rolls):
291
+ super().__init__(max(sides, 2))
292
+ self.rolls = max(rolls, 2)
293
+ ```
294
+ ## Criteria 3: Override roll() from Die()
295
+ In this criteria, you override the roll method to implement *how* your custom die rolls
296
+
297
+ **RELATED TO CRITERIA 4**
298
+
299
+ example:
300
+ ```python
301
+ class MultiDie(Die):
302
+ def __init__(self, sides, rolls):
303
+ super().__init__(max(sides, 2))
304
+ self.rolls = max(rolls, 2)
305
+ def roll(self):
306
+ number = 0
307
+ for _ in range(self.rolls):
308
+ number = randint(1, self.sides) # You got randint when you imported Die()
309
+ return number
310
+ # roll() basically does nothing because criteria 4 isnt completed
311
+ ```
312
+ ## Criteria 4: Using `self._resultss` to update your dice roll results
313
+ The last but most important criteria, updating your results list
314
+
315
+ `self._resultss` is a list that stores how much times a side of the dice was rolled for all sides of the die
316
+
317
+ the list is updated via:
318
+
319
+ ```python
320
+ self._resultss[number - 1] += 1
321
+ # number = the random number you rolled
322
+ ```
323
+
324
+ example:
325
+
326
+ ```python
327
+ # A class that met all criteria
328
+ class MultiDie(Die): # Criteria 1 check
329
+ def __init__(self, sides, rolls): # sides param
330
+ super().__init__(max(sides, 2)) # Criteria 2 check
331
+ self.rolls = max(rolls, 2)
332
+ def roll(self): # Criteria 3 check
333
+ number = 0
334
+ for _ in range(self.rolls):
335
+ number = randint(1, self.sides)
336
+ self._resultss[number - 1] += 1 # Criteria 4 check
337
+ return number # you can return Anything
338
+ ```
339
+ Remember kwargs back at `Cdice`?
340
+
341
+ The kwargs are used to enter additional arguments into `CDice` apart from sides
342
+
343
+
344
+ ```python
345
+ dice = CDice(10, MultiDie, 8, rolls=5)
346
+ # kwargs being used
347
+ ```
348
+ ## Additional examples
349
+ Idea: ExplodigDie, rolls again if you roll the highest number
350
+
351
+ ```python
352
+ class ExplodingDie(Die):
353
+ def __init__(self, sides = 6):
354
+ super().__init__(max(sides, 2))
355
+ def roll(self):
356
+ explosions = 0
357
+ number = randint(1, self.sides)
358
+ self._resultss[number - 1] += 1
359
+ roll = number
360
+ while roll == self.sides:
361
+ roll = randint(1, self.sides)
362
+ self._resultss[roll - 1] += 1
363
+ explosions += 1
364
+ return explosions
365
+ ```
366
+ Idea 2: RiggedDie, self explanitory
367
+ ```python
368
+ from random import choices
369
+ class RiggedDie(Die):
370
+ def __init__(self, rig = 6, sides = 6, bias = 2):
371
+ super().__init__(max(sides, 2))
372
+ self.bias = max(bias, 1)
373
+ self.rig = max(rig, sides)
374
+ def roll(self):
375
+ weights = [1] * self.sides
376
+ weights[self.rig - 1] = self.bias
377
+ number = choices(range(1, self.sides + 1), weights = weights)[0]
378
+ self._resultss[number - 1] += 1
379
+ return number
380
+ ```
381
+ Creativity holds no bounds
382
+ ## Additional info
383
+ As long as you follow these 4 criteria, **Any dice can be accepted into `CDice` and `IDice`
384
+
385
+ Remember: *You can create **Any** Die type ypu want*
386
+
387
+ This is the first and **Last** Version of this engine
388
+
389
+ There will be no updates whatsoever
@@ -0,0 +1,9 @@
1
+ dice_engine/__init__.py,sha256=G2vbzrI2NZFGwGDUBAqlNRJd8HliXUa44dUpk3nftWo,72
2
+ dice_engine/cdice.py,sha256=0irpJCarCVgvdbnwJRtwu-LdK0SE0GVJAR2xOP1P6yk,1074
3
+ dice_engine/die.py,sha256=WWUaLZxQ8bYqIVohiU6WvTV0y1NnD4XsQwMX26FQrYM,513
4
+ dice_engine/idice.py,sha256=glihTEK7Y3l9Fqudzp3yetaSPH6TSic1aYMzy5kN5WE,1887
5
+ dice_engine-0.1.0.dist-info/licenses/LICENSE,sha256=Wb23v3DBuxjVrKbCpNrv8NdyYNCn8JeKw6APXLFah_E,1114
6
+ dice_engine-0.1.0.dist-info/METADATA,sha256=TcPc5shuuRRQTc1tF9WR7EH-TfhT_p6-16yxG7s5Otk,10838
7
+ dice_engine-0.1.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
8
+ dice_engine-0.1.0.dist-info/top_level.txt,sha256=eTvp7CN2EEqDHOZIEa7MRjc_QUOu4DA8SN_N0AUDixo,12
9
+ dice_engine-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dillan Notice (unmSomething)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ dice_engine