Skip to content

Instantly share code, notes, and snippets.

@FrankRuns
Last active January 16, 2024 10:18
Show Gist options
  • Save FrankRuns/72e38aaba7b4c66668e5959c22cb73aa to your computer and use it in GitHub Desktop.
Save FrankRuns/72e38aaba7b4c66668e5959c22cb73aa to your computer and use it in GitHub Desktop.
Python sim for the card Uno
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A pretty ugly notebook to simulate games of the card game Uno."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"import pandas as pd\n",
"import numpy as np\n",
"import math\n",
"from matplotlib import pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Setup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create the deck"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def create_reds():\n",
" reds = []\n",
" for j in [1,2]:\n",
" for i in range(1,10):\n",
" reds.append('R_' + str(i)) \n",
" reds.append('R_0')\n",
" return reds\n",
"\n",
"def create_blues():\n",
" blues = []\n",
" for j in [1,2]:\n",
" for i in range(1,10):\n",
" blues.append('B_' + str(i)) \n",
" blues.append('B_0')\n",
" return blues\n",
"\n",
"def create_greens():\n",
" greens = []\n",
" for j in [1,2]:\n",
" for i in range(1,10):\n",
" greens.append('G_' + str(i)) \n",
" greens.append('G_0')\n",
" return greens\n",
"\n",
"def create_yellows():\n",
" yellows = []\n",
" for j in [1,2]:\n",
" for i in range(1,10):\n",
" yellows.append('Y_' + str(i)) \n",
" yellows.append('Y_0')\n",
" return yellows\n",
"\n",
"def create_draw_twos():\n",
" return ['R_dt', 'B_dt', 'Y_dt', 'G_dt', 'R_dt', 'B_dt', 'Y_dt', 'G_dt']\n",
"\n",
"def create_skips():\n",
" return ['R_sk', 'B_sk', 'Y_sk', 'G_sk', 'R_sk', 'B_sk', 'Y_sk', 'G_sk']\n",
"\n",
"def create_reverses():\n",
" return ['R_re', 'B_re', 'Y_re', 'G_re', 'R_re', 'B_re', 'Y_re', 'G_re']\n",
"\n",
"def create_wild_regs():\n",
" return ['w_r', 'w_r', 'w_r', 'w_r']\n",
"\n",
"def create_wild_draw_4s():\n",
" return ['w_d4', 'w_d4', 'w_d4', 'w_d4']\n",
"\n",
"def create_deck():\n",
" reds = create_reds() * 2\n",
" blues = create_blues() * 2\n",
" greens = create_greens() * 2\n",
" yellows = create_yellows() * 2\n",
" draw_twos = create_draw_twos() * 2\n",
" skips = create_skips() * 2\n",
" reverses = create_reverses() * 2\n",
" wilds_reg = create_wild_regs() * 2\n",
" wilds_draw = create_wild_draw_4s() * 2\n",
" deck = reds + blues + yellows + greens + draw_twos + skips + reverses + wilds_reg + wilds_draw\n",
" return deck"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"deck = create_deck()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n"
]
}
],
"source": [
"# does it work?\n",
"if len(deck) == 108 * 2:\n",
" print('All good.')\n",
"else: \n",
" print('SOMETHING IS WRONG.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initialize the game giving each player cards (4-players hard coded)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def initialize_hands(deck):\n",
" \n",
" players = {\n",
" 'player_1':[],\n",
" 'player_2':[],\n",
" 'player_3':[],\n",
" 'player_4':[]\n",
" }\n",
" \n",
" import random\n",
"\n",
" for i in range(1, 8):\n",
" for key in players:\n",
" pick = deck.pop(random.randint(0,len(deck)-1))\n",
" players[key].append(pick)\n",
" \n",
" return players"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"players = initialize_hands(deck)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n",
"All good.\n",
"All good.\n",
"All good.\n"
]
}
],
"source": [
"# does it work?\n",
"for key in players:\n",
" if len(players[key]) == 7:\n",
" print('All good.')\n",
" else:\n",
" print('SOMETHING IS WRONG.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create order of play (both forward and backwards)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['player_1', 'player_2', 'player_3', 'player_4']\n"
]
}
],
"source": [
"forward_order = list(players.keys())\n",
"print(forward_order)\n",
"reverse_order = forward_order[::-1]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n"
]
}
],
"source": [
"# does it work?\n",
"if forward_order[0] == reverse_order[3]:\n",
" print('All good.')\n",
"else:\n",
" print('SOMETHING IS WRONG.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Choose the initial card"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def choose_initial_card(deck):\n",
" initial_card = deck.pop(random.randint(0,len(deck)-1))\n",
" if initial_card not in create_draw_twos() + create_skips() + create_reverses() + create_wild_regs() + create_wild_draw_4s():\n",
" return initial_card\n",
" else:\n",
" return choose_initial_card(deck)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"initial_card = choose_initial_card(deck)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n"
]
}
],
"source": [
"# does it work? initial card shouldn't be action card (according to rule book)...\n",
"if initial_card.split('_')[0] in ['R','G','B','Y'] and initial_card.split('_')[1] in ['0','1','2','3','4','5','6','7','8','9']:\n",
" print('All good.')\n",
"else:\n",
" print('SOMETHING IS WRONG.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Define player's action based on card at play and the players hand"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"def player_action(card_at_play, player, action_color, deck):\n",
" '''\n",
" card_at_play (str): current card to be played\n",
" player (str): player at turn\n",
" '''\n",
"\n",
" temp_options = []\n",
" \n",
" # if card is not action card\n",
" if card_at_play in create_reds() + create_blues() + create_greens() + create_yellows():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[1] == card_at_play.split('_')[1] or card.split('_')[0] == 'w':\n",
" temp_options.append(card) \n",
" \n",
" # if card is action card\n",
" \n",
" # if card is wild card (regular and draw 4)\n",
" if card_at_play in create_wild_regs() or card_at_play in create_wild_draw_4s():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == action_color or card.split('_')[0] == 'w':\n",
" temp_options.append(card) \n",
" \n",
" # if card is reverse\n",
" if card_at_play in create_reverses():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 're':\n",
" temp_options.append(card) \n",
" \n",
" # if card is skip\n",
" if card_at_play in create_skips():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 'sk':\n",
" temp_options.append(card) \n",
" \n",
" # if card is draw 2\n",
" if card_at_play in create_draw_twos():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 'dt':\n",
" temp_options.append(card) \n",
" \n",
" # determine move, either draw or play\n",
" if len(temp_options) == 0:\n",
" # print('no cards can be played, draw card from deck.')\n",
" new_card = deck.pop(random.randint(0,len(deck)-1))\n",
" players[player].append(new_card)\n",
" pick = card_at_play\n",
" card_reset = 0\n",
" else:\n",
" # print('cards can be played, choose randomly.')\n",
" pick = random.choice(temp_options)\n",
" players[player].remove(pick)\n",
" card_reset = 1\n",
" \n",
" return {'pick':pick, 'card_reset':card_reset}\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Potential strategy action: what if player always plays action card if available?"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def player_strategy(card_at_play, player, action_color, deck):\n",
" '''\n",
" card_at_play (str): current card to be played\n",
" player (str): player at turn\n",
" '''\n",
"\n",
" temp_options = []\n",
" \n",
" # if card is not action card\n",
" if card_at_play in create_reds() + create_blues() + create_greens() + create_yellows():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[1] == card_at_play.split('_')[1] or card.split('_')[0] == 'w':\n",
" temp_options.append(card) \n",
" \n",
" # if card is action card\n",
" \n",
" # if card is wild card (regular and draw 4)\n",
" if card_at_play in create_wild_regs() or card_at_play in create_wild_draw_4s():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == action_color or card.split('_')[0] == 'w':\n",
" temp_options.append(card) \n",
" \n",
" # if card is reverse\n",
" if card_at_play in create_reverses():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 're':\n",
" temp_options.append(card) \n",
" \n",
" # if card is skip\n",
" if card_at_play in create_skips():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 'sk':\n",
" temp_options.append(card) \n",
" \n",
" # if card is draw 2\n",
" if card_at_play in create_draw_twos():\n",
" for card in players[player]:\n",
" if card.split('_')[0] == card_at_play.split('_')[0] or card.split('_')[0] == 'w' or card.split('_')[1] == 'dt':\n",
" temp_options.append(card) \n",
" \n",
" # determine move, either draw or play\n",
" if len(temp_options) == 0:\n",
" # print('no cards can be played, draw card from deck.')\n",
" new_card = deck.pop(random.randint(0,len(deck)-1))\n",
" players[player].append(new_card)\n",
" pick = card_at_play\n",
" card_reset = 0\n",
" else:\n",
" # print('cards can be played, choose randomly.')\n",
" action_cards = create_wild_regs() + create_wild_draw_4s() + create_reverses() + create_skips() + create_draw_twos()\n",
" action_options = [x for x in temp_options if x in action_cards]\n",
" if len(action_options) > 0:\n",
" pick = random.choice(action_options)\n",
" else:\n",
" pick = random.choice(temp_options)\n",
" players[player].remove(pick)\n",
" card_reset = 1\n",
" \n",
" return {'pick':pick, 'card_reset':card_reset}"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'player_1': ['w_d4', 'B_6', 'w_r', 'G_8', 'G_3', 'R_re', 'w_d4'],\n",
" 'player_2': ['G_re', 'R_sk', 'B_6', 'R_6', 'G_sk', 'B_2', 'w_r'],\n",
" 'player_3': ['G_8', 'B_6', 'B_sk', 'G_3', 'G_6', 'B_re', 'R_1'],\n",
" 'player_4': ['G_3', 'B_3', 'Y_5', 'w_d4', 'R_3', 'Y_re', 'Y_7']}"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# check players hands\n",
"players"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Based on card played, identify next player"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# I need a function that determines who is playing\n",
"def identify_player(current_order, current_player, current_card, card_reset):\n",
"\n",
" if current_order == 'f':\n",
" if current_card.split('_')[1] == 'sk' and card_reset == 1:\n",
" if current_player == 'player_1':\n",
" next_player = 'player_3'\n",
" elif current_player == 'player_2':\n",
" next_player = 'player_4'\n",
" elif current_player == 'player_3':\n",
" next_player = 'player_1'\n",
" else:\n",
" next_player = 'player_2'\n",
" else:\n",
" next_player = forward_order.index(current_player) + 1\n",
" if next_player > len(forward_order) - 1:\n",
" next_player = forward_order[0]\n",
" else:\n",
" next_player = forward_order[next_player] \n",
"\n",
" else: \n",
" if current_card.split('_')[1] == 'sk' and card_reset == 1:\n",
" if current_player == 'player_1':\n",
" next_player = 'player_3'\n",
" elif current_player == 'player_2':\n",
" next_player = 'player_4'\n",
" elif current_player == 'player_3':\n",
" next_player = 'player_1'\n",
" else:\n",
" next_player = 'player_2'\n",
" else:\n",
" next_player = reverse_order.index(current_player) + 1\n",
" if next_player > len(reverse_order) - 1:\n",
" next_player = reverse_order[0]\n",
" else:\n",
" next_player = reverse_order[next_player]\n",
" \n",
" # print(f'The next player is {next_player}.')\n",
" return next_player\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n"
]
}
],
"source": [
"# does it work?\n",
"if identify_player('f', 'player_4', 'G_dt', 0) == 'player_1':\n",
" print('All good.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Based on card playerd, identify if order of play has switched"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"def identify_order(current_card, card_reset, current_order):\n",
" if card_reset == 0:\n",
" current_order = current_order\n",
" else:\n",
" if current_card.split('_')[1] == 're':\n",
" if current_order == 'f':\n",
" current_order = 'r'\n",
" # print('The order has been reveresed from f to r')\n",
" else:\n",
" current_order = 'f'\n",
" # print('The order has been reveresed from r to f')\n",
" \n",
" return current_order"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### When 'draw' card is played, next player must draw cards"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"def execute_card_draw(how_many, current_order, current_player, deck):\n",
"\n",
" '''\n",
" function to figure out which player draws and how many cards to draw\n",
" '''\n",
" \n",
" if current_order == 'f':\n",
" drawing_player = forward_order.index(current_player) + 1\n",
" if drawing_player > len(forward_order) - 1:\n",
" drawing_player = forward_order[0]\n",
" for i in range(1,how_many+1):\n",
" players[drawing_player].append(deck.pop(random.randint(0,len(deck)-1)))\n",
" else:\n",
" drawing_player = forward_order[drawing_player]\n",
" for i in range(1,how_many+1):\n",
" players[drawing_player].append(deck.pop(random.randint(0,len(deck)-1)))\n",
" else:\n",
" drawing_player = reverse_order.index(current_player) + 1\n",
" if drawing_player > len(reverse_order) - 1:\n",
" drawing_player = reverse_order[0]\n",
" for i in range(1,how_many+1):\n",
" players[drawing_player].append(deck.pop(random.randint(0,len(deck)-1)))\n",
" else:\n",
" drawing_player = reverse_order[drawing_player]\n",
" for i in range(1,how_many+1):\n",
" players[drawing_player].append(deck.pop(random.randint(0,len(deck)-1)))\n",
" \n",
" return [drawing_player, how_many]\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"All good.\n"
]
}
],
"source": [
"# does it work?\n",
"if execute_card_draw(4, 'r', 'player_4', deck)[0] == 'player_3':\n",
" print('All good.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Run Simulations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Single game (for testing)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"# # start by doing 100 runs\n",
"\n",
"# print('------------------------------------ INITIALIZE GAME')\n",
"\n",
"# # initialize deck\n",
"# deck = create_deck()\n",
"\n",
"# # check for a full deck\n",
"# # print(deck)\n",
"\n",
"# # initialize player's hands\n",
"# players = initialize_hands(deck)\n",
"\n",
"# # pick first card\n",
"# current_card = choose_initial_card(deck)\n",
"# print('Initial card = ', current_card)\n",
"\n",
"# # define first player\n",
"# current_player = 'player_1'\n",
"# current_order = 'f' # for forward\n",
"# print('Initial player = ', current_player)\n",
"# print('Initial order = ', current_order)\n",
"\n",
"# # initialize wild color\n",
"# action_color = None\n",
"\n",
"# # execute first player action\n",
"\n",
"# print('------------------------------------ EXECUTE 1st PLAY!')\n",
"\n",
"# current_card = player_action(current_card, current_player, action_color, deck)\n",
"# print(f'The first card that is played is {current_card}.')\n",
"# current_order = identify_order(current_card['pick'], current_card['card_reset'], current_order)\n",
"# current_player = identify_player(current_order, current_player, current_card['pick'], current_card['card_reset'])\n",
"\n",
"# print('------------------------------------ GAME ON!')\n",
"\n",
"# # game on! \n",
"# for i in range(1,200):\n",
" \n",
"# # current player determines an action\n",
"# current_card = player_action(current_card['pick'], current_player, action_color, deck)\n",
"# print(f'The card that is played is {current_card}.')\n",
" \n",
"# # determine is there is a winner, else play on\n",
"# if len(players[current_player]) == 0:\n",
"# print(f'Game over. Player, {current_player} wins!')\n",
"# break\n",
" \n",
"# print('Game continues.')\n",
" \n",
"# # what if the current card is regular wild?\n",
"# if current_card['pick'].split('_')[0] == 'w':\n",
"# action_color = random.choice(['B','Y','R','G'])\n",
"# else:\n",
"# action_color = None\n",
" \n",
"# # what if the current card is draw 4 wild?\n",
"# if current_card['pick'].split('_')[1] == 'd4':\n",
"# execute_card_draw(4, current_order, current_player, deck)\n",
"\n",
"# # what if the current card is draw 2? \n",
"# if current_card['pick'].split('_')[1] == 'dt':\n",
"# execute_card_draw(4, current_order, current_player, deck)\n",
" \n",
"# # based on card played (or not played), determine who is next (includes when current card is reverse)\n",
"# current_order = identify_order(current_card['pick'], current_card['card_reset'], current_order)\n",
" \n",
"# # based on play order, determine the next player \n",
"# current_player = identify_player(current_order, current_player, current_card['pick'], current_card['card_reset'])\n",
" \n",
"# if len(deck) < 1:\n",
"# print('Game is a draw - out of cards.')\n",
"# break\n",
" \n",
"# print(f'The current order after round {i} is ', current_order)\n",
"# print(f'The player hands after round {i} is ',players)\n",
"# print('---------------')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Many Games"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Done\n"
]
}
],
"source": [
"turns_1 = [] # will count how many turns or how many draw 2's this player gets\n",
"turns_2 = []\n",
"turns_3 = []\n",
"turns_4 = []\n",
"winners = [] # will store the winner of the game\n",
"round_counts = [] # will count the number of turns in a game\n",
"\n",
"for j in range(1, 50000):\n",
"\n",
" t1 = 0\n",
" t2 = 0\n",
" t3 = 0\n",
" t4 = 0\n",
" winner = None\n",
"\n",
" # initialize deck\n",
" sim_deck = create_deck()\n",
"\n",
" # initialize player's hands\n",
" players = initialize_hands(sim_deck)\n",
"\n",
" # pick first card\n",
" current_card = choose_initial_card(sim_deck)\n",
" \n",
" # define first player\n",
" current_player = 'player_1'\n",
" current_order = 'f' # for forward\n",
"\n",
" # initialize wild color\n",
" action_color = None\n",
"\n",
" # execute first player action\n",
"\n",
" current_card = player_action(current_card, current_player, action_color, sim_deck)\n",
" \n",
" if current_card['pick'].split('_')[0] == 'w':\n",
" action_color = random.choice(['B','Y','R','G'])\n",
" else:\n",
" action_color = None\n",
" # what if the current card is draw 4 wild?\n",
" if current_card['pick'].split('_')[1] == 'd4':\n",
" execute_card_draw(4, current_order, current_player, sim_deck)\n",
" # what if the current card is draw 2? \n",
" if current_card['pick'].split('_')[1] == 'dt':\n",
" execute_card_draw(2, current_order, current_player, sim_deck) \n",
"\n",
" current_order = identify_order(current_card['pick'], current_card['card_reset'], current_order)\n",
" current_player = identify_player(current_order, current_player, current_card['pick'], current_card['card_reset'])\n",
"\n",
" # game on! \n",
" count = 0\n",
" for i in range(1,188):\n",
"\n",
" # current player determines an action\n",
" current_card = player_action(current_card['pick'], current_player, action_color, sim_deck)\n",
"# if current_player == 'player_4':\n",
"# current_card = player_strategy(current_card['pick'], current_player, action_color, sim_deck)\n",
"# else:\n",
"# current_card = player_action(current_card['pick'], current_player, action_color, sim_deck)\n",
"\n",
" if current_player == 'player_1' and current_card['pick'].split('_')[1] in ['dt', 'd4']:\n",
" t1 += 1\n",
" if current_player == 'player_2' and current_card['pick'].split('_')[1] in ['dt', 'd4']:\n",
" t2 += 1\n",
" if current_player == 'player_3' and current_card['pick'].split('_')[1] in ['dt', 'd4']:\n",
" t3 += 1\n",
" if current_player == 'player_4' and current_card['pick'].split('_')[1] in ['dt', 'd4']:\n",
" t4 += 1\n",
" \n",
" # determine is there is a winner, else play on\n",
" if len(players[current_player]) == 0:\n",
" winner = current_player\n",
" winners.append(winner)\n",
" break\n",
"\n",
" if len(sim_deck) < 1:\n",
" print('Game is a draw - out of cards.')\n",
" winner = 'draw'\n",
" break\n",
" \n",
" # what if the current card is regular wild?\n",
" if current_card['pick'].split('_')[0] == 'w':\n",
" action_color = random.choice(['B','Y','R','G'])\n",
" else:\n",
" action_color = None\n",
"\n",
" # what if the current card is draw 4 wild?\n",
" if current_card['pick'].split('_')[1] == 'd4':\n",
" execute_card_draw(4, current_order, current_player, sim_deck)\n",
"\n",
" # what if the current card is draw 2? \n",
" if current_card['pick'].split('_')[1] == 'dt':\n",
" execute_card_draw(2, current_order, current_player, sim_deck)\n",
"\n",
" # based on card played (or not played), determine who is next (includes when current card is reverse)\n",
" current_order = identify_order(current_card['pick'], current_card['card_reset'], current_order)\n",
"\n",
" # based on play order, determine the next player \n",
" current_player = identify_player(current_order, current_player, current_card['pick'], current_card['card_reset'])\n",
" \n",
" count += 1\n",
" \n",
" round_counts.append(count)\n",
" turns_1.append(t1)\n",
" turns_2.append(t2)\n",
" turns_3.append(t3)\n",
" turns_4.append(t4) \n",
" \n",
"print('Done')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Analyzing and visualizing many games results"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"49519\n",
"Counter({'player_1': 13364, 'player_2': 12271, 'player_3': 11987, 'player_4': 11897})\n",
"[('player_2', 24.78038732607686), ('player_4', 24.02512167046992), ('player_1', 26.98762091318484), ('player_3', 24.20687009026838)]\n"
]
}
],
"source": [
"# how many wins does each player have?\n",
"from collections import Counter\n",
"print(len(winners))\n",
"types_counts=Counter(winners)\n",
"print(types_counts)\n",
"print([(i, types_counts[i] / len(winners) * 100.0) for i in types_counts])"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<AxesSubplot:title={'center':'Win Dist Over 50k Games'}, xlabel='Player'>"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYQAAAE3CAYAAACq4zYIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAiaklEQVR4nO3de7hVdb3v8fdHMEC5KBdvLBQyzAARBRFhZx2tpDLRtroxS9zZIU13l6OW7vY5ui+UtXvS7WljkRrYNoFMj+TeVj54JfCyVAwRTXYSLEVu3tAUBb7nj/FbOpzMdZtrrDWZi8/reeazxvyO8RvjN3/i/MxxmWMqIjAzM9ut2h0wM7OdgwPBzMwAB4KZmSUOBDMzAxwIZmaWOBDMzAxwIFjBJH1Y0tMduP4DJb0mqVtHbaNWSLpH0peq3Q/rOhwI1ixJl0r6r5LaM03UpkbE/RHxwQq3dbakbekN/zVJz0r6maRDGpeJiNUR0TsitrViXYtasc0TJT0k6XVJmyTdKKmukv5XQtIqSW/kXvPvSuZ/TtKfU//+n6T+7djWVEkPpnWtT9NfkaT2vxLrChwI1pL7gEmNn8gl7QfsDhxZUvtAWra9lkREb6Af8DHgDeARSaMKWPd7SDoV+AXwb8BAYCSwBVgkae+Ct9W9mdmfSSHXOyI+kWszEvgJ8AVgX+AvwMwKt38h2ev8V2C/tL5zgUnA+ypZp3VBEeGHH00+yN4s/gKMTc9PB34G3FtSW5mmPwo05NqvAi4C/gC8AswDejaxrbOBRWXqtwM3p+mhQADdc23+BGwGngXOBD4EvAlsA14DXi6zTgF/Br5ZUt8NeAL4J6AH8DIwKjd/EFlI7ZOenwgsTcstBkaXvPZvpde+pbHPJdtbBXysifH4DvCL3PODgbeAPun5PcCX0vT+aTsXlVlPP+B14K9b+G/9aeAx4FVgDXB5bl7juP9tmvcSWaAclbb7MvCjkvV9EViRlv0tcFBu7K8E1qd/E3/Ij7Ef1Xt4D8GaFRFvAQ8Cx6bSscD9wKKSWnN7B6cDk4FhwGiyN/G2uAX4cGlR0p7A1cAnI6IPMBFYGhEryN6slkT2qXuvMuv8IHAg8Mt8MSK2A78CPh4RW9K2zyh5LfdGxHpJRwLXA18GBpB9ml8gqUdu+TPI3mj3ioitTby+GyVtkPQ7SYfn6iOBx3N9+2+yQDgk31jSULKA/lFE/KDM+o8hC7fbmth+o9eBs4C9Up/Pk3RyyTJHA8OBvwGuAr5Ntic3Ejhd0kdSn04G/h74LFmI3g/clNbxCbJ/M4ekbf0NsKmFvlkncCBYa9zLu2/+Hyb7n/v+ktq9zbS/OiKej4gXgV8DY9q4/eeBpo6dbwdGSeoVEWsjYnkr1zkw/V1bZt7a3Pxf8N5A+FyqAfxP4CcR8WBEbIuIOWR7AhNyy18dEWsi4o0m+nEm2afvg4C7gd9K2ivN6032CTrvFaBP7vkIsj2FyyJiVhPbGAhszAeSpMWSXk7nL44FiIh7ImJZRGyPiD+QvYF/pGRd/xwRb0bE78gC5KaIWB8Rz5H9mzgiLfdl4LsRsSJt9zvAGEkHAW+n13AooLRMuf8O1skcCNYa9wF/lY6rD4qIZ8gOj0xMtVE0v4fwQm76L2RvdG0xGHixtBgRr5N9ujwXWCvpPyUd2sp1bkx/9y8zb//c/LuAXpKOTm9mY4Bb07yDgAvTG+vLkl4GhgAH5Na1prlORMTvI+KNiPhLRHyX7NBL497Qa0DfkiZ9yQ6PNToTeA64uZnNbAIG5s9jRMTEtOe0ifQ+kF7j3Wlv5RWycR1Ysq51uek3yjxv/G97EPBvuXF5kexQ0eCIuAv4EfDvwDpJsySVvk6rAgeCtcYSsuPQ04HfA0TEq2Sf3KcDz0fEsx24/VPIPn3uICJ+GxEfJ3sTfwr4aeOsFtb5NNAAnJYvStoN+GtgYVr/dmA+2V7C54DbI6LxDXkNMCMi9so99oiIm3KrbOvthIPsjRNgOfDOISRJ7yc79PPH3PKXk4XXL5q5FHcJ2Z7LlBa2/QtgATAkIvoBP871pa3WAF8uGZteEbEYICKujoixZIeaDgEurnA7ViAHgrUoHe6oB/4X731jXpRqRVxd9B6SukkaJun/kp2o/scyy+wr6aR0LmEL2SfqxstR1wF1kspeQRMRQXay+x/SpZ290tVS15J9Cr8yt/gvyPZEzuTdw0WQhc+56ZO1JO0p6dOS8od0mnuNB0qaJOl9knpKupjsE/nv0yI3Ap9J3+3Yk+xE9y25QILs8MtpwJ7Az1Oglb7Wl8nGb6akUyX1lrSbpDGpXaM+wIsR8aak8WQBWKkfA5emK6WQ1E/SaWn6qDRmu5Mddmq8AMCqzIFgrXUvsA9ZCDS6P9WKDIRjJL1GdqXLPWRvzkdFxLIyy+4GXEi2p/Ii2fHur6R5d5F9wn5B0sYybYmIeWSXdH6D7FP2k0AvYFJEbMot9yDZG9cBwB25ej3ZeYQfkV1Js5K2nTDvA1yT2j5HduL9k43bTudDziULhvVp+a+UriSd+P8s2X+L65sIhe+Thfc307rWkZ0E/xbZ4T/Suv9J0mbg/5DtGVUkIm4FvgfMlfQq2ZVbn0yz+5KF6UtkV3ptAsqdDLdOpuyDkpmZ7eq8h2BmZoADwczMkhYDQdL16b4nT5SZd5GkkDQwV7tU0kpJT0s6IVcfK2lZmnd14/1TJPWQNC/VH0xfsjEzs07Wmj2E2WQnu95D0hDg48DqXG0EMJXsUrLJZFc1NF4Kdw3ZJYrD06NxnecAL0XEB8iu7PheJS/EzMzap8VAiIj7KPOlILI372/y3uuspwBzI2JLui59JTBe0v5A34hYki73uwE4OddmTpq+GTjed180M+t8zd2BsUmSTgKei4jHS967BwMP5J43pNrbabq03thmDUBEbE3fkBzAu98UzW93OtleBnvuuefYQw9t7ZdSzcwM4JFHHtkYEYPKzWtzIEjag+yGVp8oN7tMLZqpN9dmx2J2r5ZZAOPGjYv6+voW+2tmZu+S9Oem5lVyldHBZHetfFzSKqAOeDR9y7OB7F4ujerIvjTUkKZL6+TbpHut9KP8ISozM+tAbQ6EdDfEfSJiaEQMJXtDPzIiXiC7D8rUdOXQMLKTxw+lOxluljQhnR84i3dvxbsAmJamTwXuCn9bzsys07XmstObyG6O9UFJDZLOaWrZ9FX7+WS3APgNcH68+1OH55HdJ2Yl8N+8ewuA64ABklaSfbX+kgpfi5mZtUPN3rrC5xDMat/bb79NQ0MDb775ZrW70uX07NmTuro6dt999/fUJT0SEePKtanoKiMzsyI0NDTQp08fhg4diq82L05EsGnTJhoaGhg2bFir2/nWFWZWNW+++SYDBgxwGBRMEgMGDGjznpcDwcyqymHQMSoZVweCme2yvvGNb3DVVVe98/yEE07gS1/60jvPL7zwQn74wx+yYMECrrjiijat+4UXXmDq1KkcfPDBjBgxgk996lP88Y9/bLlhG9xzzz0sXry45QVbyecQcoZe8p/V7kKrrLri09XuglmHKPr/wZb+X5k4cSK//OUv+frXv8727dvZuHEjr7766jvzFy9ezFVXXcXRRx/NSSed1OrtRgSnnHIK06ZNY+7cuQAsXbqUdevWccghh1T2Ysq455576N27NxMnTixkfd5DMLNd1qRJk975hL18+XJGjRpFnz59eOmll9iyZQsrVqzgiCOOYPbs2VxwwQUAnH322Xz1q19l4sSJvP/97+fmm2/eYb133303u+++O+eee+47tTFjxvDhD3+YiODiiy9m1KhRHHbYYcybNw/I3txPPPHEd5a/4IILmD17NgBDhw7lsssu48gjj+Swww7jqaeeYtWqVfz4xz/myiuvZMyYMdx/f9mfHW8T7yGY2S7rgAMOoHv37qxevZrFixdzzDHH8Nxzz7FkyRL69evH6NGjed/7dvxZ7rVr17Jo0SKeeuopTjrpJE499dT3zH/iiScYO3Zs2W3ecsstLF26lMcff5yNGzdy1FFHceyxx7bY14EDB/Loo48yc+ZMfvCDH3Dttddy7rnn0rt3by666KLKBqCE9xDMbJfWuJfQGAjHHHPMO8+bOhRz8skns9tuuzFixAjWrVvXpu0tWrSIM844g27durHvvvvykY98hIcffrjFdp/97GcBGDt2LKtWrWrTNlvLgWBmu7SJEyeyePFili1bxqhRo5gwYQJLlixh8eLFTJo0qWybHj16vDNd7su9I0eO5JFHHinbtqkvA3fv3p3t27e/87z0ktHGbXbr1o2tW7c2/6Iq5EAws13apEmTuP322+nfvz/dunWjf//+vPzyyyxZsoRjjjmmonUed9xxbNmyhZ/+9Kfv1B5++GHuvfdejj32WObNm8e2bdvYsGED9913H+PHj+eggw7iySefZMuWLbzyyissXLiwxe306dOHzZs3V9THchwIZrZLO+yww9i4cSMTJkx4T61fv34MHDiwmZZNk8Stt97KnXfeycEHH8zIkSO5/PLLOeCAAzjllFMYPXo0hx9+OMcddxzf//732W+//RgyZAinn346o0eP5swzz+SII45ocTuf+cxnuPXWWws7qex7GeX4slOzzrVixQo+9KEPVbsbXVa58W3uXkbeQzAzM8CBYGZmiQPBzMwAB4KZVVmtnsfc2VUyrg4EM6uanj17smnTJodCwRp/D6Fnz55taudbV5hZ1dTV1dHQ0MCGDRuq3ZUup/EX09rCgWBmVbP77ru36Re9rGP5kJGZmQEOBDMzS3zIyDqMv/lt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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# visualize player wins\n",
"data = pd.DataFrame.from_dict(types_counts, orient='index').reset_index()\n",
"data = data.sort_values(by='index')\n",
"data.columns = ['Player', 'Win Count']\n",
"data.plot.bar(x='Player', y='Win Count', title='Win Dist Over 50k Games')"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1.4273885477709554\n",
"1.5499509990199805\n",
"1.5303306066121323\n",
"1.5055901118022361\n",
"-----\n",
"Avg. of not player_1:\n",
"1.5286239058114497\n"
]
}
],
"source": [
"# this is the average of how many times per game a player was hit with a draw 2 or draw 4 card...\n",
"import numpy as np\n",
"print(np.mean(turns_1))\n",
"print(np.mean(turns_2))\n",
"print(np.mean(turns_3))\n",
"print(np.mean(turns_4))\n",
"print('-----')\n",
"print('Avg. of not player_1:')\n",
"print((np.mean(turns_2) + np.mean(turns_3) + np.mean(turns_4)) / 3)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Player</th>\n",
" <th>Win Count</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>player_1</td>\n",
" <td>13364</td>\n",
" </tr>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>player_2</td>\n",
" <td>12271</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>player_3</td>\n",
" <td>11987</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>player_4</td>\n",
" <td>11897</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Player Win Count\n",
"2 player_1 13364\n",
"0 player_2 12271\n",
"3 player_3 11987\n",
"1 player_4 11897"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"data"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"player_1 does this % better over time than other players:\n"
]
},
{
"data": {
"text/plain": [
"0.10889226939565765"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"print('player_1 does this % better over time than other players:')\n",
"(13364 - np.mean([12271, 11987, 11897])) / np.mean([12271, 11987, 11897])"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"63.723434468689376\n",
"16\n",
"187\n"
]
}
],
"source": [
"# what is the avg, min, max number of turns in a game?\n",
"print(np.mean(round_counts))\n",
"print(np.min(round_counts))\n",
"print(np.max(round_counts))"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5, 1.0, 'Dist of Game Duration over 50k Games')"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# create histogram for number of turns in a game\n",
"bins = np.linspace(math.ceil(min(round_counts)), \n",
" math.floor(max(round_counts)),\n",
" 20) # fixed number of bins\n",
"\n",
"plt.hist(round_counts, bins=bins, alpha=0.5)\n",
"plt.xlabel(\"Number of Turns in Game\")\n",
"plt.ylabel(\"Count of Games\")\n",
"plt.title(\"Dist of Game Duration over 50k Games\")"
]
}
],
"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.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment