Terminal Game Q&A

It seems that now it’s working again. At least, after three crashed matches, my last match went correctly; so I guess everything is going well now.

1 Like

@KauffK, @salanueva

We deployed a hotfix around 6pm EST today, and some of our services were desynchronized during that process (The server that runs ranked games and some data it depends on).

One of them updated about 10 minutes before the other, and during that time ranked games would crash when started. This issue has been resolved, and we will be working on our update process to make things smoother in the future.

1 Like

What is the good way to play adaptive in defense?

One way to do this is to save gamestate from previous turn before combat phase and compare with actual turn to get the list of destoroied firewalls and guess that if u lost a health points and firewalls at given location that means that u need more defense around this location.

But this solution is time consuming. Did i miss something? Is there any easy way to get information about what units did my opponent deploy last turn and if/ where did they hit me?

1 Like

If you look into the algocore, you can see how the engine and game communicate, and get data about action phase frames. Its a fairly small hint, but hopefully it helps a little! Like any programming goal there are lots of ways to accomplish this, its up to you to find the best one

3 Likes

Here’s a question. For the CodeBullet challenge, it does not seem to allow me to select an algo. Whenever I choose any of my algos from the drop-down menu, after refreshing the page, the selection has changed back to “Pick my best algo”. Is there something I’m missing about how this works?

1 Like

@KauffK - Did you look at your row in the player table to see if it updated your algo choice there?

1 Like

Interesting. It does remain updated in the table after refreshing.

1 Like

oh no you are in the codebullet competition, there goes my winning chance :grimacing:

2 Likes

To be fair, if everyone that’s signed up turns in an algo, isn’t like 2/3 of the global player base technically in the codebullet competition? :stuck_out_tongue:

1 Like

yeah but that means people have to actually put in their algo, which only about 160 people did :stuck_out_tongue:

1 Like

By default anyone who clicks the ‘join’ button will have their highest Elo algo chosen when we run the competition, so long as they have at least one algo uploaded. I believe an engineer was working on a fix for that ‘My best algo’ drop down last week, I would imagine it will be deployed sometime next week.

As an aside since we are talking about CB, i’ll be streaming the top 8 thursday night, ill make a forum post with the exact time and a twitch link.

4 Likes

Will that fix be implemented before the CB tournament due date? If not, I guess I could delete all my other algos and just leave the one I want to compete with.

2 Likes

Sorry if I was unclear!

Selecting your algo DOES work, it just isn’t communicated at all. If you select an algo from the drop down, instead of the dropdown changing to your algo, it will still read ‘Choose your best algo’ or whatever the default is. If you refresh the page and check your competition entry, you will see that your submitted algo is the one selected in the drop down.

2 Likes

Oh I see. Thanks for clearing that up!

1 Like

What are the specifics of Python algorithms?

  • Matches on your servers use python 3.7, right?
  • Any plans of supporting PyPy or something? That would speed algorithms up considerably, and would be nice for adaptive algos.
  • Is multithreading supported?
1 Like

is there a way to see what decisions the opponent made last turn, specifically the locations they placed their information units? i looked in gamelib but couldn’t find anything about that.

1 Like

Short answer: There is a way that you can do it, but it isn’t built in, and you have to modify the code to do so.

Long answer:

You need to modify AlgoCore to get this information. A thread that discusses how to do this in more detail is: https://forum.c1games.com/t/how-to-find-where-my-or-my-enemys-information-units-scored/240/8. However, this thread discusses breach information, while you are looking for spawn information.

To do this, first go to game_state.py. When I did this, I added a line in the GameState.__init__ where I created an array to store all information units on the board. I called this self.units. I then modified the __create_parsed_units function. At the very end, add the lines

if not is_stationary(unit_type):
<indent>self.units.append(unit)

This will fill the array self.units with all of the information units that existed in that frame. In the parse_action_phase function (detailed in earlier link), you will only want to go through everything if it is the first frame of the aciton phase. You can then go through the list of units, take the ones that belong to your opponent, and store the relevant information.

Note: I likely made several mistakes in my explanation. If I was unclear at any point, just ask me to clarify.

2 Likes

ok thanks for showing me where to start! i managed to get something working so i’ll post the code modifications i made here so others don’t have to spend 2 hours debugging like i did (ok that might be because im a terrible programmer but still)

i made these modifications to the algocore file:

def getinfo(self):
    return self.state

def __init__(self):
    self.config = None
    self.info = None
    self.state = None
    self.get_info = True

if stateType == 0:
    self.get_info = True
    """
    This is the game turn game state message. Algo must now print to stdout 2 lines, one for build phase one for
    deploy phase. Printing is handled by the provided functions.
    """
    self.on_turn(game_state_string)

elif stateType == 1:
    """
    If stateType == 1, this game_state_string string represents the results of an action phase
    """
    if self.get_info:
        # debug_write("getting info...")
        self.state = game_state_string
        self.get_info = False
        continue
    else:
        continue

to see which location the opponent attacked from, you’d only want to get the first frame of the action. the get_info variable tells you whether to collect the frame or not, and in this program i have it set to false after it gets data, and back to true during the beginning of each turn. the frame is stored in self.state.

i then added this to the algo_strategy.py file:

def getinfo(self):
    return super().getinfo()

this allows me to call the getinfo method from algocore when i want to, which is cool because algocore isn’t very nice with letting you do that stuff.

modifications to game_state.py:

    (in __init()__)
    self.my_unit_types = []
    self.my_unit_locations = []
    self.enemy_unit_types = []
    self.enemy_unit_locations = []
    self.__parse_state(serialized_string)

            if unit_type == REMOVE:
                self.game_map[x,y][0].pending_removal = True
            else:
                unit = GameUnit(unit_type, self.config, player_number, hp, x, y)
                self.game_map[x,y].append(unit)
                # debug_write("type of unit is " + str(unit_type))
                if not is_stationary(unit_type):
                    if player_number == 1:
                        self.enemy_unit_types.append(unit.unit_type)
                        self.enemy_unit_locations.append([unit.x, unit.y])
                    else:
                        self.my_unit_types.append(unit.unit_type)
                        self.my_unit_locations.append([unit.x, unit.y])

the __create_parsed_units method didn’t have any ways to use information units because it usually wasn’t dealing with them (which was my main problem, the gamestate object was being called at the beginning of the turn when there were no information units). i added them here.

finally, this was added to the on_turn method in algo_strategy:

    info = self.getinfo()
    if info is not None:
        frame_0_gamestate = gamelib.GameState(self.config, info)
        for attack in frame_0_gamestate.enemy_unit_locations:
            # gamelib.debug_write("The enemy attacked from " + str(attack) + " last turn.")
            self.past_enemy_attacks.append(attack)

it uses the frame collected from the modified algocore file to make a second gamestate object, which has the information units on it.

this is probably a pretty inefficient solution but hopefully it will help some people!!

1 Like

I knew that I’d forgotten to put something into my answer… I guess that it was the __create_parsed_units. I have it in my code, but I forgot to place it into the thread. Thank you for clarifying. Do you mind placing your answer here into the thread that I mentioned, so that people can see that as well? If I see people asking about that, that is the thread that I always give to them, and it would be nice to be able to continue doing that :grinning:.

@C1 people:
Would you want a fixed version of something like this in the starter kit as an open source contribution, or is this one of the things that you want people to puzzle out for themselves? I could get together a nice, working version of this, but I am lazy, and don’t really want to go through the effort if you won’t use it.

@Tim

If you have a specific proposal for an open source contribution, you can message me directly for feedback.