STPs’ AI uses a score system to determine which play is the best in after a finished play. When considering plays, these factors need to be taken into account:

  • The past, information from last play.
  • The current state of the world, positioning of the ball and enemy robots.
  • The future, the effectiveness of the next play.

To handle the past, a new structure was created to transfer information from the previous play to the next play. The current state uses a new module called the PlayEvaluator to handle the computations. The future state is currently based on the position scores of the future roles and this information is saving within the PositionComputation class.

The influence of these factors are completely subjective and can differ from situation to situation. The method used to handle these evaluations is comparable to how the position computations are done with the factors and weights, where computations that have already been made in a tick are saved to be reused in the same tick.

The new structure, PlayInfo, was added to save selective pieces of the StpInfo to be evaluated in the next play, as not all the information in StpInfo is informative and most importantly: The map in StpInfo uses non-generalised keys for each role, it would require knowledge of the previous plays keys to use StpInfo. This resulted in 2 options: Either make StpInfo generalized, where role names (keys) are selected from a list14 or to make a new structure that saves the information which pre-defined terms. PlayInfo is a map with a key as a robot role15 and information linked to that robot16. This structure is created when the previous play is ended and can be used when choosing which play to do next and when the next play is initialised. The information of this structure is all optional. Therefore, the play designer can cause which information is useful for the next play and does not need to fill out every element. The next play checks if this information is filled in, and is able to use it if it is to evaluate a score.

Usage example The considered usage of this system was built on the fact that information was needed for the combination of play required to pass the ball. This sequence of plays required to pass the ball would be:

  • Get the ball, a robot gets the ball, other will get into position.
  • Pass the ball, the robot chooses the best robot to pass to and passes.
  • Receive the ball, the receiver robot will move into position to receive the ball.

The old system had this in a single play to ensure the information between the steps was kept, creating a far too complex play. Splitting this would require a method to save this information between the steps and therefore PlayInfo was designed. This system would allow the passing of the ball to shoot to a location where a robot is planning on going to (predicting a location) and transferring the pass location to the next play to process the receiving of the ball. Ideally, this would not be required as the world would indicate that the ball is going to a certain location and a path can be predicted for the ball. However, in reality, the world system has delay and is not as accurate as would be needed for this to work. As the pass direction and location are accurate, saving this information for the next play would compensate for the delay and allow plays to continue from the last play without needing information of the world. Of course, this information can then be checked with the world when the world catches up, failing the play if this information was inaccurate.

A new module was added that is an instance in the ApplicationManager (together with, PlayChecker and PlayDecider), called PlayEvaluator. The PlayEvaluator is only utilized in between plays and has a reference to the world data that is only valid in that tick18. This module is used to score for the world state in the form of Global Evaluations19, these are evaluations that are linked to the location of robots or the ball, and are not unique to an individual robot. As this can not change within a single tick, these computations are saved within PlayEvaluator to be reused within the same tick. Within the PlayChecker and PlayDecider, this module is used to evaluate if: a play is currently allowed and to help determine the score of the play, respectively.

The actual scoring of the play is done within each individual play. The function score() has a list of all factors that need to be considered and the associated weight of that factor. If the current game state needs to be considered, within the score() function, a Global Evaluation will be requested. If a play needs to consider the future, it calls upon a function that will compute the positions and scores needed to score the play. The score should be an indication of how effective the position is for the play20. These computations will not be lost as they will be saved in the PositionComputation class and the PlayEvaluator module for the rest of the tick.

One of the goals of this report was to reduce the complexity of the current plays. These plays were complex to compensate for the missing decision making capability of the AI. With the addition of this framework, those plays can be split up into smaller plays. However, this framework does not allow forcing a play after another, this should be achieved with parameter tweaking the scoring of the plays. Using the defined score list of all plays, the AI will always pick the best scoring play after the previous play has ended. The definition of the best scoring play is a subjective design choice. The play designer has chosen reasons why a play is good considering a set of chosen factors. To ensure that the actual best play is picked, testing of the scores in different scenarios needs to be done, where small tweaks to scores and adding additional factors will increase the accuracy of the best scoring play.