def getUsage(filename,col,weight,usage): tempUsage, nBattles = readTable(filename) for i in tempUsage: if keyify(i) not in usage: usage[keyify(i)]=[0,0,0,0,0] if i != 'empty': usage[keyify(i)][col] = usage[keyify(i)][col]+weight*6.0*tempUsage[i]/sum(tempUsage.values())/24
def raiseAndDrop(curTiers, usage, lowest, rise, drop): for poke in usage: if poke not in curTiers: species = keyLookup[poke] if species.endswith('Mega') or species.endswith( 'Mega-X') or species.endswith('Mega-Y'): base = keyify(species[:species.index('-')] ) #none of the megas have hyphenated names if base in curTiers: curTiers[poke] = curTiers[base] else: curTiers[poke] = lowest newTiers = {} #start with Ubers for poke in curTiers.keys(): if curTiers[poke] == 'Uber': newTiers[poke] = 'Uber' #next do the OU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][0] > rise and poke not in newTiers.keys(): newTiers[poke] = 'OU' #next do the UU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'OU' and poke not in newTiers.keys(): if usage[poke][0] < drop: newTiers[poke] = 'UU' else: newTiers[poke] = 'OU' #next do the UU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][1] > rise and poke not in newTiers.keys(): newTiers[poke] = 'UU' #next do the NU drops for poke in curTiers.keys(): if curTiers[poke] == 'UU' and poke not in newTiers.keys(): if usage[poke][1] < drop: newTiers[poke] = 'NU' else: newTiers[poke] = 'UU' #the rest are NU for poke in curTiers.keys(): if poke not in newTiers.keys(): newTiers[poke] = 'NU' return newTiers
def raiseAndDrop(curTiers,usage,lowest,rise,drop): for poke in usage: if poke not in curTiers: species = keyLookup[poke] if species.endswith('Mega') or species.endswith('Mega-X') or species.endswith('Mega-Y'): base = keyify(species[:species.index('-')]) #none of the megas have hyphenated names if base in curTiers: curTiers[poke]=curTiers[base] else: curTiers[poke]=lowest newTiers={} #start with Ubers for poke in curTiers.keys(): if curTiers[poke] == 'Uber': newTiers[poke] = 'Uber' #next do the OU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][0] > rise and poke not in newTiers.keys(): newTiers[poke] = 'OU' #next do the UU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'OU' and poke not in newTiers.keys(): if usage[poke][0] < drop: newTiers[poke] = 'UU' else: newTiers[poke] = 'OU' #next do the UU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][1] > rise and poke not in newTiers.keys(): newTiers[poke] = 'UU' #next do the NU drops for poke in curTiers.keys(): if curTiers[poke] == 'UU' and poke not in newTiers.keys(): if usage[poke][1] < drop: newTiers[poke] = 'NU' else: newTiers[poke] = 'UU' #the rest are NU for poke in curTiers.keys(): if poke not in newTiers.keys(): newTiers[poke] = 'NU' return newTiers
def analyzePoke(poke): species=keyify(poke['species']) if species not in baseStats.keys(): sys.stderr.write(species+" is not listed in baseStats.json\n") sys.stderr.write("You may want to fix that.\n") return None #technically I don't need to do this as a separate loop, but I'm doing it this way for modularity's sake stats = [] if species == 'shedinja': stats.append(1) else: stats.append(statFormula(baseStats[species]['hp'],poke['level'],-1,poke['ivs']['hp'],poke['evs']['hp'])) stats.append(statFormula(baseStats[species]['atk'],poke['level'],nmod[poke['nature']][0],poke['ivs']['atk'],poke['evs']['atk'])) stats.append(statFormula(baseStats[species]['def'],poke['level'],nmod[poke['nature']][1],poke['ivs']['def'],poke['evs']['def'])) stats.append(statFormula(baseStats[species]['spa'],poke['level'],nmod[poke['nature']][3],poke['ivs']['spa'],poke['evs']['spa'])) stats.append(statFormula(baseStats[species]['spd'],poke['level'],nmod[poke['nature']][4],poke['ivs']['spd'],poke['evs']['spd'])) stats.append(statFormula(baseStats[species]['spe'],poke['level'],nmod[poke['nature']][2],poke['ivs']['spe'],poke['evs']['spe'])) if species == 'aegislash' and poke['ability'] == 'stancechange': #check for attacking move as well? stats[1] = statFormula(baseStats['aegislashblade']['atk'],poke['level'],nmod[poke['nature']][0],poke['ivs']['atk'],poke['evs']['atk']) stats[2] += statFormula(baseStats['aegislashblade']['def'],poke['level'],nmod[poke['nature']][1],poke['ivs']['def'],poke['evs']['def']) stats[3] = statFormula(baseStats['aegislashblade']['spa'],poke['level'],nmod[poke['nature']][3],poke['ivs']['spa'],poke['evs']['spa']) stats[4] += statFormula(baseStats['aegislashblade']['spd'],poke['level'],nmod[poke['nature']][4],poke['ivs']['spd'],poke['evs']['spd']) stats[2] /= 2 stats[4] /= 2 #calculate base stalliness bias = poke['evs']['atk']+poke['evs']['spa']-poke['evs']['hp']-poke['evs']['def']-poke['evs']['spd'] if species == 'shedinja': stalliness = 0 elif species == 'ditto': stalliness = math.log(3,2) #eventually I'll want to replace this with mean stalliness for the tier else: try: stalliness=-math.log(((2.0*poke['level']+10)/250*max(stats[1],stats[3])/max(stats[2],stats[4])*120+2)*0.925/stats[0],2) except: sys.stderr.write('Got a problem with a '+species+'\n') sys.stderr.write(poke) return None #moveset modifications if poke['ability'] in ['purepower','hugepower']: stalliness -= 1.0 if poke['item'] in ['choiceband','choicescarf','choicespecs','lifeorb']: stalliness -= 0.5 if poke['item'] == 'eviolite': stalliness += 0.5 if 'spikes' in poke['moves']: stalliness += 0.5 if 'toxicspikes' in poke['moves']: stalliness += 0.5 if 'toxic' in poke['moves']: stalliness += 1.0 if 'willowisp' in poke['moves']: stalliness += 0.5 if len(set(['recover' ,'slackoff', 'healorder', 'milkdrink', 'roost', 'moonlight', 'morningsun', 'synthesis', 'wish', 'aquaring', 'rest', 'softboiled', 'swallow', 'leechseed']).intersection(poke['moves'])) != 0: stalliness += 1.0 if poke['ability'] == 'regenerator': stalliness += 0.5 if len(set(['healbell','aromatherapy']).intersection(poke['moves'])) != 0: stalliness += 0.5 if poke['ability'] in ['chlorophyll', 'download', 'hustle', 'moxie', 'reckless', 'sandrush', 'solarpower', 'swiftswim', 'technician', 'tintedlens', 'darkaura', 'fairyaura', 'infiltrator', 'parentalbond', 'protean', 'strongjaw', 'sweetveil', 'toughclaws','aerilate','normalize','pixilate','refrigerate']: stalliness -= 0.5 if poke['ability'] in ['flareboost', 'guts', 'quickfeet'] and poke['item'] == 'flameorb': stalliness -= 1.0 if poke['ability'] in ['toxicboost', 'guts', 'quickfeet'] and poke['item'] == 'toxicorb': stalliness -= 1.0 if poke['ability'] in ['speedboost', 'moody']: stalliness -= 1.0 if poke['ability'] in ['arenatrap','magnetpull','shadowtag']: stalliness -= 1.0 elif len(set(['block','meanlook','spiderweb','pursuit']).intersection(poke['moves'])) != 0: stalliness -= 0.5 if poke['ability'] in ['dryskin', 'filter', 'hydration', 'icebody', 'intimidate', 'ironbarbs', 'marvelscale', 'naturalcure', 'magicguard', 'multiscale', 'raindish', 'roughskin', 'solidrock', 'thickfat', 'unaware', 'aromaveil', 'bulletproof', 'cheekpouch', 'gooey']: stalliness += 0.5 if poke['ability'] == 'poisonheal' and poke['item'] == 'toxicorb': stalliness += 0.5 if poke['ability'] in ['slowstart','truant','furcoat']: stalliness += 1.0 if poke['item'] == 'lightclay': stalliness -= 1.0 if 'bellydrum' in poke['moves']: stalliness -= 2.0 elif 'shellsmash' in poke['moves']: stalliness -= 1.5 elif len(set(['curse', 'dragondance', 'growth', 'shiftgear', 'swordsdance', 'fierydance', 'nastyplot', 'tailglow', 'quiverdance', 'geomancy']).intersection(poke['moves'])) != 0: stalliness -= 1.0 elif len(set(['acupressure', 'bulkup', 'coil', 'howl', 'workup', 'meditate', 'sharpen', 'calmmind', 'chargebeam', 'agility', 'autotomize', 'flamecharge', 'rockpolish', 'doubleteam', 'minimize', 'tailwind', 'poweruppunch', 'rototiller']).intersection(poke['moves'])) != 0: stalliness -= 0.5 if 'substitute' in poke['moves']: stalliness -= 0.5 if len(set(['protect','detect','kingsshield','matblock','spikyshield']).intersection(poke['moves'])) != 0: stalliness += 1.0 if 'endeavor' in poke['moves']: stalliness -= 1.0 if 'superfang' in poke['moves']: stalliness -= 0.5 if 'trick' in poke['moves']: stalliness -= 0.5 if 'psychoshift' in poke['moves']: stalliness += 0.5 if len(set(['whirlwind', 'roar', 'circlethrow', 'dragontail']).intersection(poke['moves'])) != 0: stalliness += 0.5 if len(set(['haze', 'clearsmog']).intersection(poke['moves'])) != 0: stalliness += 0.5 if len(set(['thunderwave', 'stunspore', 'glare', 'nuzzle']).intersection(poke['moves'])) != 0: stalliness += 0.5 if len(set(['supersonic', 'confuseray', 'swagger', 'flatter', 'teeterdance', 'yawn']).intersection(poke['moves'])) != 0: stalliness += 0.5 if len(set(['darkvoid', 'grasswhistle', 'hypnosis', 'lovelykiss', 'sing', 'sleeppowder', 'spore']).intersection(poke['moves'])) != 0: stalliness -= 0.5 if poke['item'] == 'redcard': stalliness += 0.5 if poke['item'] == 'rockyhelmet': stalliness += 0.5 if poke['item'] in ['firegem', 'watergem', 'electricgem', 'grassgem', 'icegem', 'fightinggem', 'posiongem', 'groundgem', 'groundgem', 'flyinggem', 'psychicgem', 'buggem', 'rockgem', 'ghostgem', 'darkgem', 'steelgem', 'normalgem', 'focussash', 'mentalherb', 'powerherb', 'whiteherb', 'absorbbulb', 'berserkgene', 'cellbattery', 'redcard', 'focussash', 'airballoon', 'ejectbutton', 'shedshell', 'aguavberry', 'apicotberry', 'aspearberry', 'babiriberry', 'chartiberry', 'cheriberry', 'chestoberry', 'chilanberry', 'chopleberry', 'cobaberry', 'custapberry', 'enigmaberry', 'figyberry', 'ganlonberry', 'habanberry', 'iapapaberry', 'jabocaberry', 'kasibberry', 'kebiaberry', 'lansatberry', 'leppaberry', 'liechiberry', 'lumberry', 'magoberry', 'micleberry', 'occaberry', 'oranberry', 'passhoberry', 'payapaberry', 'pechaberry', 'persimberry', 'petayaberry', 'rawstberry', 'rindoberry', 'rowapberry', 'salacberry', 'shucaberry', 'sitrusberry', 'starfberry', 'tangaberry', 'wacanberry', 'wikiberry', 'yacheberry','keeberry','marangaberry','roseliberry','snowball']: stalliness -= 0.5 if poke['ability'] == 'harvest' or 'recycle' in poke['moves']: stalliness += 1.0 if len(set(['jumpkick', 'doubleedge', 'submission', 'petaldance', 'hijumpkick', 'outrage', 'volttackle', 'closecombat', 'flareblitz', 'bravebird', 'woodhammer', 'headsmash', 'headcharge', 'wildcharge', 'takedown', 'dragonascent']).intersection(poke['moves'])) != 0: stalliness -= 0.5 if len(set(['selfdestruct', 'explosion', 'destinybond', 'perishsong', 'memento', 'healingwish', 'lunardance', 'finalgambit']).intersection(poke['moves'])) != 0: stalliness -= 1.0 if len(set(['guillotine', 'fissure', 'sheercold']).intersection(poke['moves'])) != 0: stalliness -= 1.0 if poke['ability'] in ['sandstream','snowwarning'] or 'sandstorm' in poke['moves'] or 'hail' in poke['moves']: stalliness += 0.5 if species in ['latios', 'latias'] and poke['item'] == 'souldew': stalliness -= 0.5 if species == 'pikachu' and poke['item'] == 'lightball': stalliness -= 1.0 if species in ['cubone', 'marowak'] and poke['item'] == 'thickclub': stalliness -= 1.0 if species == 'clamperl' and poke['item'] == 'deepseatooth': stalliness -= 1.0 if species == 'clamperl' and poke['item'] == 'deepseascale': stalliness += 1.0 if poke['item'] in ['expertbelt', 'wiseglasses', 'muscleband', 'dracoplate', 'dreadplate', 'earthplate', 'fistplate', 'flameplate', 'icicleplate', 'insectplate', 'ironplate', 'meadowplate', 'mindplate', 'skyplate', 'splashplate', 'spookyplate', 'stoneplate', 'toxicplate', 'zapplate', 'blackglasses', 'charcoal', 'dragonfang', 'hardstone', 'magnet', 'metalcoat', 'miracleseed', 'mysticwater', 'nevermeltice', 'poisonbarb', 'sharpbeak', 'silkscarf', 'silverpowder', 'softsand', 'spelltag', 'twistedspoon', 'pixieplate']: stalliness -= 0.25 if species == 'dialga' and poke['item'] == 'adamantorb': stalliness -= 0.25 if species == 'palkia' and poke['item'] == 'lustrousorb': stalliness = stalliness - 0.25 if species == 'giratinaorigin' and poke['item'] == 'griseousorb': #it's better be holding a Griseous Orb stalliness -= 0.25 if poke['item'] == 'weaknesspolicy': stalliness -= 1.0 return stalliness,bias
def movesetCounter(filename, cutoff, teamtype, usage): file = gzip.open(filename,'rb') raw = file.read() file.close() raw=raw.split('][') for i in range(len(raw)): if (i>0): raw[i]='['+raw[i] if (i<len(raw)-1): raw[i]=raw[i]+']' species = keyLookup[filename[string.rfind(filename,'/')+1:]] for alias in aliases: if species in aliases[alias]: species = alias break bias = [] stalliness = [] abilities = {} items = {} happinesses = {} spreads = {} moves = {} movesets = [] weights = [] rawCount = 0 gxes={} for line in raw: movesets = json.loads(line) for moveset in movesets: if teamtype: if teamtype not in moveset['tags']: continue rawCount = rawCount+1 weight=weighting(1500.0,130.0,cutoff) if 'rating' in moveset.keys(): if 'rpr' in moveset['rating'].keys() and 'rprd' in moveset['rating'].keys(): gxe = victoryChance(moveset['rating']['rpr'],moveset['rating']['rprd'],1500.0,130.0) gxe=int(round(100*gxe)) addMe=True if moveset['trainer'] in gxes: if gxes[moveset['trainer']] > gxe: addMe = False if addMe: gxes[moveset['trainer']]=gxe if moveset['rating']['rprd'] != 0.0: weight=weighting(moveset['rating']['rpr'],moveset['rating']['rprd'],cutoff) weights.append(weight) elif 'outcome' in moveset.keys(): if moveset['outcome'] == 'win': weight=weighting(1540.16061434,122.858308077,cutoff) elif moveset['outcome'] == 'loss': weight=weighting(1459.83938566,122.858308077,cutoff) #else it's a tie, and we use 1500 if moveset['ability'] not in keyLookup: moveset['ability'] = 'illuminate' if moveset['ability'] not in abilities: abilities[moveset['ability']] = 0.0 abilities[moveset['ability']] = abilities[moveset['ability']] + weight if moveset['item'] not in keyLookup: moveset['item'] = 'nothing' if moveset['item'] not in items: items[moveset['item']] = 0.0 items[moveset['item']] = items[moveset['item']] + weight if moveset['nature'] in ['serious','docile','quirky','bashful'] or moveset['nature'] not in keyLookup: nature = 'hardy' #round the EVs for stat in moveset['evs'].keys(): ev=moveset['evs'][stat] if species == 'shedinja' and stat == 'hp': stat = 1 moveset['evs']['stat']=0 continue if stat == 'hp': n=-1 else: n=nmod[moveset['nature']][{'atk': 0, 'def': 1, 'spa': 2, 'spd': 3, 'spe': 4}[stat]] x = statFormula(baseStats[keyify(species)][stat],moveset['level'],n,moveset['ivs'][stat],ev) while ev > 0: if x != statFormula(baseStats[keyify(species)][stat],moveset['level'],n,moveset['ivs'][stat],ev-1): break ev = ev-1 moveset['evs'][stat]=ev spread = keyLookup[moveset['nature']]+':' for stat in ['hp','atk','def','spa','spd']: spread=spread+str(moveset['evs'][stat])+'/' spread=spread+str(moveset['evs']['spe']) if spread not in spreads: spreads[spread] = 0.0 spreads[spread] += weight for move in moveset['moves']: if move in keyLookup: #I think it's valid to triple-count 'nothing' right now #if keyLookup[move]=='Nothing': # continue if move not in moves: moves[move] = 0.0 moves[move] += weight happiness = moveset['happiness'] if happiness not in happinesses.keys(): happinesses[happiness]=0.0 happinesses[happiness]+=weight count = sum(abilities.values()) gxes=list(reversed(sorted(gxes.values()))) #teammate stats try: teammates = teammateMatrix[species] except KeyError: sys.stderr.write('No teammates data for '+filename+' ('+str(cutoff)+')\n') teammates={} for s in teammates: if s not in usage.keys(): teammates[s]=0.0 else: teammates[s]=teammates[s]-(count*usage[s]) #checks and counters cc={} if species in encounterMatrix.keys(): for s in encounterMatrix[species].keys(): matchup = encounterMatrix[species][s] #number of times species is KOed by s + number of times species switches out against s over number of times #either (or both) is switched out or KOed (don't count u-turn KOs or force-outs) n=sum(matchup[0:6]) if n>20: p=float(matchup[0]+matchup[3])/n d=math.sqrt(p*(1.0-p)/n) #cc[s]=p-4*d #using a CRE-style calculation cc[s]=[n,p,d] maxGXE = [0,0,0,0] if len(gxes) > 0: maxGXE = [len(gxes),gxes[0],gxes[int(math.ceil(0.01*len(gxes)))-1],gxes[int(math.ceil(0.20*len(gxes)))-1]] stuff = { 'Raw count': rawCount, 'Viability Ceiling': maxGXE, 'Abilities': abilities, 'Items': items, 'Spreads': spreads, 'Moves': moves, 'Happiness' : happinesses, 'Teammates': teammates, 'Checks and Counters': cc} #print tables tablewidth = 40 separator = ' +' for i in range(tablewidth): separator = separator + '-' separator = separator + '+ ' print separator line = ' | '+species for i in range(len(species),tablewidth-1): line = line + ' ' line = line + '| ' print line print separator line = ' | Raw count: %d'%(rawCount) while len(line) < tablewidth+2: line = line + ' ' line = line + '| ' print line line = ' | Avg. weight: ' if len(weights)>0: line = line+str(sum(weights)/len(weights)) else: line = line+'---' while len(line) < tablewidth+2: line = line + ' ' line = line + '| ' print line line = ' | Viability Ceiling: %d'%(maxGXE[1]) while len(line) < tablewidth+2: line = line + ' ' line = line + '| ' print line print separator for x in ['Abilities','Items','Spreads','Moves','Teammates','Checks and Counters']: table = [] line = ' | '+x while len(line) < tablewidth+2: line = line + ' ' line = line + '| ' print line for i in stuff[x]: if (x in ['Spreads', 'Teammates','Checks and Counters']): table.append([i,stuff[x][i]]) else: table.append([keyLookup[i],stuff[x][i]]) if x is 'Checks and Counters': table=sorted(table, key=lambda table:-(table[1][1]-4.0*table[1][2])) else: table=sorted(table, key=lambda table:-table[1]) total = 0.0 for i in range(len(table)): if (total > .95 and x is not 'Abilities') or (x is 'Abilities' and i>5) or (x is 'Spreads' and i>5) or (x is 'Teammates' and i>11) or (x is 'Checks and Counters' and i>11): if x is 'Moves': line = ' | %s %6.3f%%' % ('Other',400.0*(1.0-total)) elif x not in ['Teammates','Checks and Counters']: line = ' | %s %6.3f%%' % ('Other',100.0*(1.0-total)) else: if x is 'Checks and Counters': matchup = encounterMatrix[species][table[i][0]] n=sum(matchup[0:6]) score=float(table[i][1][1])-4.0*table[i][1][2] if score < 0.5: break line = u' | %s %6.3f (%3.2f\u00b1%3.2f)' % (table[i][0],100.0*score,100.0*table[i][1][1],100*table[i][1][2]) while len(line) < tablewidth+1: line = line + ' ' line=line+' |\n |\t (%2.1f%% KOed / %2.1f%% switched out)' %(float(100.0*matchup[0])/n,float(100.0*matchup[3])/n) if float(100.0*matchup[0])/n < 10.0: line = line+' ' if float(100.0*matchup[3])/n < 10.0: line = line+' ' elif x is 'Teammates': line = ' | %s %+6.3f%%' % (table[i][0],100.0*table[i][1]/count) if table[i][1] < 0.005*count: break else: line = ' | %s %6.3f%%' % (table[i][0],100.0*table[i][1]/count) while len(line) < tablewidth+2: line = line + ' ' line = line + '| ' print line.encode('utf8') if (total > .95 and x is not 'Abilities') or (x is 'Abilities' and i>5) or (x is 'Spreads' and i>5) or (x is 'Teammates' and i>10) or (x is 'Checks and Counters' and i>10): break if x is 'Moves': total = total + float(table[i][1])/count/4.0 elif x is 'Teammates': total = total + float(table[i][1])/count/5.0 elif x is not 'Checks and Counters': total = total + float(table[i][1])/count print separator return stuff
return stuff file = open('keylookup.pickle') keyLookup = pickle.load(file) file.close() keyLookup['nothing']='Nothing' keyLookup['']='Nothing' cutoff = 1500 cutoffdeviation = 0 teamtype = None if (len(sys.argv) > 2): cutoff = float(sys.argv[2]) if (len(sys.argv) > 3): teamtype = keyify(sys.argv[3]) specs = '-' if teamtype: specs += teamtype+'-' specs += '{:.0f}'.format(cutoff) file = open('Raw/moveset/'+str(sys.argv[1])+'/teammate'+specs+'.pickle') teammateMatrix = pickle.load(file) file.close() file = open('Raw/moveset/'+str(sys.argv[1])+'/encounterMatrix'+specs+'.pickle') encounterMatrix = pickle.load(file) file.close() filename = 'Stats/'+str(sys.argv[1])+specs+'.txt'
def main(months): file = open('keylookup.pickle') keyLookup = pickle.load(file) file.close() rise = [0.06696700846,0.04515839608,0.03406367107][len(months)-1] drop = [0.01717940145,0.02284003156,0.03406367107][len(months)-1] formatsData = getBattleFormatsData() curTiers = {} NFE=[] for poke in formatsData: if poke in ['pichuspikyeared', 'unownb', 'unownc', 'unownd', 'unowne', 'unownf', 'unowng', 'unownh', 'unowni', 'unownj', 'unownk', 'unownl', 'unownm', 'unownn', 'unowno', 'unownp', 'unownq', 'unownr', 'unowns', 'unownt', 'unownu', 'unownv', 'unownw', 'unownx', 'unowny', 'unownz', 'unownem', 'unownqm', 'burmysandy', 'burmytrash', 'cherrimsunshine', 'shelloseast', 'gastrodoneast', 'deerlingsummer', 'deerlingautumn', 'deerlingwinter', 'sawsbucksummer', 'sawsbuckautumn', 'sawsbuckwinter', 'keldeoresolution', 'genesectdouse', 'genesectburn', 'genesectshock', 'genesectchill', 'basculinbluestriped', 'darmanitanzen','keldeoresolute','pikachucosplay']: continue if 'isNonstandard' in formatsData[poke]: if formatsData[poke]['isNonstandard']: continue #if 'requiredItem' in formatsData[poke]: # continue #if poke == 'rayquazamega': # continue if 'tier' not in formatsData[poke].keys(): continue old = formatsData[poke]['tier'] if old[0] == '(': old = old[1:-1] if old in ['NFE','LC']: NFE.append(poke) if old == 'Illegal' or old == 'Unreleased': continue elif old not in tiers: old = 'PU' curTiers[poke]=old usage = {} #track usage across all relevant tiers [OU,UU,RU,NU] remaining=24.0 for i in xrange(len(months)): weight = remaining if i + 1 < len(months): if i == 0: weight = 20.0 if i == 1: weight = 3.0 remaining -= weight usageTiers = ['ou','uu','ru','nu','pu'] for j in xrange(len(usageTiers)): nRegular = nSuspect = 0 baseline = "1630" if usageTiers[j] in ['ou']: baseline = "1695" try: usageRegular, nRegular = readTable(months[i]+"/Stats/"+usageTiers[j]+"-"+baseline+".txt") except IOError: pass try: usageSuspect, nSuspect = readTable(months[i]+"/Stats/"+usageTiers[j]+"suspecttest-"+baseline+".txt") except IOError: pass if nRegular > 0: for poke in usageRegular: if keyify(poke) not in usage: usage[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usage[keyify(poke)][j] += weight*nRegular/(nRegular+nSuspect)*usageRegular[poke]/24 if nSuspect > 0: for poke in usageSuspect: if keyify(poke) not in usage: usage[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usage[keyify(poke)][j] += weight*nSuspect/(nRegular+nSuspect)*usageSuspect[poke]/24 #generate three-month tables and start working on that new tier list OU = [] UU = [] RU = [] NU = [] PU = [] for i in usage: if usage[i][0] > 0.0: OU.append([i,usage[i][0]]) if usage[i][1] > 0.0: UU.append([i,usage[i][1]]) if usage[i][2] > 0.0: RU.append([i,usage[i][2]]) if usage[i][3] > 0.0: NU.append([i,usage[i][3]]) if usage[i][4] > 0.0: PU.append([i,usage[i][4]]) OU = sorted(OU, key=lambda OU:-OU[1]) UU = sorted(UU, key=lambda UU:-UU[1]) RU = sorted(RU, key=lambda RU:-RU[1]) NU = sorted(NU, key=lambda NU:-NU[1]) PU = sorted(PU, key=lambda PU:-PU[1]) makeTable(OU,"OU",keyLookup) makeTable(UU,"UU",keyLookup) makeTable(RU,"RU",keyLookup) makeTable(NU,"NU",keyLookup) newTiers={} #start with Ubers for poke in curTiers.keys(): if curTiers[poke] == 'Uber': newTiers[poke] = 'Uber' #next do the OU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][0] > rise and poke not in newTiers.keys(): newTiers[poke] = 'OU' #next do the UU drops for poke in curTiers.keys(): if curTiers[poke] == 'OU' and poke not in newTiers.keys(): if usage[poke][0] < drop: newTiers[poke] = 'UU' else: newTiers[poke] = 'OU' #next do BL for poke in curTiers.keys(): if curTiers[poke] == 'BL' and poke not in newTiers.keys(): newTiers[poke] = 'BL' #next do the UU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][1] > rise and poke not in newTiers.keys(): newTiers[poke] = 'UU' #next do the RU drops for poke in curTiers.keys(): if curTiers[poke] == 'UU' and poke not in newTiers.keys(): if usage[poke][1] < drop: newTiers[poke] = 'RU' else: newTiers[poke] = 'UU' #next do BL2 for poke in curTiers.keys(): if curTiers[poke] == 'BL2' and poke not in newTiers.keys(): newTiers[poke] = 'BL2' #next do the RU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][2] > rise and poke not in newTiers.keys(): newTiers[poke] = 'RU' #next do the NU drops for poke in curTiers.keys(): if curTiers[poke] == 'RU' and poke not in newTiers.keys(): if usage[poke][2] < drop: newTiers[poke] = 'NU' else: newTiers[poke] = 'RU' #next do BL3 for poke in curTiers.keys(): if curTiers[poke] == 'BL3' and poke not in newTiers.keys(): newTiers[poke] = 'BL3' #next do the NU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][3] > rise and poke not in newTiers.keys(): newTiers[poke] = 'NU' #next do the PU drops for poke in curTiers.keys(): if curTiers[poke] == 'NU' and poke not in newTiers.keys(): if usage[poke][3] < drop: newTiers[poke] = 'PU' else: newTiers[poke] = 'NU' #next do BL4 for poke in curTiers.keys(): if curTiers[poke] == 'BL4' and poke not in newTiers.keys(): newTiers[poke] = 'BL4' #the rest are PU for poke in curTiers.keys(): if poke not in newTiers.keys(): newTiers[poke] = 'PU' print "" for poke in curTiers: if curTiers[poke] != newTiers[poke]: species = keyLookup[poke] if species.endswith('-Mega') or species.endswith('-Mega-X') or species.endswith('-Mega-Y') or species.endswith('-Primal'): base = keyify(species[:species.index('-')]) #none of the megas have hyphenated names if tiers.index(newTiers[base]) < tiers.index(newTiers[poke]): #if the base is in a higher tier newTiers[poke] = newTiers[base] continue print species+" moved from "+curTiers[poke]+" to "+newTiers[poke] print "" print "" print "[size=5][b]FU[/b][/size]" print "FU is an unofficial tier. It is not currently supported on any simulator, but since [url=http://www.smogon.com/forums/forums/pu.327/?prefix_id=282]people have expressed interest in such a metagame[/url], here is a proper banlist:" makeTable(PU,"PU",keyLookup) fuBanlist = [] for poke in usage.keys(): if poke in curTiers: if newTiers[poke] == 'PU' and (usage[poke][4] >= drop or curTiers[poke] == 'NU'): fuBanlist.append(poke) fuBanlist = sorted(fuBanlist) printme = "[b]Banlist:[/b] " for poke in fuBanlist: printme += keyLookup[poke]+', ' printme = printme[:-2] print printme
def main(months): file = open('baseStats.json') baseStats = json.loads(file.readline()) file.close() validPokemon=baseStats.keys() formats = json.load(open('formats.json')) banlists={} for format in ('lc','lcuu','doublesou', 'doublesuu'): banlist=[] for entry in formats[format]['banlist']: keyified=keyify(entry) if keyified in validPokemon: banlist.append(keyified) banlists[formats[format]['name']]=banlist curTiers= {} curTiers['LC']={} curTiers['Doubles']={} for poke in banlists['LC']: curTiers['LC'][poke]='Uber' for poke in banlists['LC UU']: if poke not in curTiers['LC'].keys(): curTiers['LC'][poke]='OU' for poke in banlists['Doubles OU']: curTiers['Doubles'][poke]='Uber' for poke in banlists['Doubles UU']: if poke not in curTiers['Doubles'].keys(): curTiers['Doubles'][poke]='OU' rise = [0.06696700846,0.04515839608,0.03406367107][len(months)-1] drop = [0.01717940145,0.02284003156,0.03406367107][len(months)-1] usageLC = {} usageDoubles = {} remaining=24.0 for i in xrange(len(months)): weight = remaining if i + 1 < len(months): if i == 0: weight = 20.0 if i == 1: weight = 3.0 remaining -= weight nRegular = nSuspect = 0 try: usageRegular, nRegular = readTable(months[i]+"/Stats/lc-1630.txt") except IOError: pass try: usageSuspect, nSuspect = readTable(months[i]+"/Stats/lcsuspecttest-1630.txt") except IOError: pass if nRegular > 0: for poke in usageRegular: if keyify(poke) not in usageLC: usageLC[keyify(poke)]=[0,0] if poke != 'empty': usageLC[keyify(poke)][0] += weight*nRegular/(nRegular+nSuspect)*usageRegular[poke]/24 if nSuspect > 0: for poke in usageSuspect: if keyify(poke) not in usageLC: usageLC[keyify(poke)]=[0,0] if poke != 'empty': usageLC[keyify(poke)][0] += weight*nSuspect/(nRegular+nSuspect)*usageSuspect[poke]/24 usageTiers = ['doublesou','doublesuu'] for j in xrange(len(usageTiers)): nRegular = nSuspect = 0 baseline = "1630" if usageTiers[j] in ['doublesou']: baseline = "1695" try: usageRegular, nRegular = readTable(months[i]+"/Stats/"+usageTiers[j]+"-"+baseline+".txt") except IOError: pass try: usageSuspect, nSuspect = readTable(months[i]+"/Stats/"+usageTiers[j]+"suspecttest-"+baseline+".txt") except IOError: pass if nRegular > 0: for poke in usageRegular: if keyify(poke) not in usageDoubles: usageDoubles[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usageDoubles[keyify(poke)][j] += weight*nRegular/(nRegular+nSuspect)*usageRegular[poke]/24 if nSuspect > 0: for poke in usageSuspect: if keyify(poke) not in usageDoubles: usageDoubles[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usageDoubles[keyify(poke)][j] += weight*nSuspect/(nRegular+nSuspect)*usageSuspect[poke]/24 #generate three-month tables and start working on that new tier list newTiers={} print "[size=5][b]Little Cup[/b][/size]" (LCOU,LCUU) = usageToTiers(usageLC) makeTable(LCOU,"LC OU",keyLookup) #makeTable(LCUU,"LC UU",keyLookup) newTiers['LC']=raiseAndDrop(curTiers['LC'],usageLC,'UU',rise,drop) print "" for poke in curTiers['LC']: if curTiers['LC'][poke] != newTiers['LC'][poke]: if newTiers['LC'][poke] != 'NU': print keyLookup[poke]+" moved from LC "+curTiers['LC'][poke]+" to LC "+newTiers['LC'][poke] print "" print "" print "[size=5][b]Doubles[/b][/size]" (doublesOU,doublesUU) = usageToTiers(usageDoubles) makeTable(doublesOU,"Doubles OU",keyLookup) newTiers['Doubles']=raiseAndDrop(curTiers['Doubles'],usageDoubles,'UU',rise,drop) print "" newUU = [] for poke in curTiers['Doubles']: if curTiers['Doubles'][poke] != newTiers['Doubles'][poke]: species = keyLookup[poke] if species.endswith('-Mega') or species.endswith('-Mega-X') or species.endswith('-Mega-Y') or species.endswith('-Primal'): base = keyify(species[:species.index('-')]) #none of the megas have hyphenated names if tiers.index(newTiers['Doubles'][base]) < tiers.index(newTiers['Doubles'][poke]): #if the base is in a higher tier newTiers['Doubles'][poke] = newTiers['Doubles'][base] continue if newTiers['Doubles'][poke] != 'NU': print keyLookup[poke]+" moved from Doubles "+curTiers['Doubles'][poke]+" to Doubles "+newTiers['Doubles'][poke] print "" print "" print "[size=5][b]Doubles NU[/b][/size]" print "Doubles NU is an unofficial metagame that's apparently so unpopular there's not even enough interest to support a challenge-only format. Still, it's conceivable that someone will want to play it, and that person should have an unofficial banlist to refer to. So..." makeTable(doublesUU,"Doubles UU",keyLookup) dnuBanlist = [] for poke in usageDoubles.keys(): if poke in curTiers['Doubles']: if newTiers['Doubles'][poke] == 'UU' and (usageDoubles[poke][1] >= drop or curTiers['Doubles'][poke] == 'OU'): dnuBanlist.append(poke) dnuBanlist = sorted(dnuBanlist) printme = "[b]Banlist:[/b] " for poke in dnuBanlist: printme += keyLookup[poke]+', ' printme = printme[:-2] print printme
def movesetCounter(filename, cutoff, teamtype, usage): file = gzip.open(filename, 'rb') raw = file.read() file.close() raw = raw.split('][') for i in range(len(raw)): if (i > 0): raw[i] = '[' + raw[i] if (i < len(raw) - 1): raw[i] = raw[i] + ']' species = keyLookup[filename[string.rfind(filename, '/') + 1:]] for alias in aliases: if species in aliases[alias]: species = alias break bias = [] stalliness = [] abilities = {} items = {} happinesses = {} spreads = {} moves = {} movesets = [] weights = [] rawCount = 0 for line in raw: movesets = json.loads(line) for moveset in movesets: if teamtype: if teamtype not in moveset['tags']: continue rawCount = rawCount + 1 weight = weighting(1500.0, 130.0, cutoff) if 'rating' in moveset.keys(): if 'rpr' in moveset['rating'].keys( ) and 'rprd' in moveset['rating'].keys(): if moveset['rating']['rprd'] != 0.0: weight = weighting(moveset['rating']['rpr'], moveset['rating']['rprd'], cutoff) weights.append(weight) elif 'outcome' in moveset.keys(): if moveset['outcome'] == 'win': weight = weighting(1540.16061434, 122.858308077, cutoff) elif moveset['outcome'] == 'loss': weight = weighting(1459.83938566, 122.858308077, cutoff) #else it's a tie, and we use 1500 if moveset['ability'] not in keyLookup: moveset['ability'] = 'illuminate' if moveset['ability'] not in abilities: abilities[moveset['ability']] = 0.0 abilities[ moveset['ability']] = abilities[moveset['ability']] + weight if moveset['item'] not in keyLookup: moveset['item'] = 'nothing' if moveset['item'] not in items: items[moveset['item']] = 0.0 items[moveset['item']] = items[moveset['item']] + weight if moveset['nature'] in ['serious', 'docile', 'quirky', 'bashful' ] or moveset['nature'] not in keyLookup: nature = 'hardy' #round the EVs for stat in moveset['evs'].keys(): ev = moveset['evs'][stat] if species == 'shedinja' and stat == 'hp': stat = 1 moveset['evs']['stat'] = 0 continue if stat == 'hp': n = -1 else: n = nmod[moveset['nature']][{ 'atk': 0, 'def': 1, 'spa': 2, 'spd': 3, 'spe': 4 }[stat]] x = statFormula(baseStats[keyify(species)][stat], moveset['level'], n, moveset['ivs'][stat], ev) while ev > 0: if x != statFormula(baseStats[keyify(species)][stat], moveset['level'], n, moveset['ivs'][stat], ev - 1): break ev = ev - 1 moveset['evs'][stat] = ev spread = keyLookup[moveset['nature']] + ':' for stat in ['hp', 'atk', 'def', 'spa', 'spd']: spread = spread + str(moveset['evs'][stat]) + '/' spread = spread + str(moveset['evs']['spe']) if spread not in spreads: spreads[spread] = 0.0 spreads[spread] += weight for move in moveset['moves']: if move in keyLookup: #I think it's valid to triple-count 'nothing' right now #if keyLookup[move]=='Nothing': # continue if move not in moves: moves[move] = 0.0 moves[move] += weight happiness = moveset['happiness'] if happiness not in happinesses.keys(): happinesses[happiness] = 0.0 happinesses[happiness] += weight count = sum(abilities.values()) #teammate stats try: teammates = teammateMatrix[species] except KeyError: sys.stderr.write('No teammates data for ' + filename + ' (' + str(cutoff) + ')\n') teammates = {} for s in teammates: if s not in usage.keys(): teammates[s] = 0.0 else: teammates[s] = teammates[s] - (count * usage[s]) #checks and counters cc = {} if species in encounterMatrix.keys(): for s in encounterMatrix[species].keys(): matchup = encounterMatrix[species][s] #number of times species is KOed by s + number of times species switches out against s over number of times #either (or both) is switched out or KOed (don't count u-turn KOs or force-outs) n = sum(matchup[0:6]) if n > 20: p = float(matchup[0] + matchup[3]) / n d = math.sqrt(p * (1.0 - p) / n) #cc[s]=p-4*d #using a CRE-style calculation cc[s] = [n, p, d] stuff = { 'Raw count': rawCount, 'Abilities': abilities, 'Items': items, 'Spreads': spreads, 'Moves': moves, 'Happiness': happinesses, 'Teammates': teammates, 'Checks and Counters': cc } #print tables tablewidth = 40 separator = ' +' for i in range(tablewidth): separator = separator + '-' separator = separator + '+ ' print separator line = ' | ' + species for i in range(len(species), tablewidth - 1): line = line + ' ' line = line + '| ' print line print separator line = ' | Raw count: %d' % (rawCount) while len(line) < tablewidth + 2: line = line + ' ' line = line + '| ' print line line = ' | Avg. weight: ' if len(weights) > 0: line = line + str(sum(weights) / len(weights)) else: line = line + '---' while len(line) < tablewidth + 2: line = line + ' ' line = line + '| ' print line print separator for x in [ 'Abilities', 'Items', 'Spreads', 'Moves', 'Teammates', 'Checks and Counters' ]: table = [] line = ' | ' + x while len(line) < tablewidth + 2: line = line + ' ' line = line + '| ' print line for i in stuff[x]: if (x in ['Spreads', 'Teammates', 'Checks and Counters']): table.append([i, stuff[x][i]]) else: table.append([keyLookup[i], stuff[x][i]]) if x is 'Checks and Counters': table = sorted( table, key=lambda table: -(table[1][1] - 4.0 * table[1][2])) else: table = sorted(table, key=lambda table: -table[1]) total = 0.0 for i in range(len(table)): if (total > .95 and x is not 'Abilities') or ( x is 'Abilities' and i > 5) or (x is 'Spreads' and i > 5) or ( x is 'Teammates' and i > 11) or (x is 'Checks and Counters' and i > 11): if x is 'Moves': line = ' | %s %6.3f%%' % ('Other', 400.0 * (1.0 - total)) elif x not in ['Teammates', 'Checks and Counters']: line = ' | %s %6.3f%%' % ('Other', 100.0 * (1.0 - total)) else: if x is 'Checks and Counters': matchup = encounterMatrix[species][table[i][0]] n = sum(matchup[0:6]) score = float(table[i][1][1]) - 4.0 * table[i][1][2] if score < 0.5: break line = u' | %s %6.3f (%3.2f\u00b1%3.2f)' % ( table[i][0], 100.0 * score, 100.0 * table[i][1][1], 100 * table[i][1][2]) while len(line) < tablewidth + 1: line = line + ' ' line = line + ' |\n |\t (%2.1f%% KOed / %2.1f%% switched out)' % ( float(100.0 * matchup[0]) / n, float(100.0 * matchup[3]) / n) if float(100.0 * matchup[0]) / n < 10.0: line = line + ' ' if float(100.0 * matchup[3]) / n < 10.0: line = line + ' ' elif x is 'Teammates': line = ' | %s %+6.3f%%' % (table[i][0], 100.0 * table[i][1] / count) if table[i][1] < 0.005 * count: break else: line = ' | %s %6.3f%%' % (table[i][0], 100.0 * table[i][1] / count) while len(line) < tablewidth + 2: line = line + ' ' line = line + '| ' print line.encode('utf8') if (total > .95 and x is not 'Abilities') or ( x is 'Abilities' and i > 5) or (x is 'Spreads' and i > 5) or ( x is 'Teammates' and i > 10) or (x is 'Checks and Counters' and i > 10): break if x is 'Moves': total = total + float(table[i][1]) / count / 4.0 elif x is 'Teammates': total = total + float(table[i][1]) / count / 5.0 elif x is not 'Checks and Counters': total = total + float(table[i][1]) / count print separator return stuff
file = open('keylookup.pickle') keyLookup = pickle.load(file) file.close() keyLookup['nothing'] = 'Nothing' keyLookup[''] = 'Nothing' cutoff = 1500 cutoffdeviation = 0 teamtype = None if (len(sys.argv) > 2): cutoff = float(sys.argv[2]) if (len(sys.argv) > 3): teamtype = keyify(sys.argv[3]) specs = '-' if teamtype: specs += teamtype + '-' specs += '{:.0f}'.format(cutoff) file = open('Raw/moveset/' + str(sys.argv[1]) + '/teammate' + specs + '.pickle') teammateMatrix = pickle.load(file) file.close() file = open('Raw/moveset/' + str(sys.argv[1]) + '/encounterMatrix' + specs + '.pickle') encounterMatrix = pickle.load(file) file.close()
def main(months): file = open('keylookup.pickle') keyLookup = pickle.load(file) file.close() rise = [0.06696700846,0.04515839608,0.03406367107][len(months)-1] drop = [0.01717940145,0.02284003156,0.03406367107][len(months)-1] formatsData = getBattleFormatsData() curTiers = {} NFE=[] for poke in formatsData: if poke in ['pichuspikyeared', 'unownb', 'unownc', 'unownd', 'unowne', 'unownf', 'unowng', 'unownh', 'unowni', 'unownj', 'unownk', 'unownl', 'unownm', 'unownn', 'unowno', 'unownp', 'unownq', 'unownr', 'unowns', 'unownt', 'unownu', 'unownv', 'unownw', 'unownx', 'unowny', 'unownz', 'unownem', 'unownqm', 'burmysandy', 'burmytrash', 'cherrimsunshine', 'shelloseast', 'gastrodoneast', 'deerlingsummer', 'deerlingautumn', 'deerlingwinter', 'sawsbucksummer', 'sawsbuckautumn', 'sawsbuckwinter', 'keldeoresolution', 'genesectdouse', 'genesectburn', 'genesectshock', 'genesectchill', 'basculinbluestriped', 'darmanitanzen','keldeoresolute','pikachucosplay']: continue if 'isNonstandard' in formatsData[poke]: if formatsData[poke]['isNonstandard']: continue #if 'requiredItem' in formatsData[poke]: # continue #if poke == 'rayquazamega': # continue if 'tier' not in formatsData[poke].keys(): continue old = formatsData[poke]['tier'] if old[0] == '(': old = old[1:-1] if old in ['NFE','LC']: NFE.append(poke) if old == 'Illegal' or old == 'Unreleased': continue elif old not in tiers: old = tiers[-1] curTiers[poke]=old usage = {} #track usage across all relevant tiers [OU,UU,RU,NU] remaining=24.0 for i in xrange(len(months)): weight = remaining if i + 1 < len(months): if i == 0: weight = 20.0 if i == 1: weight = 3.0 remaining -= weight for j in xrange(len(usageTiers)): n = {} u = {} baseline = "1630" if usageTiers[j] in ['ou']: baseline = "1695" for k in ('', 'suspecttest', 'alpha', 'beta'): try: u[k], n[k] = readTable(months[i]+"/Stats/gen7"+usageTiers[j]+k+"-"+baseline+".txt") except IOError: pass ntot = sum(n.values()) for k in u: for poke in u[k]: if keyify(poke) not in usage: usage[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usage[keyify(poke)][j] += weight*n[k]/ntot*u[k][poke]/24 #generate three-month tables and start working on that new tier list OU = [] UU = [] RU = [] ''' NU = [] PU = [] ''' for i in usage: if usage[i][0] > 0.0: OU.append([i,usage[i][0]]) if usage[i][1] > 0.0: UU.append([i,usage[i][1]]) if usage[i][2] > 0.0: RU.append([i,usage[i][2]]) ''' if usage[i][3] > 0.0: NU.append([i,usage[i][3]]) if usage[i][4] > 0.0: PU.append([i,usage[i][4]]) ''' OU = sorted(OU, key=lambda OU:-OU[1]) UU = sorted(UU, key=lambda UU:-UU[1]) RU = sorted(RU, key=lambda RU:-RU[1]) ''' NU = sorted(NU, key=lambda NU:-NU[1]) PU = sorted(PU, key=lambda PU:-PU[1]) ''' makeTable(OU,"OU",keyLookup) makeTable(UU,"UU",keyLookup) makeTable(RU,"RU",keyLookup) ''' makeTable(NU,"NU",keyLookup) ''' newTiers={} #start with Ubers for poke in curTiers.keys(): if curTiers[poke] == 'Uber': newTiers[poke] = 'Uber' for poke in curTiers.keys(): if poke not in usage: newTiers[poke] = curTiers[poke] #next do the OU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][0] > rise and poke not in newTiers.keys(): newTiers[poke] = 'OU' #next do the UU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'OU' and poke not in newTiers.keys(): if usage[poke][0] < drop: newTiers[poke] = 'UU' else: newTiers[poke] = 'OU' #next do BL for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'BL' and poke not in newTiers.keys(): newTiers[poke] = 'BL' #next do the UU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][1] > rise and poke not in newTiers.keys(): newTiers[poke] = 'UU' #next do the RU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'UU' and poke not in newTiers.keys(): if usage[poke][1] < drop: newTiers[poke] = 'RU' else: newTiers[poke] = 'UU' #next do BL2 for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'BL2' and poke not in newTiers.keys(): newTiers[poke] = 'BL2' #next do the RU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][2] > rise and poke not in newTiers.keys(): newTiers[poke] = 'RU' #next do the NU drops for poke in curTiers.keys(): if curTiers[poke] == 'RU' and poke not in newTiers.keys(): if usage[poke][2] < drop: newTiers[poke] = 'NU' else: newTiers[poke] = 'RU' #next do BL3 for poke in curTiers.keys(): if curTiers[poke] == 'BL3' and poke not in newTiers.keys(): newTiers[poke] = 'BL3' ''' #next do the NU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][3] > rise and poke not in newTiers.keys(): newTiers[poke] = 'NU' #next do the PU drops for poke in curTiers.keys(): if curTiers[poke] == 'NU' and poke not in newTiers.keys(): if usage[poke][3] < drop: newTiers[poke] = 'PU' else: newTiers[poke] = 'NU' #next do BL4 for poke in curTiers.keys(): if curTiers[poke] == 'BL4' and poke not in newTiers.keys(): newTiers[poke] = 'BL4' ''' #the rest go in the lowest tier for poke in curTiers.keys(): if poke not in newTiers.keys(): newTiers[poke] = tiers[-1] print "" for poke in curTiers: if curTiers[poke] != newTiers[poke]: species = keyLookup[poke] if species.endswith('-Mega') or species.endswith('-Mega-X') or species.endswith('-Mega-Y') or species.endswith('-Primal'): base = keyify(species[:species.index('-')]) #none of the megas have hyphenated names if tiers.index(newTiers[base]) < tiers.index(newTiers[poke]): #if the base is in a higher tier newTiers[poke] = newTiers[base] continue print species+" moved from "+curTiers[poke]+" to "+newTiers[poke]
#!/usr/bin/python import sys import json from TA import megas from common import keyify stats=json.load(open(sys.argv[1])) megastats=[] total=0 for species in stats['data'].keys(): total += sum(stats['data'][species]['Abilities'].values()) if keyify(species) == 'rayquaza': name = species try: megastats.append([name,stats['data'][species]['Moves']['dragonascent']]) except KeyError: pass else: for mega in megas: if keyify(species) == mega[0]: try: name = species if mega[1][-1] in ['x','y']: name+=' '+mega[1][-1].upper() megastats.append([name,stats['data'][species]['Items'][mega[1]]]) if mega[1][-1] != 'x': break except KeyError: if mega[1][-1] != 'x':
def analyzeTeam(team): tbias = 0 tstalliness = [] possibleTypes = False for p in team: #for stats and moveset purposes, we're now counting mega Pokemon separately. But for Team Analysis, we still want to #consider the base (this presumably breaks for hackmons, but w/e--hackmons has always been broken) poke = copy.deepcopy(p) if poke['species'].endswith('-Mega') or poke['species'].endswith('-Mega-X') or poke['species'].endswith('-Mega-Y') or poke['species'].endswith('-Primal'): poke['species'] = poke['species'][:poke['species'].index('-')] #none of the megas have hyphenated names species = keyify(poke['species']) if possibleTypes == False: possibleTypes = set(types[species]) else: possibleTypes = possibleTypes.intersection(types[species]) analysis = analyzePoke(poke) if analysis is None: return None (stalliness,bias) = analysis if species == 'meloetta' and 'relicsong' in poke['moves']: megapoke = copy.deepcopy(poke) megaspecies='meloettapirouette' stalliness += analyzePoke(megapoke)[0] stalliness /= 2.0 elif species == 'darmanitan' and poke['ability'] == 'zenmode': megapoke = copy.deepcopy(poke) megaspecies='darmanitanzen' stalliness += analyzePoke(megapoke)[0] stalliness /= 2.0 elif species == 'rayquaza' and 'dragonascent' in poke['moves']: megapoke = copy.deepcopy(poke) megaspecies='rayquazamega' megapoke['ability']='deltastream' stalliness += analyzePoke(megapoke)[0] stalliness /= 2.0 else: for mega in megas: if [species,poke['item']] == mega[:2]: megaspecies = species+'mega' if poke['item'].endswith('x'): megaspecies +='x' elif poke['item'].endswith('y'): megaspecies += 'y' if megaspecies in ['kyogremega','groudonmega']: megaspecies=megaspecies[:-4]+'primal' megapoke = copy.deepcopy(poke) megaspecies=megaspecies megapoke['ability']=mega[2] stalliness += analyzePoke(megapoke)[0] stalliness /= 2.0 break #final correction stalliness=stalliness-math.log(3,2) tbias = tbias + bias #tstalliness = tstalliness + stalliness tstalliness.append(stalliness) #team-type detection tstalliness = sum(tstalliness) / len(tstalliness) tags = [] #don't put anything before weather #rain count = 0 detected = False for poke in team: if poke['ability'] in ['drizzle','primordialsea']: detected = True break elif poke['item'] == 'damprock' and 'raindance' in poke['moves']: detected = True break elif 'raindance' in poke['moves']: count = count + 1 if count > 1: detected = True break if detected: tags.append('rain') #sun count = 0 detected = False for poke in team: if poke['ability'] in ['drought','desolateland']: detected = True break elif [species,poke['item']] == ['charizard','charizarditey']: detected = True break elif poke['item'] == 'heatrock' and 'sunnyday' in poke['moves']: detected = True break elif 'sunnyday' in poke['moves']: count += 1 if count > 1: detected = True break if detected: tags.append('sun') #sand count = 0 detected = False for poke in team: if poke['ability'] == 'sandstream': detected = True break elif poke['item'] == 'smoothrock' and 'sandstorm' in poke['moves']: detected = True break elif 'sandstorm' in poke['moves']: count = count + 1 if count > 1: detected = True break if detected: tags.append('sand') #hail count = 0 detected = False for poke in team: if poke['ability'] == 'snowwarning': detected = True break elif poke['item'] == 'icyrock' and 'hail' in poke['moves']: detected = True break elif 'hail' in poke['moves']: count += 1 if count > 1: detected = True break if detected: tags.append('hail') if len(tags) == 4: tags.append('allweather') elif len(tags) > 1: tags.append('multiweather') elif len(tags) == 0: tags.append('weatherless') #baton pass count = 0 for poke in team: if 'batonpass' in poke['moves']: if len(set(['acupressure', 'bellydrum', 'bulkup', 'coil', 'curse', 'dragondance', 'growth', 'honeclaws', 'howl', 'meditate', 'sharpen', 'shellsmash', 'shiftgear', 'swordsdance', 'workup', 'calmmind', 'chargebeam', 'fierydance', 'nastyplot', 'tailglow', 'quiverdance', 'agility', 'autotomize', 'flamecharge', 'rockpolish', 'doubleteam', 'minimize', 'substitute', 'acidarmor', 'barrier', 'cosmicpower', 'cottonguard', 'defendorder', 'defensecurl', 'harden', 'irondefense', 'stockpile', 'withdraw', 'amnesia', 'charge', 'ingrain']).intersection(poke['moves'])) != 0 or poke['ability'] in ['angerpoint', 'contrary', 'moody', 'moxie', 'speedboost']: #check for setup move/ability count += 1 if count > 1: break if count > 1: tags.append('batonpass') #tailwind count = 0 for poke in team: if 'tailwind' in poke['moves']: count += 1 if count > 1: break if count > 1: tags.append('tailwind') #trick room count = [0,0] for poke in team: if 'trickroom' in poke['moves'] and 'imprison' not in poke['moves']: count[0] += 1 elif (poke['nature'] in ['brave', 'relaxed', 'quiet', 'sassy'] or baseStats[species]['spe'] <= 50) and poke['evs']['spe'] < 5: #or I could just use actual stats and speed factor count[1] += 1 if (count[0] > 1 and count[1] > 1) or (count[0] > 2): tags.append('trickroom') if 'sun' in tags: tags.append('tricksun') if 'rain' in tags: tags.append('trickrain') if 'sand' in tags: tags.append('tricksand') if 'hail' in tags: tags.append('trickhail') #gravity count = [0,0] for poke in team: if 'gravity' in poke['moves']: count[0] += 1 if len(set(['guillotine', 'fissure', 'sheercold', 'dynamicpunch', 'inferno', 'zapcannon', 'grasswhistle', 'sing', 'supersonic', 'hypnosis', 'blizzard', 'focusblast', 'gunkshot', 'hurricane', 'smog', 'thunder', 'clamp', 'dragonrush', 'eggbomb', 'irontail', 'lovelykiss', 'magmastorm', 'megakick', 'poisonpowder', 'slam', 'sleeppowder', 'stunspore', 'sweetkiss', 'willowisp', 'crosschop', 'darkvoid', 'furyswipes', 'headsmash', 'hydropump', 'kinesis', 'psywave', 'rocktomb', 'stoneedge', 'submission', 'boneclub', 'bonerush', 'bonemerang', 'bulldoze', 'dig', 'drillrun', 'earthpower', 'earthquake', 'magnitude', 'mudbomb', 'mudshot', 'mudslap', 'sandattack', 'spikes', 'toxicspikes']).intersection(poke['moves'])) != 0: count[1] += 1 if (count[0] > 1 and count[1] > 1) or (count[0] > 2): tags.append('gravity') #voltturn count = 0 for poke in team: if len(set(['voltswitch','uturn','batonpass']).intersection(poke['moves'])) != 0 or poke['item'] == 'ejectbutton': count = count + 1 if count > 2: break if count > 2 and 'batonpass' not in tags: tags.append('voltturn') #dragmag and trapper count = [0,0] for poke in team: if poke['ability'] in ['magnetpull', 'arenatrap', 'shadowtag'] or len(set(['block','meanlook','spiderweb']).intersection(poke['moves'])) != 0: count[0] += 1 elif species in ['dratini', 'dragonair', 'bagon', 'shelgon', 'axew', 'fraxure', 'haxorus', 'druddigon', 'dragonite', 'altaria', 'salamence', 'latias', 'latios', 'rayquaza', 'gible', 'gabite', 'garchomp', 'reshiram', 'zekrom', 'kyurem', 'kyuremwhite', 'kyuremblack', 'kingdra', 'vibrava', 'flygon', 'dialga', 'palkia', 'giratina', 'giratinaorigin', 'deino', 'zweilous', 'hydreigon']: count[1] += 1 if count[0] > 0 and count[1] > 1: tags.append('dragmag') if count[0] > 2: tags.append('trapper') #F.E.A.R. count = [0,0] for poke in team: if poke['ability'] == 'magicbounce' or 'rapidspin' in poke['moves']: count[0] += 1 elif (poke['ability'] == 'sturdy' or poke['item'] == 'focussash') and 'endeavor' in poke['moves']: count[1] += 1 if count[0] > 1 and count[1] > 2: tags.append('fear') if 'sand' in tags: tags.append('sandfear') if 'hail' in tags: tags.append('hailfear') if 'trickroom' in tags: tags.append('trickfear') #choice count = 0 for poke in team: if poke['item'] in ['choiceband', 'choicescarf', 'choicespecs'] and poke['ability'] != 'klutz': count += 1 if count > 3: break if count > 3: tags.append('choice') count = 0 for poke in team: if len(set(['foulplay','swagger']).intersection(poke['moves'])) > 1: count += 1 if count > 1: break if count > 1: tags.append('swagplay') #monotype possibleTypes = list(possibleTypes) if possibleTypes: tags.append("monotype") for monotype in possibleTypes: tags.append('mono'+monotype.lower()) #stalliness stuff if tstalliness <= -1.0: tags.append('hyperoffense') if 'multiweather' not in tags and 'allweather' not in tags and 'weatherless' not in tags: if 'rain' in tags: tags.append('rainoffense') elif 'sun' in tags: tags.append('sunoffense') elif 'sand' in tags: tags.append('sandoffense') else: tags.append('hailoffense') elif tstalliness <= 0.0: tags.append('offense') elif tstalliness <= 1.0: tags.append('balance') elif tstalliness <= math.log(3.0,2.0): tags.append('semistall') else: tags.append('stall') if 'multiweather' not in tags and 'allweather' not in tags and 'weatherless' not in tags: if 'rain' in tags: tags.append('rainstall') elif 'sun' in tags: tags.append('sunstall') elif 'sand' in tags: tags.append('sandstall') else: tags.append('hailstall') return {'bias':tbias, 'stalliness': tstalliness, 'tags': tags}
#!/usr/bin/python import sys import json from TA import megas from common import keyify stats = json.load(open(sys.argv[1])) megastats = [] total = 0 for species in stats['data'].keys(): total += sum(stats['data'][species]['Abilities'].values()) if keyify(species) == 'rayquaza': name = species try: megastats.append( [name, stats['data'][species]['Moves']['dragonascent']]) except KeyError: pass else: for mega in megas: if keyify(species) == mega[0]: try: name = species if mega[1][-1] in ['x', 'y']: name += ' ' + mega[1][-1].upper() megastats.append( [name, stats['data'][species]['Items'][mega[1]]]) if mega[1][-1] != 'x': break
def main(months): file = open('keylookup.pickle') keyLookup = pickle.load(file) file.close() rise = [0.06696700846,0.04515839608,0.03406367107][len(months)-1] drop = [0.01717940145,0.02284003156,0.03406367107][len(months)-1] formatsData = getBattleFormatsData() curTiers = {} NFE=[] for poke in formatsData: if poke in ['pichuspikyeared', 'unownb', 'unownc', 'unownd', 'unowne', 'unownf', 'unowng', 'unownh', 'unowni', 'unownj', 'unownk', 'unownl', 'unownm', 'unownn', 'unowno', 'unownp', 'unownq', 'unownr', 'unowns', 'unownt', 'unownu', 'unownv', 'unownw', 'unownx', 'unowny', 'unownz', 'unownem', 'unownqm', 'burmysandy', 'burmytrash', 'cherrimsunshine', 'shelloseast', 'gastrodoneast', 'deerlingsummer', 'deerlingautumn', 'deerlingwinter', 'sawsbucksummer', 'sawsbuckautumn', 'sawsbuckwinter', 'keldeoresolution', 'genesectdouse', 'genesectburn', 'genesectshock', 'genesectchill', 'basculinbluestriped', 'darmanitanzen','keldeoresolute','pikachucosplay']: continue if 'isNonstandard' in formatsData[poke]: if formatsData[poke]['isNonstandard']: continue #if 'requiredItem' in formatsData[poke]: # continue #if poke == 'rayquazamega': # continue if 'tier' not in formatsData[poke].keys(): continue old = formatsData[poke]['tier'] if old[0] == '(': old = old[1:-1] if old in ['NFE','LC']: NFE.append(poke) if old == 'Illegal' or old == 'Unreleased': continue elif old not in tiers: old = tiers[-1] curTiers[poke]=old usage = {} #track usage across all relevant tiers [OU,UU,RU,NU] remaining=24.0 for i in xrange(len(months)): weight = remaining if i + 1 < len(months): if i == 0: weight = 20.0 if i == 1: weight = 3.0 remaining -= weight for j in xrange(len(usageTiers)): n = {} u = {} baseline = "1630" if usageTiers[j] in ['ou']: baseline = "1695" for k in ('', 'suspecttest', 'alpha', 'beta'): try: u[k], n[k] = readTable(months[i]+"/Stats/gen7"+usageTiers[j]+k+"-"+baseline+".txt") except IOError: pass ntot = sum(n.values()) for k in u: for poke in u[k]: if keyify(poke) not in usage: usage[keyify(poke)]=[0]*len(usageTiers) if poke != 'empty': usage[keyify(poke)][j] += weight*n[k]/ntot*u[k][poke]/24 #generate three-month tables and start working on that new tier list OU = [] UU = [] RU = [] NU = [] PU = [] for i in usage: if usage[i][0] > 0.0: OU.append([i,usage[i][0]]) if usage[i][1] > 0.0: UU.append([i,usage[i][1]]) if usage[i][2] > 0.0: RU.append([i,usage[i][2]]) if usage[i][3] > 0.0: NU.append([i,usage[i][3]]) if usage[i][4] > 0.0: PU.append([i,usage[i][4]]) OU = sorted(OU, key=lambda OU:-OU[1]) UU = sorted(UU, key=lambda UU:-UU[1]) RU = sorted(RU, key=lambda RU:-RU[1]) NU = sorted(NU, key=lambda NU:-NU[1]) PU = sorted(PU, key=lambda PU:-PU[1]) makeTable(OU,"OU",keyLookup) makeTable(UU,"UU",keyLookup) makeTable(RU,"RU",keyLookup) makeTable(NU,"NU",keyLookup) makeTable(PU,"PU",keyLookup) newTiers={} #start with Ubers for poke in curTiers.keys(): if curTiers[poke] == 'Uber': newTiers[poke] = 'Uber' for poke in curTiers.keys(): if poke not in usage: newTiers[poke] = curTiers[poke] #next do the OU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][0] > rise and poke not in newTiers.keys(): newTiers[poke] = 'OU' #next do the UU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'OU' and poke not in newTiers.keys(): if usage[poke][0] < drop: newTiers[poke] = 'UU' else: newTiers[poke] = 'OU' #next do BL for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'BL' and poke not in newTiers.keys(): newTiers[poke] = 'BL' #next do the UU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][1] > rise and poke not in newTiers.keys(): newTiers[poke] = 'UU' #next do the RU drops for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'UU' and poke not in newTiers.keys(): if usage[poke][1] < drop: newTiers[poke] = 'RU' else: newTiers[poke] = 'UU' #next do BL2 for poke in curTiers.keys(): if poke not in usage: continue if curTiers[poke] == 'BL2' and poke not in newTiers.keys(): newTiers[poke] = 'BL2' #next do the RU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][2] > rise and poke not in newTiers.keys(): newTiers[poke] = 'RU' #next do the NU drops for poke in curTiers.keys(): if curTiers[poke] == 'RU' and poke not in newTiers.keys(): if usage[poke][2] < drop: newTiers[poke] = 'NU' else: newTiers[poke] = 'RU' #next do BL3 for poke in curTiers.keys(): if curTiers[poke] == 'BL3' and poke not in newTiers.keys(): newTiers[poke] = 'BL3' #next do the NU rises for poke in curTiers.keys(): if poke not in usage: continue if usage[poke][3] > rise and poke not in newTiers.keys(): newTiers[poke] = 'NU' #next do the PU drops for poke in curTiers.keys(): if curTiers[poke] == 'NU' and poke not in newTiers.keys(): if usage[poke][3] < drop: newTiers[poke] = 'PU' else: newTiers[poke] = 'NU' #next do BL4 for poke in curTiers.keys(): if curTiers[poke] == 'BL4' and poke not in newTiers.keys(): newTiers[poke] = 'BL4' #the rest go in the lowest tier for poke in curTiers.keys(): if poke not in newTiers.keys(): newTiers[poke] = tiers[-1] print "" for poke in curTiers: if curTiers[poke] != newTiers[poke]: species = keyLookup[poke] if species.endswith('-Mega') or species.endswith('-Mega-X') or species.endswith('-Mega-Y') or species.endswith('-Primal'): base = keyify(species[:species.index('-')]) #none of the megas have hyphenated names if tiers.index(newTiers[base]) < tiers.index(newTiers[poke]): #if the base is in a higher tier newTiers[poke] = newTiers[base] continue print species+" moved from "+curTiers[poke]+" to "+newTiers[poke]