<< Back to Ladder Forum   Search

Posts 1 - 20 of 24   1  2  Next >>   
Ladder wins by colour?: 2016-05-15 15:13:19


Ox
Level 58
Report
Hey, Fizzer, or anyone who can access this data, I found this old thread and it seemed quite interesting.

https://www.warlight.net/Forum/5071-ladder-wins-color

Turns out in 2012, Deep Pink was the strongest, and Electric Purple was the weakest.

Any chance there can be an updated 2016 version ? ^^
Ladder wins by colour?: 2016-05-15 19:20:09


Onoma94
Level 61
Report
Wow... I have the weakest colour :(
Ladder wins by colour?: 2016-05-15 19:23:15


Genghis 
Level 54
Report
I suspect there might be a psychological aspect to the colors, in the sense that Blue instills Patience, Strategic thinking, and Red encourages Action and Short-term thought.
Ladder wins by colour?: 2016-05-15 19:39:50


Zephyrum
Level 60
Report
Deep Pink Master Race confirmed!!!
Ladder wins by colour?: 2016-05-15 19:40:24


Perrin3088 
Level 49
Report
me and my former color *back when the first list was made* had picked our colors cause we hated having to repick.. it just so happened we had the 2nd and lowest when the thread came out, lol
Ladder wins by colour?: 2016-05-15 20:19:10


MightySpeck (a Koala) 
Level 60
Report
you could just look at like the past 1000 games or something and record the colors. you could also make a bot to do it but that might take some work.

but looking at 1000 games would be a lot of work too.

Edited 5/15/2016 20:19:29
Ladder wins by colour?: 2016-05-15 20:41:54


knyte
Level 55
Report
Anyone know a good way to just convert the color hex RGB values (that show up in query game API output) to their actual names?

Nvm found a place: https://www.warlight.net/wiki/Player_colors

Edited 5/15/2016 20:44:51
Ladder wins by colour?: 2016-05-15 20:42:05


Ox
Level 58
Report
Yeah, yellow did pretty badly :(
Ladder wins by colour?: 2016-05-15 20:44:53

[wolf]japan77
Level 57
Report
@knyte, if you know the how they correspond, it should be doable. As such probably check the primary and secondary color selection page, and use its outputs?(They should align)
Ladder wins by colour?: 2016-05-15 20:46:26


knyte
Level 55
Report
so yeah now we have to just wait a while unless someone's faster than me here; currently 400/155940 games through.
Ladder wins by colour?: 2016-05-15 20:49:48

[wolf]japan77
Level 57
Report
Not me, I still haven't done any programming involving using networks.
Ladder wins by colour?: 2016-05-15 20:54:18


Ox
Level 58
Report
oh this is great. thanks a bunch btw :D looking forward to it!
Ladder wins by colour?: 2016-05-15 21:05:01


l4v.r0v 
Level 59
Report
currently 2700 games in- so that's 2200 games in about 20 minutes

At this rate, the whole ladder analysis should take ~1400 minutes- just about a whole day- on my system. There's at least a few ways to make things go faster, though.


import requests
import string

class APIError(Exception):
    """
    Error class that should simply output errors
    raised by the Warlight API itself
    """
    pass

class ServerGameKeyNotFound(Exception):
    """
    Error class for nonexistent games
    """

def getNextID(ID):
    """
    Given an ID, returns the next ID
    """
    lastChar = ID[-1]
    mainID = ID[:(len(ID) - 1)]
    if (lastChar == "Z"): newEnd = "AA"
    else: newEnd = chr(ord(lastChar) + 1)
    return (mainID + newEnd)

def canBeTeamless(teams, allowTeamless=True):
    """
    Helper function to determine whether a game can be teamless
    """
    return ((allowTeamless is True) and ([team for team in teams 
            if (isinstance(team, tuple))] == list()))

def makePlayers(teams, allowTeamless=False):
    """
    Given teams, returns a list
    containing player dictionaries
    PARAMETERS:
    teams: list of teams as tuples of player IDs
    OPTIONAL:
    teamless: bool (default False); if set to True,
              a teamless result will be returned if possible
    """
    teamless = canBeTeamless(teams, allowTeamless)
    teamID = 0
    players = list()
    for team in teams:
        if (teamless):
            player = dict()
            player['token'] = str(team)
            player['team'] = str(None)
            players.append(player)
        elif (type(team) == list) or (type(team) == tuple):
            for member in team:
                player = dict()
                player['token'] = str(member)
                player['team'] = str(teamID)
                players.append(player)
        else:
            player = dict()
            player['token'] = str(team)
            player['team'] = str(teamID)
            players.append(player)
        teamID += 1
    return players

def overrideBonuses(bonuses):
    """
    Given a list containing tuples
    with bonus name and new values,
    generates new list with said data
    in dictionary form
    """
    overridenBonuses = list()
    for bonus in bonuses:
        bonusData = dict()
        bonusData['bonusName'] = bonus[0]
        bonusData['value'] = bonus[1]
        overridenBonuses.append(bonusData)
    return overridenBonuses

def getAPIToken(email, password):
    """
    Gets API token using email and password
    """
    site = "https://www.warlight.net/API/GetAPIToken"
    data = dict()
    data['Email'] = email
    data['Password'] = password
    r = requests.post(url=site, params=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])
    return jsonOutput['APIToken']

def queryGame(email, token, gameID, getHistory=False):
    """
    Queries a game given gameID
    using credentials (email+token)
    returns JSON output
    """
    getHistory = str(getHistory).lower()
    site = "https://www.warlight.net/API/GameFeed"
    data = dict()
    data['Email'] = email
    data['APIToken'] = token
    data['GameID'] = str(gameID)
    data['GetHistory'] = getHistory
    r = requests.post(url=site, params=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        if ("ServerGameKeyNotFound" in jsonOutput['error']):
            raise ServerGameKeyNotFound(jsonOutput['error'])
        raise APIError(jsonOutput['error'])
    return jsonOutput

def createGame(email, token, **settings):
    """
    Creates a game given settings
    using credentials (email+token)
    returns game ID
    """
    site = "https://www.warlight.net/API/CreateGame"
    data = dict()
    data['hostEmail'] = email
    data['hostAPIToken'] = str(token)
    data['templateID'] = settings.get('template')
    data['gameName'] = settings.get('gameName')
    data['personalMessage'] = settings.get('message', "")
    teams = settings.get('teams')
    data['players'] = makePlayers(teams)
    if 'overriddenBonuses' in settings:
        data['overridenBonuses'] = \
        overrideBonuses(settings.get('overridenBonuses'))
    r = requests.post(url=site, json=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])
    return jsonOutput['gameID']

def deleteGame(email, token, gameID):
    """
    Deletes a game
    using credentials (email+token)
    does not return anything
    """
    site = "https://www.warlight.net/API/DeleteLobbyGame"
    data = dict()
    data['Email'] = email
    data['APIToken'] = str(token)
    data['gameID'] = int(gameID)
    r = requests.post(url=site, json=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])
    if 'success' not in jsonOutput:
        raise APIError("Unknown error!")

def getGameIDs(email, token, *source):
    """
    Gets a list of games for a ladder/tournament
    using credentials (email+token)
    returns list of games
    """
    site = "https://www.warlight.net/API/GameIDFeed"
    data = dict()
    data['Email'] = email
    data['APIToken'] = token
    try:
        assert(len(source) == 2)
    except:
        raise TypeError("Need both source type and ID!")
    if ("ladder" in source) or ("Ladder" in source):
        data['LadderID'] = int(source[-1])
    elif ("tournament" in source) or ("Tournament" in source):
        data['TournamentID'] = int(source[-1])
    else:
        raise IOError("Source type must be either ladder or tournament!")
    r = requests.post(url=site, params=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])
    return jsonOutput['gameIDs']

def validateToken(email, token, player, *templates):
    """
    Validtes an inviteToken
    using credentials (email+token)
    returns response
    """
    site = "https://www.warlight.net/API/ValidateInviteToken"
    data = dict()
    data['Email'] = email
    data['APIToken'] = token
    data['Token'] = player
    if templates is not tuple():
        data['TemplateIDs'] = string.join(templates, ",")
    r = requests.post(url=site, params=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])
    return jsonOutput

def setMapDetails(email, token, mapID, *commands):
    """
    Sets map details
    using credentials (email+token)
    and command setup (commandtype, dict())
    """
    site = "https://www.warlight.net/API/SetMapDetails"
    data = dict()
    data['email'] = email
    data['APIToken'] = token
    data['mapID'] = str(mapID)
    commandData = list()
    for command in commands:
        order = dict()
        order['command'] = command[0]
        for item in command[1]:
            order[item] = command[item]
        commands.append(order)
    data['commands'] = commandData
    r = requests.post(url=site, json=data)
    jsonOutput = r.json()
    if 'error' in jsonOutput:
        raise APIError(jsonOutput['error'])


^ Here's a (pretty insecure) wrapper library for the Warlight API in Python


from api import *
import getpass
from decimal import Decimal

requests.packages.urllib3.disable_warnings()
# if you're not using Python 2.7.9, this just silences the InsecurePlatformWarning

def getWinningColor(email, token, gameID):
    queryData = queryGame(email, token, gameID)
    for player in queryData['players']:
        if player['state'] == 'Won':
            return player['color']

if __name__ == "__main__":
    # get credentials
    email = raw_input("e-mail: ")
    password = getpass.getpass()
    token = getAPIToken(email, password)

    # get 1v1 ladder games
    ladder_1vs1 = getGameIDs(email, token, "ladder", 0)

    # global variables for storing wins
    totalWins = 0
    colorWins = dict()

    for game in ladder_1vs1:
        winningColor = getWinningColor(email, token, game)
        if winningColor is None: # no winner
            continue
        totalWins += 1
        if winningColor not in colorWins:
            colorWins[winningColor] = 0
        colorWins[winningColor] += 1

    colorWinsList = list()

    for color in colorWins:
        winPercent = round(Decimal(100) * Decimal(colorWins[color]) / Decimal(totalWins), 2)
        colorWinsList.append((color, winPercent))

    colorWinsList = sorted(colorWinsList, key=lambda x: x[1]) # sort by win percent
    colorWinsList.reverse()

    for dataPoint in colorWinsList:
        print (str(dataPoint[0]) + ": " str(dataPoint[1]) + "% of total wins")



^ just save the top code as api.py, save the bottom code in the same folder, and run the bottom code

You can add a bunch of optimizations to make it run faster (like not running everything on a single thread), plus odds are your system + network connection are both faster than mine.

Edited 5/16/2016 18:41:58
Ladder wins by colour?: 2016-05-15 21:44:25

[wolf]japan77
Level 57
Report
Interesting. Also its highly unlikely that my machine is faster than yours, its a chromebook with 2GBs of ram( and yes, I'm running linux on it).
Also, why are you doing it on a single thread?
Ladder wins by colour?: 2016-05-15 22:15:25


l4v.r0v 
Level 59
Report
1. It'd be slightly less trivial to write if I added in meaningful optimizations

2. Connection sucks and I don't want to make a shitton of server calls in a shot span of time
Ladder wins by colour?: 2016-05-15 22:30:15


Master Shredtail
Level 58
Report
I might be able to run it fast. If you need specs or details, mail me.
Ladder wins by colour?: 2016-05-16 15:06:40


knyte
Level 55
Report
105,700 games in now.
Ladder wins by colour?: 2016-05-17 05:54:44


knyte
Level 55
Report
lel so it looks like I misread the thing and tracked the wrong data; was wondering why anyone would want to know what % of wins came from players with a certain color

but then again ladder win % rates are worthless anyway too

whoops T_T

Blue: 10.6% of total wins
Red: 10.56% of total wins
Green: 7.5% of total wins
Dark Gray: 7.46% of total wins
Dark Green: 6.17% of total wins
Yellow: 5.31% of total wins
Purple: 5.06% of total wins
Aqua: 4.82% of total wins
Orange: 4.51% of total wins
Teal: 3.75% of total wins
Dark Magenta: 3.47% of total wins
Orange Red: 3.42% of total wins
Electric Purple: 3.4% of total wins
Light Blue: 3.38% of total wins
Ivory: 3.0% of total wins
Lime: 2.65% of total wins
Deep Pink: 2.5% of total wins
Tan: 2.39% of total wins
Sea Green: 2.17% of total wins
Orchid: 1.89% of total wins
Brown: 1.64% of total wins
Saddle Brown: 1.55% of total wins
Copper Rose: 1.48% of total wins
Hot Pink: 1.3% of total wins
Goldenrod: 0.01% of total wins
Mardi Gras: <0.01% of total wins
Artichoke: <0.01% of total wins
Tyrian Purple: <0.01% of total wins
Cyan: <0.01% of total wins
Royal Blue: <0.01% of total wins
Apple Green: <0.01% of total wins
Rain Forest: <0.01% of total wins


So it looks like no one's won as Peach, Mahogany, Pink Lace, Bronze, Wood Brown, or Tuscany yet. At least that's interesting? idk

I'll just query and save the entire ladder now so I can do interesting stuff without having to make 150k+ API calls again.
Ladder wins by colour?: 2016-05-17 06:22:29


Krzysztof 
Level 67
Report
So it looks like no one's won as Peach, Mahogany, Pink Lace, Bronze, Wood Brown, or Tuscany yet. At least that's interesting?

Not really ;) It's now required to choose your first and second color from "base" colors so it's not very likely that anyone will win as one of color mentioned above :P
Ladder wins by colour?: 2016-05-17 06:33:55

[wolf]japan77
Level 57
Report
I mean you can pull that unique trick to grab those colors as secondary.
Posts 1 - 20 of 24   1  2  Next >>