Having successfully used the ThunderScraper to create a csv file containing all of the map information, the next step was to divide the maps based on map size so I could get an even mix of differently-sized maps in each of my map pools.
Then, I could look at each of the maps, that were balanced for a specific matchup in a specific size range, and use that to arbitrarily (by my own preferences) construct the map pools.
Once I had the map pools constructed, I also needed a function that I could use to dynamically select the maps. Basically, the process was as follows: Two players knew that they could see play on any of 16 maps. A map would be selected from the pool at random without replacement, and one player could either veto or stay on that map. If they veto, their veto count gets decremented, and the map is rejected. If they stay, the other player either vetoes or stays. If there are two stays, the map is added to the pool. If one player runs out of vetoes, he stays on every subsequent selection. The process repeats until a prespecified number of maps are selected.
Generally speaking, players seemed to enjoy the novel map selection process.
Next, check out the Competitor Bracket Generator .
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import numpy as np
import pandas as pd
import random
# In[2]:
first_guy = pd.read_csv("MapCSV/true_full_list.csv")
# In[47]:
# full_maps_df = first_guy.rename(columns = {"Unnamed: 0": "Map"})
# full_maps_df.loc[full_maps_df['Map'] == 'Abiogenesis_LE']
first_guy.loc[first_guy["Map"] == "Alterzim_Stronghold_TE"]
# So It Begins.
# In[50]:
maps_with_some_games = first_guy.dropna().sort_values("Map").drop(columns = ['Unnamed: 0'])
tvz_maps_low_count = maps_with_some_games.loc[maps_with_some_games['tvz count'].astype(int) <= 30]
zvp_maps_low_count = maps_with_some_games.loc[maps_with_some_games['zvp count'].astype(int) <= 30]
pvt_maps_low_count = maps_with_some_games.loc[maps_with_some_games['pvt count'].astype(int) <= 30]
tvz_maps_balanced = maps_with_some_games.loc[(maps_with_some_games['tvz winrate'] > 46) & (maps_with_some_games['tvz winrate'] < 54)]
zvp_maps_balanced = maps_with_some_games.loc[(maps_with_some_games['zvp winrate'] > 46) & (maps_with_some_games['zvp winrate'] < 54)]
pvt_maps_balanced = maps_with_some_games.loc[(maps_with_some_games['pvt winrate'] > 46) & (maps_with_some_games['pvt winrate'] < 54)]
len(tvz_maps_balanced), len(zvp_maps_balanced), len(pvt_maps_balanced)
# In[ ]:
# PvT
# In[51]:
pvt_maps_tiny = pvt_maps_balanced.loc[pvt_maps_balanced['total size'] <= 18000]
pvt_maps_tiny
# In[52]:
pvt_maps_small = pvt_maps_balanced.loc[(pvt_maps_balanced['total size'] > 18000) & (pvt_maps_balanced['total size'] < 20000)]
pvt_maps_small
#PvTList = ['Antiga_Shipyard', 'Cloud_Kingdom_LE', 'Kairos_Junction_LE', 'Fracture_LE', 'Korhal_Floating_Island','Backwater_LE', 'Cyber_Forest_LE', 'Dreamcatcher_LE', 'Interloper_LE','Ulrena', 'Entombed_Valley', 'Dusk_Towers', 'Zen_LE', 'Waystation', 'Whirlwind_LE']
# In[69]:
pvt_maps_medium = pvt_maps_balanced.loc[(pvt_maps_balanced['total size'] > 20000) & (pvt_maps_balanced['total size'] < 23000)]
pvt_maps_medium
# In[81]:
pvt_maps_large = pvt_maps_balanced.loc[(pvt_maps_balanced['total size'] > 23000) & (pvt_maps_balanced['total size'] < 26000)]
pvt_maps_large
# In[71]:
pvt_maps_huge = pvt_maps_balanced.loc[(pvt_maps_balanced['total size'] > 26000)]
pvt_maps_huge
# ZvP
# In[72]:
zvp_maps_tiny = zvp_maps_balanced.loc[zvp_maps_balanced['total size'] <= 18000]
zvp_maps_tiny
# In[73]:
zvp_maps_small = zvp_maps_balanced.loc[(zvp_maps_balanced['total size'] > 18000) & (zvp_maps_balanced['total size'] < 20000)]
zvp_maps_small
# In[74]:
zvp_maps_medium = zvp_maps_balanced.loc[(zvp_maps_balanced['total size'] > 20000) & (zvp_maps_balanced['total size'] < 23000)]
zvp_maps_medium
# In[75]:
zvp_maps_large = zvp_maps_balanced.loc[(zvp_maps_balanced['total size'] > 23000) & (zvp_maps_balanced['total size'] < 26000)]
zvp_maps_large
# In[76]:
zvp_maps_huge = zvp_maps_balanced.loc[(zvp_maps_balanced['total size'] > 26000)]
zvp_maps_huge
# TvZ
# In[65]:
tvz_maps_tiny = tvz_maps_balanced.loc[tvz_maps_balanced['total size'] <= 18000]
tvz_maps_tiny
# In[67]:
tvz_maps_small = tvz_maps_balanced.loc[(tvz_maps_balanced['total size'] > 18000) & (tvz_maps_balanced['total size'] < 20000)]
tvz_maps_medium
# In[82]:
tvz_maps_medium = tvz_maps_balanced.loc[(tvz_maps_balanced['total size'] > 20000) & (tvz_maps_balanced['total size'] < 23000)]
tvz_maps_medium.sort_values("Map")
# In[83]:
tvz_maps_large = tvz_maps_balanced.loc[(tvz_maps_balanced['total size'] > 23000) & (tvz_maps_balanced['total size'] < 26000)]
tvz_maps_large
# In[80]:
tvz_maps_huge= tvz_maps_balanced.loc[(tvz_maps_balanced['total size'] > 26000)]
tvz_maps_huge
# Wildcard Maps
# In[22]:
wildcard_maps.loc[wildcard_maps['total size'] < 18000].sort_values("Map")
# In[75]:
wildcard_maps.loc[(wildcard_maps['total size'] > 18000) & (wildcard_maps['total size'] < 21000)].sort_values("Map")
# In[76]:
wildcard_maps.loc[(wildcard_maps['total size'] > 21000) & (wildcard_maps['total size'] < 24000)].sort_values("Map")
# In[77]:
wildcard_maps.loc[wildcard_maps['total size'] > 24000].sort_values("Map")
# In[ ]:
full_maps_df
# Map Selector Function
# In[23]:
ZvZList
# In[3]:
PvTList = ['Antiga_Shipyard', 'Nimbus_LE', 'Cloud_Kingdom_LE', 'Kairos_Junction_LE', 'Fracture_LE', 'Dasan_Station_LE', 'Cyber_Forest_LE', 'Dreamcatcher_LE', 'Interloper_LE','Ulrena', 'Dusk_Towers', 'Zen_LE', 'Waystation', 'Heavy_Rain_LE']
TvZList = ['Blistering_Sands', "Dreamcatcher_LE", 'Daybreak_LE', "Ulrena", 'Korhal_Sky_Island', 'Bridgehead_LE', "Entombed_Valley", "Acropolis_LE", 'Cerulean_Fall_LE', 'Catallena_LE', "Coda_LE", 'Polar_Night_LE', 'Acolyte_LE', 'Frost_LE', 'Dash_and_Terminal_LE', 'Merry_Go_Round_LE']
ZvPList = ['Moonlight_Madness_LE', 'Shakuras_Plateau', 'Fracture_LE', "Xel'Naga_Caverns", 'Acid_Plant_LE', 'Coda_LE', 'Echo_LE', 'Redshift_LE', 'Expedition_Lost','Heavy_Rain', 'Interloper_LE', 'Foxtrot_Labs_LE', 'King_Sejong_Station_LE', 'Sequencer_LE', 'Cactus_Valley_LE', 'Invader_LE']
TvTList = ['Abiogenesis_LE', "Arid_Plateau", 'Blood_Boil_LE', 'Dasan_Station_LE', 'Desert_Oasis', "Defender's_Landing_LE", 'Fractured_Glacier', 'Howling_Peak', 'Incineration_Zone', 'Klontas_Mire', 'Korhal_Carnage_Knockout_LE', 'Lost_Temple', 'Nerazim_Crypt', 'Newkirk_Precinct_TE', 'Odyssey_LE', 'Prion_Terraces']
PvPList = ['16-bit_LE', 'Abyssal_Caverns', 'Backwater_Gulch', 'Battle_on_the_Boardwalk_LE', 'Cerulean_Fall_LE', 'Ephemeron_LE', 'Jungle_Basin', 'Iron_Fortress_LE', 'Korhal_City', 'Lerilak_Crest', 'Metalopolis', 'New_Repugnancy_LE', 'Shakuras_Plateau', 'Star_Station_TE', 'Steppes_of_War', 'Yeonsu_LE']
ZvZList = ['Apotheosis_LE', 'Backwater_Gulch', 'Blueshift_LE', 'Cloud_Kingdom_LE', 'Darkness_Sanctuary_LE', 'Delta_Quadrant', 'Habitation_Station_LE', 'Inferno_Pools', 'Kulas_Ravine', 'Metropolis_LE', 'Moonlight_Madness_LE', 'New_Gettysburg_LE', 'Ruins_of_Seras', 'Scrap_Station', 'Secret_Spring', 'Slag_Pits']
len(sorted(ZvPList))
Exhibition1 = ['Blood Boil','New Gettysburg', 'Moonlight Madness', 'Invader']
PvTList2 = ['Antiga_Shipyard', 'Nimbus_LE', 'Cloud_Kingdom_LE', 'Kairos_Junction_LE', 'Fracture_LE', 'Dasan_Station_LE', 'Cyber_Forest_LE', 'Dreamcatcher_LE','Ulrena', 'Zen_LE']
AllMaps = ['Blood Boil', 'Desert Oasis', 'Orbital Shipyard', 'Moonlight Madness', 'Klontas Mire', 'New Gettysburg', 'Merry Go Round']
# Version 1
# In[4]:
def mapselector(listchoice, BoX):
maplist = []
parentlist = listchoice.copy()
for i in range(BoX):
map_option = random.choice(parentlist)
maplist.append(map_option)
parentlist.remove(map_option)
return maplist
mapselector(Exhibition1, 4)
# Version 2
# In[6]:
def mapselector2(listchoice, BoX):
i = 0
vetos_remaining = 3
maplist = []
parentlist = listchoice.copy()
while (i < BoX) & (vetos_remaining > 0):
map_option = random.choice(parentlist)
parentlist.remove(map_option)
print(f"Map Choice: {map_option}")
playerchoice = input()
if playerchoice == "Stay":
maplist.append(map_option)
i += 1
else:
vetos_remaining -= 1
while len(maplist) < BoX:
map_option = random.choice(parentlist)
parentlist.remove(map_option)
maplist.append(map_option)
return maplist
mapselector2(PvTList2, 2)
# In[4]:
import random
listy = [1,2,3]
bro = random.shuffle(listy)
bro
# Version 3
# In[8]:
parentlist = PvPList
parentlist
# random.choice(parentlist)
# In[9]:
class VetoLogger:
def __init__(self, Active, Vetoes):
self.Active = True
self.Vetoes = 3
P1 = VetoLogger(True, 3)
P2 = VetoLogger(False, 3)
def mapselector3(listchoice, BoX):
i = 0
staycount = 0
maplist = []
parentlist = listchoice.copy()
map_option = random.choice(parentlist)
parentlist.remove(map_option)
while i < BoX:
if (P1.Vetoes > 0) & (P1.Active == True):
print(f"P1: The map is {map_option}. You still have {P1.Vetoes} vetoes. Veto or Stay?")
P1choice = input()
if P1choice == "Veto":
P1.Vetoes -= 1
map_option = random.choice(parentlist)
parentlist.remove(map_option)
P2.Active = True
P1.Active = False
staycount = 0
elif P1choice == "Stay":
P2.Active = True
P1.Active = False
staycount += 1
else:
print(f"P1 has no vetoes. Forcing Stay.")
staycount += 1
P1.Active = False
P2.Active = True
if staycount > 1:
print(f"added {map_option} to list")
maplist.append(map_option)
map_option = random.choice(parentlist)
parentlist.remove(map_option)
staycount = 0
i = len(maplist)
if (P2.Vetoes > 0) & (P2.Active == True):
print(f"P2: The map is {map_option}. You still have {P2.Vetoes} vetoes. Veto or Stay?")
P2choice = input()
if P2choice == "Veto":
P2.Vetoes -= 1
map_option = random.choice(parentlist)
parentlist.remove(map_option)
P2.Active = False
P1.Active = True
staycount = 0
elif P2choice == "Stay":
P2.Active = False
P1.Active = True
staycount += 1
else:
print(f"P2 has no vetoes. Forcing Stay.")
staycount += 1
P2.Active = False
P1.Active = True
if staycount > 1:
print(f"added {map_option} to list")
maplist.append(map_option)
map_option = random.choice(parentlist)
parentlist.remove(map_option)
staycount = 0
i = len(maplist)
return maplist
mapselector3(PvTList, 3)