Last active
January 28, 2023 14:49
-
-
Save nickyreinert/05dc269fc5091d9ecc7b03836970cab0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 314, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import random\n", | |
"from pprint import pprint as pp\n", | |
"from tqdm import tqdm\n", | |
"import csv\n", | |
"import json\n", | |
"import math\n", | |
"import sys\n", | |
"\n", | |
"class GameEngine:\n", | |
"\n", | |
" characters = {}\n", | |
" characters_variations = []\n", | |
" variable_attributes = {}\n", | |
" bonus_attack_activator = [1, 2, 3, 4, 5, 6]\n", | |
" bonus_defense_activator = [1, 2, 3, 4, 5, 6]\n", | |
" escape_activator = [2, 3, 4, 5]\n", | |
" dice_range = [1, 2, 3, 4, 5, 6]\n", | |
" debug = False\n", | |
" stats_summary = []\n", | |
" stats = []\n", | |
" stats_per_character = []\n", | |
"\n", | |
" def calculateAttackValue(self, character):\n", | |
" \n", | |
" attack_value = (1 + character['attributes']['attribute_1']) * (1 + character['attributes']['attribute_3'])\n", | |
" eleveated_attack_value = attack_value\n", | |
" # roll the attack dice\n", | |
" if 'attack' in character['bonus']:\n", | |
" if random.choice(self.dice_range) in self.bonus_attack_activator:\n", | |
" dice_1 = random.choice(self.dice_range)\n", | |
" dice_2 = random.choice(self.dice_range)\n", | |
" \n", | |
" if dice_1 > dice_2:\n", | |
" eleveated_attack_value *= dice_1\n", | |
" else:\n", | |
" eleveated_attack_value *= dice_2\n", | |
"\n", | |
" if self.debug : print(f'\\tbase attack: {attack_value}, elevated attack {eleveated_attack_value}')\n", | |
"\n", | |
" return eleveated_attack_value, attack_value\n", | |
"\n", | |
" def calculateDefenseValue(self, character):\n", | |
"\n", | |
" defense_value = character['attributes']['attribute_2'] + character['attributes']['attribute_4']\n", | |
" elevated_defense_value = defense_value\n", | |
" \n", | |
" # roll the defense dice\n", | |
" if 'defense' in character['bonus']:\n", | |
" if random.choice(self.dice_range) in self.bonus_defense_activator:\n", | |
" \n", | |
" dice_1 = random.choice(self.dice_range)\n", | |
" dice_2 = random.choice(self.dice_range)\n", | |
" \n", | |
" if dice_1 > dice_2:\n", | |
" elevated_defense_value += dice_1\n", | |
" else:\n", | |
" elevated_defense_value += dice_2\n", | |
"\n", | |
" if self.debug : print(f'\\tbase defense: {defense_value}, elevated defense {elevated_defense_value}')\n", | |
"\n", | |
" return elevated_defense_value, defense_value\n", | |
"\n", | |
" def calculateEscapeValue(self, character):\n", | |
" # roll the escape dice\n", | |
" escape_success = False\n", | |
" if 'escape' in character['bonus']:\n", | |
" if random.choice(self.dice_range) in self.bonus_attack_activator:\n", | |
" escape_bonus = random.choice(self.dice_range)\n", | |
"\n", | |
" if escape_bonus in self.escape_activator:\n", | |
" escape_success = True \n", | |
" else:\n", | |
" escape_success = False\n", | |
" \n", | |
" if self.debug : print(f'\\tescape success: {escape_success}')\n", | |
"\n", | |
" return escape_success\n", | |
"\n", | |
" def __init__(self, \n", | |
" debug=False, \n", | |
" bonus_attack_activator = [1, 2, 3, 4, 5, 6],\n", | |
" bonus_defense_activator = [1, 2, 3, 4, 5, 6],\n", | |
" escape_activator = [1, 2, 3, 4, 5, 6],\n", | |
" dice_range = [1, 2, 3, 4, 5, 6],\n", | |
" variable_attributes = {}\n", | |
" ):\n", | |
"\n", | |
" self.debug = debug\n", | |
" self.bonus_attack_activator = bonus_attack_activator\n", | |
" self.bonus_defense_activator = bonus_defense_activator\n", | |
" self.escape_activator = escape_activator\n", | |
" self.dice_range = dice_range\n", | |
" self.variable_attributes = variable_attributes\n", | |
"\n", | |
" self.stats_summary = []\n", | |
" self.stats = []\n", | |
" self.stats_per_character = []\n", | |
" \n", | |
" with open(f'characters.json', 'r') as file:\n", | |
" self.characters = json.load(file)\n", | |
"\n", | |
" def preparePlayers(self, players = 4, characters_per_stack = 0, sibblings_per_character = 1):\n", | |
" \n", | |
" if self.debug == True: print(f'Creating {players} players with {characters_per_stack} characters per stack from a deck of {sibblings_per_character * len(self.characters)} characters ({len(self.characters)} unique)')\n", | |
" \n", | |
" max_characters_per_stack = math.floor(sibblings_per_character * len(self.characters) / players)\n", | |
" if characters_per_stack > max_characters_per_stack:\n", | |
" print(f'Error: too many characters per stack. Maximum is {max_characters_per_stack}')\n", | |
" sys.exit()\n", | |
"\n", | |
" # put all characters x sibblings per characters to a list\n", | |
" available_characters = sibblings_per_character * list(self.characters.keys())\n", | |
" # create a dict that contains a unique id for every card\n", | |
" full_stack = {index: character_id for index, character_id in enumerate(available_characters)}\n", | |
" # create a second dict that contanins a unique id for available cards only\n", | |
" available_stack = full_stack.copy()\n", | |
"\n", | |
" self.player_stacks = {}\n", | |
" for player in range(1, players + 1, 1):\n", | |
" \n", | |
" # get a sample of unique ids for all characters from the available stack\n", | |
" current_stack = random.sample(list(available_stack.keys()), characters_per_stack)\n", | |
"\n", | |
" # add sampled stack of characters to the player stack\n", | |
" # almost the same list comphrehension as above, but index IN current_stack instead of index NOT IN current_stack\n", | |
" self.player_stacks['player_no_' + str(player)] = {index: full_stack[index] for index in available_stack if index in current_stack}\n", | |
" \n", | |
" # remove selected characters from the available stack, to not select them again\n", | |
" # use unique ids from current_stack\n", | |
" available_stack = {index: full_stack[index] for index in available_stack if index not in current_stack}\n", | |
"\n", | |
" if self.debug == True: print(f'\\tDone, {len(available_stack)} characters left in the deck')\n", | |
"\n", | |
" def reindex_player_stacks(self):\n", | |
" for player in self.player_stacks:\n", | |
" reindexed_stack = {}\n", | |
" index = 0\n", | |
" for card in self.player_stacks[player]:\n", | |
" reindexed_stack[index] = self.player_stacks[player][card]\n", | |
" index += 1\n", | |
"\n", | |
" self.player_stacks[player] = reindexed_stack\n", | |
"\n", | |
" def simulateRealGames(self, games = 1, round_limit = 100, characters_per_stack = 0, sibblings_per_character = 1, players = 4):\n", | |
"\n", | |
" if self.debug == True: print(f'Start simulation of {games} games for {players} players and {len(self.characters_variations)} character variations')\n", | |
"\n", | |
" # first loop through all character variations\n", | |
" for character_variation in self.characters_variations:\n", | |
"\n", | |
" # now loop through n games\n", | |
" for game in range(1, games + 1):\n", | |
" \n", | |
" stats_per_character = {}\n", | |
"\n", | |
" self.preparePlayers(players, characters_per_stack, sibblings_per_character)\n", | |
"\n", | |
" game_is_running = True\n", | |
" current_player_index = 0\n", | |
" current_round = 0\n", | |
" # finally loop through rounds until one player wins\n", | |
" \n", | |
" while game_is_running:\n", | |
"\n", | |
" current_round += 1\n", | |
" if current_round > round_limit:\n", | |
" game_is_running = False\n", | |
" if self.debug == True: print(f'#########\\nGame {game} is over, round limit of {round_limit} reached')\n", | |
" if self.debug == True: \n", | |
" print(f'Game stats:')\n", | |
" for player in self.player_stacks:\n", | |
" print(f'\\t{player}: {len(self.player_stacks[player])} cards left')\n", | |
" self.stats_summary.append({\n", | |
" 'characters_variation': character_variation['variation'],\n", | |
" 'game': game,\n", | |
" 'rounds_played': round_limit,\n", | |
" 'winner': None\n", | |
" })\n", | |
" break\n", | |
"\n", | |
" # re-index player stacks after each round\n", | |
" self.reindex_player_stacks()\n", | |
"\n", | |
" # ['player_no_1', 'player_no_2', 'player_no_3', 'player_no_4']\n", | |
" # ['player_no_1', 'player_no_2', 'player_no_4']\n", | |
"\n", | |
" if current_player_index >= len(self.player_stacks): current_player_index = 0\n", | |
" \n", | |
" # look for one opponent\n", | |
" current_player = list(self.player_stacks.keys())[current_player_index]\n", | |
" available_opponents = list(self.player_stacks.keys())\n", | |
" available_opponents.remove(list(self.player_stacks.keys())[current_player_index])\n", | |
" current_opponent = random.choice(available_opponents)\n", | |
" \n", | |
" if self.debug: print(f'Round {current_round}, {current_player} vs {current_opponent}')\n", | |
"\n", | |
" stats_per_character = self.fight(character_variation=character_variation, attacker=current_player, defender=current_opponent, round=current_round, game=game, stats_per_character=stats_per_character)\n", | |
"\n", | |
" # check if one player has no cards left\n", | |
" for player in list(self.player_stacks.keys()):\n", | |
" if len(self.player_stacks[player]) == 0:\n", | |
" if self.debug: print(f'Player {player} has no cards left and leaves the game')\n", | |
" del self.player_stacks[player]\n", | |
" \n", | |
" # check if only one player is left\n", | |
" if len(self.player_stacks) == 1:\n", | |
" game_is_running = False\n", | |
" if self.debug: print(f'Game {game} is over after {current_round} rounds, {list(self.player_stacks.keys())[0]} wins')\n", | |
" self.stats_summary.append({\n", | |
" 'characters_variation': character_variation['variation'],\n", | |
" 'game': game,\n", | |
" 'rounds_played': current_round,\n", | |
" 'winner': list(self.player_stacks.keys())[0]\n", | |
" })\n", | |
"\n", | |
" break\n", | |
"\n", | |
" current_player_index += 1\n", | |
" \n", | |
" for character_id in stats_per_character:\n", | |
" self.stats_per_character.append(stats_per_character[character_id])\n", | |
"\n", | |
" def fight(self, character_variation, attacker, defender, round, game, stats_per_character):\n", | |
"\n", | |
" character_variation_id = character_variation['variation']\n", | |
" characters = character_variation['characters']\n", | |
"\n", | |
" # get the first character of each, attacker and defender stack\n", | |
" attacking_character = self.player_stacks[attacker][0]\n", | |
" defending_character = self.player_stacks[defender][0] \n", | |
"\n", | |
" if not attacking_character in stats_per_character:\n", | |
" stats_per_character[attacking_character] = {\n", | |
" 'flight': 'real_game',\n", | |
" 'character': attacking_character,\n", | |
" 'characters_variation': character_variation['variation'],\n", | |
" 'game': game,\n", | |
" 'round': round,\n", | |
" 'wins_count': 0,\n", | |
" 'losses_count': 0,\n", | |
" 'draws_count': 0,\n", | |
" 'escapes_count': 0\n", | |
" }\n", | |
"\n", | |
" if not defending_character in stats_per_character:\n", | |
" stats_per_character[defending_character] = {\n", | |
" 'flight': 'real_game',\n", | |
" 'character': defending_character,\n", | |
" 'characters_variation': character_variation['variation'],\n", | |
" 'game': game,\n", | |
" 'round': round,\n", | |
" 'wins_count': 0,\n", | |
" 'losses_count': 0,\n", | |
" 'draws_count': 0,\n", | |
" 'escapes_count': 0\n", | |
" }\n", | |
"\n", | |
" # calculate the base attack and defense values\n", | |
" attack_value, base_attack_value = self.calculateAttackValue(characters[attacking_character])\n", | |
" defense_value, base_defense_value = self.calculateDefenseValue(characters[defending_character])\n", | |
"\n", | |
" escape_success = self.calculateEscapeValue(characters[attacking_character])\n", | |
"\n", | |
" stats = {\n", | |
" 'flight': 'real_game',\n", | |
" 'characters_variation': character_variation_id,\n", | |
" 'game': game,\n", | |
" 'round': round,\n", | |
" 'attacker': attacker,\n", | |
" 'defender': defender,\n", | |
" 'attacking_character': attacking_character,\n", | |
" 'defending_character': defending_character,\n", | |
" 'base_attack_value': base_attack_value,\n", | |
" 'base_defense_value': base_defense_value,\n", | |
" 'attack_value': attack_value,\n", | |
" 'defense_value': defense_value,\n", | |
" 'escape_success': escape_success\n", | |
" }\n", | |
"\n", | |
" # finish the fight\n", | |
" if escape_success == False:\n", | |
"\n", | |
" if attack_value > defense_value:\n", | |
" \n", | |
" if self.debug : print(f'\\t{attacker} wins')\n", | |
" # move first card from defender stack to attacker stack\n", | |
" # same for first card from attacker stack\n", | |
" self.player_stacks[attacker][len(self.player_stacks[attacker])] = self.player_stacks[defender][0]\n", | |
" self.player_stacks[attacker][len(self.player_stacks[attacker])] = self.player_stacks[attacker][0]\n", | |
"\n", | |
" self.player_stacks[attacker] = {k: v for k, v in self.player_stacks[attacker].items() if k != 0}\n", | |
" self.player_stacks[defender] = {k: v for k, v in self.player_stacks[defender].items() if k != 0}\n", | |
"\n", | |
" stats['winner'] = attacker\n", | |
" stats['loser'] = defender\n", | |
" stats['winning_character'] = attacking_character\n", | |
" stats['losing_character'] = defending_character\n", | |
" stats_per_character[attacking_character]['wins_count'] += 1\n", | |
" stats_per_character[defending_character]['losses_count'] += 1\n", | |
"\n", | |
" elif attack_value <= defense_value:\n", | |
"\n", | |
" if self.debug : print(f'\\t{defender} wins')\n", | |
"\n", | |
" # move first card from attacker stack to defender stack\n", | |
" # same for first card from defender stack\n", | |
" self.player_stacks[defender][len(self.player_stacks[defender])] = self.player_stacks[attacker][0]\n", | |
" self.player_stacks[defender][len(self.player_stacks[defender])] = self.player_stacks[defender][0]\n", | |
"\n", | |
" self.player_stacks[attacker] = {k: v for k, v in self.player_stacks[attacker].items() if k != 0}\n", | |
" self.player_stacks[defender] = {k: v for k, v in self.player_stacks[defender].items() if k != 0}\n", | |
"\n", | |
" stats['winner'] = defender\n", | |
" stats['loser'] = attacker\n", | |
" stats['winning_character'] = defending_character\n", | |
" stats['losing_character'] = attacking_character\n", | |
"\n", | |
" stats_per_character[attacking_character]['losses_count'] += 1\n", | |
" stats_per_character[defending_character]['wins_count'] += 1\n", | |
"\n", | |
" else:\n", | |
"\n", | |
" if self.debug : print(f'\\t{attacker} and {defender} draw')\n", | |
" \n", | |
" # move first card from attacker stack to attacker stack\n", | |
" # move first card from attacker stack to attacker stack\n", | |
" self.player_stacks[attacker][len(self.player_stacks[attacker])] = self.player_stacks[attacker][0]\n", | |
" self.player_stacks[defender][len(self.player_stacks[defender])] = self.player_stacks[defender][0]\n", | |
"\n", | |
" self.player_stacks[attacker] = {k: v for k, v in self.player_stacks[attacker].items() if k != 0}\n", | |
" self.player_stacks[defender] = {k: v for k, v in self.player_stacks[defender].items() if k != 0}\n", | |
" \n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = None\n", | |
" stats['losing_character'] = None\n", | |
"\n", | |
" stats_per_character[attacking_character]['draws_count'] += 1\n", | |
" stats_per_character[defending_character]['draws_count'] += 1\n", | |
"\n", | |
" else:\n", | |
"\n", | |
" if self.debug : print(f'\\t{defender} escapes')\n", | |
" \n", | |
" # move first card from attacker stack to attacker stack\n", | |
" # move first card from attacker stack to attacker stack\n", | |
" self.player_stacks[attacker][len(self.player_stacks[attacker])] = self.player_stacks[attacker][0]\n", | |
" self.player_stacks[defender][len(self.player_stacks[defender])] = self.player_stacks[defender][0]\n", | |
"\n", | |
" self.player_stacks[attacker] = {k: v for k, v in self.player_stacks[attacker].items() if k != 0}\n", | |
" self.player_stacks[defender] = {k: v for k, v in self.player_stacks[defender].items() if k != 0}\n", | |
"\n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = None\n", | |
" stats['losing_character'] = None\n", | |
"\n", | |
" stats_per_character[defending_character]['escapes_count'] += 1\n", | |
"\n", | |
"\n", | |
" self.stats.append(stats)\n", | |
"\n", | |
" return stats_per_character\n", | |
" \n", | |
" def simulateAllvsAll(self, games):\n", | |
"\n", | |
" for character_variation in self.characters_variations:\n", | |
"\n", | |
" character_variation_id = character_variation['variation']\n", | |
" characters = character_variation['characters']\n", | |
"\n", | |
" for game in range(1, games + 1, 1):\n", | |
"\n", | |
" stats_per_character = {}\n", | |
"\n", | |
" for character_1 in characters:\n", | |
"\n", | |
" if not str(character_1) + str(character_variation_id) in stats_per_character:\n", | |
" stats_per_character[str(character_1) + str(character_variation_id)] = {\n", | |
" 'flight': 'all_vs_all',\n", | |
" 'character': character_1,\n", | |
" 'characters_variation': character_variation_id,\n", | |
" 'game': game,\n", | |
" 'round': None,\n", | |
" 'wins_count': 0,\n", | |
" 'losses_count': 0,\n", | |
" 'draws_count': 0,\n", | |
" 'escapes_count': 0\n", | |
" }\n", | |
"\n", | |
" # calculate the base attack and defense values\n", | |
" attack_value, base_attack_value = self.calculateAttackValue(characters[character_1])\n", | |
"\n", | |
" for character_2 in characters:\n", | |
"\n", | |
" if not str(character_2) + str(character_variation_id) in stats_per_character:\n", | |
" stats_per_character[str(character_2) + str(character_variation_id)] = {\n", | |
" 'flight': 'all_vs_all',\n", | |
" 'character': character_2,\n", | |
" 'characters_variation': character_variation_id,\n", | |
" 'game': game,\n", | |
" 'round': None,\n", | |
" 'wins_count': 0,\n", | |
" 'losses_count': 0,\n", | |
" 'draws_count': 0,\n", | |
" 'escapes_count': 0\n", | |
" }\n", | |
"\n", | |
" defense_value, base_defense_value = self.calculateDefenseValue(characters[character_2])\n", | |
"\n", | |
" escape_success = self.calculateEscapeValue(characters[character_2])\n", | |
"\n", | |
" stats = {\n", | |
" 'flight': 'all_vs_all',\n", | |
" 'characters_variation': character_variation_id,\n", | |
" 'game': game,\n", | |
" 'round': None,\n", | |
" 'attacking_character': character_1,\n", | |
" 'defending_character': character_2,\n", | |
" 'base_attack_value': base_attack_value,\n", | |
" 'base_defense_value': base_defense_value,\n", | |
" 'attack_value': attack_value,\n", | |
" 'defense_value': defense_value,\n", | |
" 'escape_success': escape_success\n", | |
"\n", | |
" }\n", | |
"\n", | |
" if escape_success == False:\n", | |
"\n", | |
" if attack_value > defense_value:\n", | |
"\n", | |
" stats_per_character[str(character_1) + str(character_variation_id)]['wins_count'] += 1\n", | |
" stats_per_character[str(character_2) + str(character_variation_id)]['losses_count'] += 1\n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = character_1\n", | |
" stats['losing_character'] = character_2\n", | |
" \n", | |
" elif attack_value < defense_value:\n", | |
" \n", | |
" stats_per_character[str(character_1) + str(character_variation_id)]['losses_count'] += 1\n", | |
" stats_per_character[str(character_2) + str(character_variation_id)]['wins_count'] += 1\n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = character_2\n", | |
" stats['losing_character'] = character_1\n", | |
"\n", | |
" else:\n", | |
" \n", | |
" stats_per_character[str(character_1) + str(character_variation_id)]['draws_count'] += 1\n", | |
" stats_per_character[str(character_2) + str(character_variation_id)]['draws_count'] += 1\n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = None\n", | |
" stats['losing_character'] = None\n", | |
" else:\n", | |
"\n", | |
" stats_per_character[str(character_2) + str(character_variation_id)]['escapes_count'] += 1\n", | |
" stats['winner'] = None\n", | |
" stats['loser'] = None\n", | |
" stats['winning_character'] = None\n", | |
" stats['losing_character'] = None\n", | |
"\n", | |
" self.stats.append(stats)\n", | |
"\n", | |
" for character_id in stats_per_character:\n", | |
" self.stats_per_character.append(stats_per_character[character_id])\n", | |
"\n", | |
" def calculateWinLoseQuoteForCharacters(self, iteration, game):\n", | |
" \n", | |
" temp_game_stats = self.game_stats.copy()\n", | |
"\n", | |
" for character in self.characters.copy():\n", | |
" temp_game_stats.append({\n", | |
" 'iteration': iteration,\n", | |
" 'game': game,\n", | |
" 'character': character,\n", | |
" 'wins': self.characters[character]['stats']['wins'],\n", | |
" 'losses': self.characters[character]['stats']['losses'],\n", | |
" 'draws': self.characters[character]['stats']['draws'],\n", | |
" 'attacked': self.characters[character]['stats']['attacked'],\n", | |
" 'defended': self.characters[character]['stats']['defended'],\n", | |
" 'escaped': self.characters[character]['stats']['escaped']\n", | |
" })\n", | |
"\n", | |
" self.game_stats = temp_game_stats.copy()\n", | |
" \n", | |
" def exportGameStatsToCsv(self):\n", | |
" with open('stats.csv', 'w') as file:\n", | |
" writer = csv.DictWriter(file, fieldnames=self.stats[0].keys())\n", | |
"\n", | |
" writer.writeheader()\n", | |
" writer.writerows(self.stats)\n", | |
"\n", | |
" with open('stats_summary.csv', 'w') as file:\n", | |
" writer = csv.DictWriter(file, fieldnames=self.stats_summary[0].keys())\n", | |
"\n", | |
" writer.writeheader()\n", | |
" writer.writerows(self.stats_summary)\n", | |
"\n", | |
" with open('stats_per_character.csv', 'w') as file:\n", | |
" writer = csv.DictWriter(file, fieldnames=self.stats_per_character[0].keys())\n", | |
"\n", | |
" writer.writeheader()\n", | |
" writer.writerows(self.stats_per_character)\n", | |
"\n", | |
" def randomizeCharacterAttributes(self, variations=1):\n", | |
" '''Loop through all characters and randomize given attributes'''\n", | |
" if self.debug : print(f'Creating {variations} variations for {len(self.characters)} characters')\n", | |
"\n", | |
" self.characters_variations = []\n", | |
"\n", | |
" # append base defintion\n", | |
" self.characters_variations.append({'variation': 0, 'characters': self.characters.copy()})\n", | |
"\n", | |
" # increment by 1 - 0 is base definition\n", | |
" for variation in range(1, variations + 1, 1):\n", | |
" for character in self.characters:\n", | |
" for attribute in self.characters[character]['attributes']:\n", | |
" if attribute in self.variable_attributes:\n", | |
" self.characters[character]['attributes'][attribute] = random.choice(self.variable_attributes[attribute])\n", | |
" \n", | |
" self.characters_variations.append({'variation': variation, 'characters': self.characters.copy()})\n", | |
" \n", | |
" with open(f'characters_variations.json', 'w') as file:\n", | |
" json.dump(self.characters_variations, file)\n", | |
"\n", | |
" def showSummary(self):\n", | |
"\n", | |
" for header in list(self.stats_summary[0].keys()):\n", | |
" print(f'{header}', end='\\t')\n", | |
"\n", | |
" print('\\n--------------------------------------------------------------------\\n', end='')\n", | |
" \n", | |
" for row in self.stats_summary:\n", | |
" for column in list(row.keys()):\n", | |
" print(f'{row[column]}', end='\\t')\n", | |
" print('') \n", | |
"\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"variable_attributes = {\n", | |
" 'attribute_2': range(1, 50, 1), # min, max\n", | |
" 'attribute_4': range(1, 30, 1), # min, max\n", | |
"}\n", | |
"\n", | |
"gameEngine = GameEngine(\n", | |
" debug=False, \n", | |
" bonus_attack_activator=[1, 6],\n", | |
" bonus_defense_activator=[1, 2, 3, 4, 5, 6],\n", | |
" escape_activator=[3], \n", | |
" dice_range=[1, 2, 3, 4, 5, 6],\n", | |
" variable_attributes=variable_attributes)\n", | |
"\n", | |
"gameEngine.randomizeCharacterAttributes(variations=10)\n", | |
"\n", | |
"gameEngine.simulateRealGames(games=100, round_limit=100, players=4, characters_per_stack=5, sibblings_per_character=1)\n", | |
"\n", | |
"gameEngine.simulateAllvsAll(games=100)\n", | |
"\n", | |
"gameEngine.exportGameStatsToCsv()\n", | |
"\n", | |
"gameEngine.showSummary()" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.9.13" | |
}, | |
"orig_nbformat": 4, | |
"vscode": { | |
"interpreter": { | |
"hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" | |
} | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
documentation can be found here:
https://nickyreinert.medium.com/how-to-develope-a-balanced-card-game-98ff346f4ced