Home - Trials - Strategies - Register

Trust Trials

Trust Trials is a game based on the prisoner's dilemma, or more specifically the iterated prisoner's dilemma. In this game, you provide a strategy that the game server places in matchups against other strategies. The strategy you provide is an API and can be written in any language as long as it responds per the specification. It can be hosted anywhere as long as it responds within the defined SLA.

The Game Theory

The Prisoner's Dilemma

The prisoner's dilemma is a game theory scenario where two individuals must choose to cooperate or betray each other without knowing the other's choice. The outcomes are:

Despite better collective outcomes from cooperation, rational self-interest often leads both to betray.

Iterated Prisoner's Dilemma

The iterated prisoner's dilemma involves repeated rounds of the prisoner's dilemma. Players remember previous interactions and adjust their strategies. Cooperation can emerge over time as players reward cooperation and punish betrayal, leading to long-term stable strategies.

How to Play

The Rules

  1. The game server will run a trial every 4 hours.
  2. At the beginning of each trial, every strategy needs to respond to a health check within 1000ms. The only valid response for the health check is I'm alive!.
  3. Strategies that pass the health check will be randomly paired for matchups with other strategies. If there is an odd number of strategies, one strategy will be matched up twice.
  4. Each matchup will consist of a random number of rounds between 100 and 150.
  5. During a matchup, the only valid responses are Cooperate, Defect, or Bye!. Bye! is only valid when the game server indicates the game is over.
  6. During a matchup, a strategy must respond within 1000ms on the first round and 500ms on every subsequent round.
  7. On every round, the game server will provide the ID of the opposing strategy. From the second round onwards, the game server will also provide the opposing strategy's last decision.
  8. If a strategy fails to answer correctly during any matchup or exceeds the SLA, the matchup is defaulted, and the scores are not counted towards either strategy's average scores.
  9. If a strategy has 8 exceptions (failing a health check or failing to answer correctly during a matchup) in the past 10 days, it is dropped from future trials.
  10. Every trial, there is a 5% chance that the poorest performing strategy, which has been in at least 40 matchups, will be dropped.

The API

Strategies must be able to respond to 5 types of messages.

  1. Health Check:
    Message: It's a-me, Mario!
    Response Time: Within 1000ms
    Valid Response: I'm alive!

  2. First Round of Matchup:
    Message: Let's-a go, little guys!
    Response Time: Within 1000ms
    Valid Responses: Cooperate or Defect

  3. Subsequent Rounds of Matchup:
    Message: Mama Mia!
    Response Time: Within 500ms
    Valid Responses: Cooperate or Defect

  4. Last Round:
    Message: Mario time!
    Response Time: Within 500ms
    Valid Responses: Cooperate or Defect

  5. End of Matchup:
    Message: Thanks for playing! Way to go!
    Response Time: Within 500ms
    Valid Response: Bye!

Request Structure

Every request made by the game server is an HTTP POST request. The payload always has the following structure:

{
    "secret_key": "secret_key",
    "message": "message",
    "opponent": {
        "id" : "opponent_id",
        "last_decision": "opponent_last_decision"
    }
}

Response Structure

Every response to the game server should be a valid JSON string. Note that a JSON string is encapsulated in quotes!

"your_response"

Full Request

This is an full request and response as conducted through Postman.

Request Headers
    Content-Type: application/json
    User-Agent: PostmanRuntime/7.39.0
    Accept: */*
    Postman-Token: f95f9489-f6df-4679-83c2-7ce726bb0a85
    Host: XXXXXXX.execute-api.us-west-2.amazonaws.com
    Accept-Encoding: gzip, deflate, br
    Connection: keep-alive
    Content-Length: 165
Request Body
    {
        "secret_key": "XXXXXXX",
        "message": "It's a-me, Mario!",
        "opponent": {
            "id" : null,
            "last_decision": null
        }
    }
Response Headers
    Date: Sat, 01 Jun 2024 01:36:46 GMT
    Content-Type: text/plain; charset=utf-8
    Content-Length: 12
    Connection: keep-alive
    Apigw-Requestid: YqgvTjYFPHcEMPA=
Response Body
    "I'm alive!"

Creating a Basic Strategy Using AWS

In this section, we will guide you through creating a basic strategy for the game using AWS services. We will use AWS Lambda to run the strategy code and API Gateway to handle the HTTP requests. The example strategy we'll create is called "TitForTat," which is one of the strategies preloaded into the game. This setup should fit within the AWS Free Tier, meaning there should be no cost, but you should always verify costs on your own.

Prerequisites

Before you begin, ensure you have the following:

Follow these steps to set up your strategy:

Step 1: Create a Lambda Function

  1. Navigate to AWS Lambda: Go to the AWS Management Console and open the Lambda service. You can follow the detailed instructions here.

  2. Create a New Lambda Function:

    a. Choose "Create function".
    b. Select "Author from scratch".
    c. Name your function (e.g., TitForTatStrategy).
    d. Choose Python as the runtime.
    e. Choose "Create Function".

  3. Example Code:

    import json
    
    secret_key = "XXXXXXX"
    
    def validate_request(body):
        required_fields = ["secret_key", "message", "opponent"]
        opponent_fields = ["id", "last_decision"]
    
        if any(field not in body for field in required_fields):
            return 400, "Malformed request."
    
        if any(field not in body["opponent"] for field in opponent_fields):
            return 400, "Malformed request."
    
        if body["secret_key"] != secret_key:
            return 401, "Unauthorized"
    
        return None, None
    
    def process_message(body):
        match body["message"]:
            case "It's a-me, Mario!":
                return 200, "I'm alive!"
    
            case "Let's-a go, little guys!":
                return 200, "Cooperate"
    
            case "Mama Mia!":
                match body["opponent"]["last_decision"]:
                    case "Cooperate":
                        return 200, "Cooperate"
                    case "Defect":
                        return 200, "Defect"
                    case _:
                        return 400, "Invalid last_decision"
    
            case "Mario time!":
                match body["opponent"]["last_decision"]:
                    case "Cooperate":
                        return 200, "Cooperate"
                    case "Defect":
                        return 200, "Defect"
                    case _:
                        return 400, "Invalid last_decision"
    
            case "Thanks for playing! Way to go!":
                return 200, "Bye!"
    
            case _:
                return 400, "Invalid message."
    
    def lambda_handler(event, context):
        body = json.loads(event["body"])
    
        status_code, response = validate_request(body)
        if status_code:
            return {
                'statusCode': status_code,
                'body': json.dumps(response)
            }
    
        status_code, response = process_message(body)
        return {
            'statusCode': status_code,
            'body': json.dumps(response)
        }

Step 2: Set Up API Gateway

Based on the instructions for "Create an HTTP API by using the AWS Management Console" here.

  1. Navigate to the API Gateway Console: https://console.aws.amazon.com/apigateway/main/apis
  2. Choose "Create API".
  3. Click "Build for "HTTP API".
  4. Choose "Add integration".
  5. From the dropdown, choose "Lambda".
  6. For "Lambda function", chose the one that correlates to the Lambda you created in Step 1.
  7. Name API name (e.g., myStrategies).
  8. Choose "Review and Create".
  9. Review the listed details and choose "Create".
  10. You should now see a screen showing the routes for your API "myStrategies". The only listed route should be for the Lambda function you related to this API, e.g., "/TitForTatStrategy".
  11. Make note of this route name, as you will need it for the API URL.

Step 3: Get the API URL

Now we will get the API URL that you can use to register your strategy for Trust Trials.

  1. Picking up from where you left off in Step 2, choose "Stages" from the navigation menu.
  2. You should see a single stage, "$default". Select it.
  3. Make note of the "Invoke URL", e.g., "https://XXXXXXX.execute-api.us-west-2.amazonaws.com".
  4. Append the route name from Step 2 to this URL and you'll have the full API URL, e.g., "https://XXXXXXX.execute-api.us-west-2.amazonaws.com/TitForTatStrategy".

Step 4: Test Your API

You can test your API using tools like Postman.

Once you register on the site, you will be provided with a secret_key. Update your Lambda function with this key as soon as possible to avoid any failed calls from the game server.