How to find where my (or my enemy's) information units scored?

So I am going to ask a very, very, dumb, question. How would you go about doing stuff with the state? What would you say to get the results, If the function gets called every frame, won’t it override the previous string? I want to get information on where enemy units breached but what would I put there to find it? Similarly, Where can I find where enemy units and firewalls are placed? Looking above they say to “look into” the game_state_string or something. How would I exactly do that, and how would I Implement that into my code?

The result of

state = json.loads(game_state) 

is that state is now a python dictionary object.
Info on what this is and how to read it here:
https://docs.python.org/3.6/tutorial/datastructures.html#dictionaries

This object will, on each frame, contain the complete state of the units on the board, as well as helpfully including specific information about important events, such as units being spawned, units breaching a player’s edges, etc.

The keys and information hierarchy of this dictionary is (incredibly helpfully!!!) analyzed in complete detail in this thread:

Even though it talks about replays, its really talking about how to get info from the game state strings, since the replay is just a whole bunch of those strings stuffed into a file.

Each frame DOES overwrite the previous value, so you will have to add logic in your on_action function to look at each frame’s dictionary and save the data you want immediately, before the end of the on_action function.

1 Like

so the dictionary state = json.loads(game_state)

means that information can be called from that dictionary. and If I asked for information I do
state[information]
but why does people keep referencing “breach”? the only word breach is in tests.py and I have not looked at engine.jar because it is too slow to open and scroll in
the tests.py line is
turn_0 = """{"p2Units":[[],[],[],[],[],[],[]],"turnInfo":[0,0,-1],"p1Stats":[30.0,25.0,5.0,0],"p1Units":[[],[],[],[],[],[],[]],"p2Stats":[30.0,25.0,5.0,0],"events":{"selfDestruct":[],"breach":[],"damage":[],"shield":[],"move":[],"spawn":[],"death":[],"attack":[],"melee":[]}}"""

I do not know how to decode that.
Could someone explain this to me?

Ok, lets look at that string. That is, in fact, what a game_state_string looks like. This gets turned into a line of python.

First of all, the way to declare a dictionary is using curly brackets. For example:

turn = { "key1":[contents1], "key2":[contents2] }

Is a dictionary with two keys, which are strings “key1” and “key2”, and calling on each key returns a list. So:

list1 = turn["key1"]

Will set list1 equal to the [contents1] list.
As it happens, dictionaries can hold all sorts of things, including other dictionaries!
This is how the game state string is arranged. So now lets look at what you pasted, using the same notation:

 turn_0 = { "p2Units":[[],[],[],[],[],[],[]], "turnInfo":[0,0,-1], "p1Stats":[30.0,25.0,5.0,0], "p1Units":[[],[],[],[],[],[], 
 []], "p2Stats":[30.0,25.0,5.0,0], "events":{"selfDestruct":[], "breach":[], "damage":[], "shield":[], "move":[], 
  "spawn":[], "death":[], "attack":[], "melee":[] } }

turn_0 is a dictionary with the following keys:
“p2units”
“turnInfo”
“p1Stats”
“p1Units”
“p2Stats”
“events”

For each of the key-object pairs separated by a colon, setting something equal to turn_0[“key”] will set it equal to whatever came after the colon. Many of these are complicated nested lists-of-lists-of-mysterious-numbers, and that thread in which it all gets decoded will tell you exactly what means what.
But the most complicated key is the “events” key, because that returns another dictionary! And this dictionary looks like this:

  {"selfDestruct":[], "breach":[], "damage":[], "shield":[], "move":[], "spawn":[], "death":[], "attack":[], "melee":[] }

Hopefully it’s clear now what keys this dictionary contains. Each key will return a list of lists, and the numbers in those lists will tell you about each event. These events don’t happen every action frame, so most of the time these lists are empty. Now, suppose you did something like this:

where_I_got_hit = turn_0["events"]["breach"]

Now you have a list of lists, and each sub-list contains the coordinates and information about where enemy units hit your edges. You will have to check every action frame to find the one where this list is not empty; if there are no sub-lists, that event type did not happen during that particular frame.

2 Likes

So what I would do to save only the frames of when I got breached is I do in AlgoStrategy:

def on_action(self, game_state):
    state = json.loads(game_state)
    if state["events"]["breach"] != [] """would that work""":
        # I just append a list right?

And how would I get that variable too?
Do I just put in my if statement if (state["events"]["breach"] == thingy):
And would this mean that after each frame, this function gets called because of what I did before in AlgoCore?
And is the empty list filled with a list of [x, y] or something else?

Also why did everyone take alot of time into finding out the numbers for each unit? Isn’t there a big thing right under the global variables that tell you everything already?

    FILTER = config["unitInformation"][0]["shorthand"]
    UNIT_TYPE_TO_INDEX[FILTER] = 0
    ENCRYPTOR = config["unitInformation"][1]["shorthand"]
    UNIT_TYPE_TO_INDEX[ENCRYPTOR] = 1
    DESTRUCTOR = config["unitInformation"][2]["shorthand"]
    UNIT_TYPE_TO_INDEX[DESTRUCTOR] = 2
    PING = config["unitInformation"][3]["shorthand"]
    UNIT_TYPE_TO_INDEX[PING] = 3
    EMP = config["unitInformation"][4]["shorthand"]
    UNIT_TYPE_TO_INDEX[EMP] = 4
    SCRAMBLER = config["unitInformation"][5]["shorthand"]
    UNIT_TYPE_TO_INDEX[SCRAMBLER] = 5
    REMOVE = config["unitInformation"][6]["shorthand"]
    UNIT_TYPE_TO_INDEX[REMOVE] = 6

Or am I the dumb one here (probably the latter) and this was not the issue everyone was examining

Those unit numbers 0 through 6 are indeed the type ID codes for each unit, but the game state strings contain information on a whole lot more than that, and what that other thread figured out was how to read that information.

In regard to

Again, exactly what those empty lists are filled with can be found in the Parsing Replay Files thread that was linked previously.

so if this is the breach info:

“breach”: [[ [13,27], 1.0, 3, “7”, 1]]

How would I say if state["events"]["breach"]# second Item in the list == 1.0:
would I say, if state["events"]["breach"][0][0] == 13: to get the x value of where the breach occurred?

How would I know exactly which frame I am examining, how do I specify that, does that use a for loop? If so, would it look like this?

for each_state in saved_states:

Giving @KauffK the community helper badge

3 Likes