Name Average Performance Finished Rounds Draw
All
Total

A Quick Start on The Retailer Robot Mode

Last updated: Feb 22nd, 2017

Introduction

Feeling tired of playing The Retailer Game manually? If you have some knowledge in programming, you can attempt the competitions programmatically. You can also explore the patterns and deduce the best algorithm to solve the competitions.

APIs

Before you proceed

Make sure you understand some basic knowledge like (url, request and response, status code, JSON and etc.) before you proceed, or you will have issues understanding the following sections.

You need to get your Student Key on student page before your send any request to the server.

Get your Competition Data

You can request your competition data simply by POSTing the following JSON data
{
    competition_id: "TEST1", //competition ID you are requesting
    studentEmail: "test@gmail.com", //Your email
    studentKey: "KEY" //The key you got from the student page
}
To this URL:

http://retailer2.net/api/clientCompetitionData

If you haven't attempted this competition, the server will return the following JSON data for your reference
{
status: 0, //Indicating you are doing right, if any error occurs, this will equal to 1 instead
data: {
    competition_id: "TEST1", //competition ID you are requesting
    totalRounds: 5, //Total number of rounds this competition have
    isRobot: true, //Indicate this is a robot competition
    isStarted: false //You hence need to call the startCompetition API
    }
}
If you have attempted this competition, the server will return the following JSON data showing your performance (even partially completed competitions will be shown here)
{
status: 0,
data: {
    competition_id: "TEST1", //competition ID you are requesting
    totalRounds: 5, //Total number of rounds this competition have
    currentRound: 2, //Current round you are now attempting
    isCompleted: false, //This competition is not done yet
    isView: true, //You are viewing data, not posting price actions
    isRobot: true, //Indicate this is a robot competition
    isStarted: true, //You have started the competition
    clientRoundDataArr:
        [
            {
                optimal: 109771, //the optimal revenue
                revenue: 101940 //the revenue you earn
            }
        ]
    }
}

Useful Tip:

optimal and revenue are only shown when you have completed that round, i.e. isCompleted == true

Get your Round Data

The Competition Data API is only useful when you want to know your overall performance, like when you are generating a performance summary report. Usually you need only focus on the data of one round.

You can get the Round Data of the current round you are attempting by POSTing the following JSON data:
{
    competition_id: "TEST1", //competition ID you are requesting
    studentEmail: "test@gmail.com", //Your email
    studentKey: "KEY", //The key you got from the student page
}
You can get the Round Data of any round number (the server will return your current attempting round if you never attempted the round you are requesting) by POSTing the following JSON data:
{
    competition_id: "TEST1", //competition ID you are requesting
    studentEmail: "test@gmail.com", //Your email
    studentKey: "KEY", //The key you got from the student page
    round: 0 //The round number you are requesting
}
To this URL:

http://retailer2.net/api/clientRoundData

And the server will return:
{
status: 0,
data: {
    competition_id: "TEST1", //competition ID you are requesting
    totalRounds: 5, //Total number of rounds this competition have
    currentRound: 0, //Current round you are now attempting
    displayedRound: 0, //The round number you specified in your request
    isCompleted: false,
    isRobot: true,
    isStarted: true,
    clientRoundData:
        {
            isCompleted: false,
            priceActions: [0],
            weeks:
            [
                {
                    price: 60,
                    sales: 105,
                    revenue: 6300,
                    inventory: 1895 //Inventory left at the end of the week
                }
            ]
        }
    }
}

Start the competition

Robot mode does not allow you to POST price actions unless you call this API first

POST your Start Competition command in the format of the following
{
    competition_id: "TEST1", //competition ID you are requesting
    studentEmail: "test@gmail.com", //Your email
    studentKey: "KEY", //The key you got from the student page
}
To this URL:

http://retailer2.net/api/competitionRoundPriceAction

The server will return the Round Data after starting your competition (Equivalent to a price action of Full Price):
{
status: 0,
data: {
    competition_id: "TEST1", //competition ID you are requesting
    totalRounds: 5, //Total number of rounds this competition have
    currentRound: 0, //Current round you are now attempting
    displayedRound: 0, //The round number you specified in your request
    isRobot: True,
    isStarted: True,
    clientRoundData:
        {
            isCompleted: false,
            priceActions: [0],
            weeks:
            [
                {
                    price: 60,
                    sales: 105,
                    revenue: 6300,
                    inventory: 1895 //Inventory left at the end of the week
                }
            ]
        }
    }
}

POST your Price Action

After you started your competition, you can now post Price Actions

Price Action format
  • 0 refers to Full Price
  • 1 refers to -10%
  • 2 refers to -20%
  • 3 refers to -40%
  • Of course price cannot increase, and the server will not accept your illegal request
You can POST your Price Action in the format of the following
{
    competition_id: "TEST1", //competition ID you are requesting
    studentEmail: "test@gmail.com", //Your email
    studentKey: "KEY", //The key you got from the student page
    priceAction: 2
}
To this URL:

http://retailer2.net/api/competitionRoundPriceAction

The server will return the Round Data after applying your Price Action:
{
status: 0,
data: {
    competition_id: "TEST1", //competition ID you are requesting
    totalRounds: 5, //Total number of rounds this competition have
    currentRound: 0, //Current round you are now attempting
    displayedRound: 0, //The round number you specified in your request
    isRobot: True,
    isStarted: True,
    clientRoundData:
        {
            isCompleted: false,
            priceActions: [0, 2],
            weeks:
            [
                {
                    price: 60,
                    sales: 105,
                    revenue: 6300,
                    inventory: 1895 //Inventory left at the end of the week
                },
                {
                    price: 48,
                    sales: 222,
                    revenue: 10656,
                    inventory: 1421 //Inventory left at the end of the week
                }
            ]
        }
    }
}

How to start a new round

You can start a new round by simply POSTing a Price Action after you finished the previous round (or at the start of a competition you never attempted before), no rocket science involved here.

First Price Action in each round is default to 0

At the moment, The Retailer Game limit your first week Price Action to Full Price, no matter what you actually POST.

Price Action is auto-filled by the server if your round is terminated before week 16

For example, if you POST a Price Action equals to 3, the round will end immediately with the completed Round Data returned to you.

No More Price Action after you finished all rounds in the competition

The server will return an error message telling you the competition has already finished if you insist in POSTing more Price Actions. Of course if you are lazy counting how many rounds you have attempted, simply use this message as an ending signal.

Error Handling

If any error occurs, you will receive a response with status = 1 and the error message:
{
    status: 1, //Indicating an error
    error: "Wrong key", //Indicating your student key does not match our record
}

Sample Code

Python (CPython 3.5) Code Example
from urllib.parse import urlencode
from urllib.request import Request, urlopen
from urllib.error import HTTPError
import json

host = 'http://retailer2.net'
studentEmail = "test@gmail.com"
studentKey = "KEY"
competition_id = "TEST"


def postPriceAction(priceAction):
    url = host + '/api/competitionRoundPriceAction'
    req = {
        'studentEmail': studentEmail,
        'studentKey': studentKey,
        'competition_id': competition_id,
        'priceAction': priceAction
    }
    request = Request(url, urlencode(req).encode())
    try:
        res = urlopen(request).read().decode('utf-8')
        json_object = json.loads(res)
    except HTTPError as err:
        json_object = json.loads(err.read().decode('utf-8'))
    return json_object


def getRoundData():
    url = host + '/api/clientRoundData'
    req = {
        'studentEmail': studentEmail,
        'studentKey': studentKey,
        'competition_id': competition_id,
    }
    request = Request(url, urlencode(req).encode())
    try:
        res = urlopen(request).read().decode('utf-8')
        json_object = json.loads(res)
    except HTTPError as err:
        json_object = json.loads(err.read().decode('utf-8'))
    return json_object


def getCompetitionData():
    url = host + '/api/clientCompetitionData'
    req = {
        'studentEmail': studentEmail,
        'studentKey': studentKey,
        'competition_id': competition_id,
    }
    request = Request(url, urlencode(req).encode())
    try:
        res = urlopen(request).read().decode('utf-8')
        json_object = json.loads(res)
    except HTTPError as err:
        json_object = json.loads(err.read().decode('utf-8'))
    return json_object


def startCompetition():
    url = host + '/api/startCompetition'
    req = {
        'studentEmail': studentEmail,
        'studentKey': studentKey,
        'competition_id': competition_id,
    }
    request = Request(url, urlencode(req).encode())
    try:
        res = urlopen(request).read().decode('utf-8')
        json_object = json.loads(res)
    except HTTPError as err:
        json_object = json.loads(err.read().decode('utf-8'))
    return json_object


def main():
    competition_data = getCompetitionData()
    print(competition_data)
    if competition_data['data']['isStarted']:
        round_data = getRoundData()
    else:
        round_data = startCompetition()
    print(round_data)
    price_action = 0  # Decide your first price action
    while round_data['status'] != 1:
        round_data = postPriceAction(price_action)
        print(round_data)
        price_action = 0  # Decide your following price strategy
    print(getCompetitionData())

if __name__ == "__main__":
    main()