from flask import Flask from flask_restx import Api, Resource, fields import random app = Flask(__name__) app.config.SWAGGER_UI_JSONEDITOR = True app.config['SWAGGER_UI_JSONEDITOR'] = True api = Api(app, version='1.0', title='Gamma World Dice', description='Rolled Dice As A Service') dice = api.namespace('dice', description='Dice operations') ability = api.namespace('ability', description='Ability operations') hp = api.namespace('hp', description='HP operations') dice_model = dice.model('Dice', { 'quantity': fields.Integer(required=True, description='The number of dice to roll'), 'geometry': fields.Integer(required=True, description='The number of sides on each die'), 'discard_lowest': fields.Boolean(required=False, default=False, description='Drop the lowest score') }) ability_model = ability.model('Ability', { 'chartype': fields.String(required=False, default="human", description='Character type') }) hp_model = hp.model('HP', { 'chartype': fields.String(required=False, default="human", description='Character type'), 'conscore': fields.Integer(required=True, description='Conscore') }) @api.route('/roll/dice', methods=['POST']) class RollDice(Resource): @dice.expect(dice_model) def post(self): data = api.payload quantity = data.get('quantity') geometry = data.get('geometry') discard_lowest = data.get('discard_lowest') if quantity is None or geometry is None: return {"message": "Required dice data not provided"}, 400 return roll_dices(quantity, geometry, discard_lowest), 200 @api.route('/roll/ability', methods=['POST']) class RollAbility(Resource): @ability.expect(ability_model) def post(self): data = api.payload chartype = data.get('chartype') if chartype == 'human': geometry = 8 else: geometry = 6 return roll_dices(4, geometry, True), 200 @api.route('/roll/hp', methods=['POST']) class RollHP(Resource): @hp.expect(hp_model) def post(self): data = api.payload chartype = data.get('chartype') conscore = data.get('conscore') if conscore is None: return {"message": "A constitution score is required"}, 400 if chartype == 'human': geometry = 8 else: geometry = 6 return roll_dices(conscore, geometry, False), 200 @api.route('/roll/chance', methods=['GET']) class RollChance(Resource): def get(self): return roll_dices(1, 100, False), 200 @api.route('/roll/tohit', methods=['GET']) class RollToHit(Resource): def get(self): return roll_dices(1, 20, False), 200 def roll_dices(dice_count, dice_sides, discard_lowest): roll_results = [] for _ in range(dice_count): roll_results.append(random.randint(1, dice_sides)) if discard_lowest and len(roll_results) > 0: roll_results.remove(min(roll_results)) result = { 'die-set': {'quantity': dice_count, 'geometry': dice_sides}, 'rolls': roll_results, 'sum': sum(roll_results) } return result if __name__ == '__main__': app.run()