Stephen Superville'S AI Project
PROJECT

Kanonball Automated Clone

Contents
Domain
Illustration
Methods
Conclusions

Domain

Kanonball is a futuristic sports simulation that is advertised as "the ultimate sport of the 23rd century". The game is simple: "A ball, 2 teams, opposing goals and a time limit". Replacing the Olympics, Kanonball is played exclusively by genetically engineered clones designed specifically for the sport. Using a variety of attacks, such as dives and slide tackles, the players attempt to put the ball into the goal, while preventing the opposing team from doing the same. A demo version of this game, for which I have done all the programming, is already available as a mod for the HL engine. For more information and a detailed description on the mechanics of Kanonball visit http://www.kanonzone.com

The environment of the KAC consists of a large number of connected nodes, a list of players (which could be human operated in-game or other KAC), a ball, and goals. The static information is handled by facts, such as which nodes are connected, the distance between them, ect. The dynamic information about the ball and the players are stored in associated data structures.

Player Stats:
player( NAME, BODY, TEAM, POSITION, HAS_BALL, IS_DOWN, TIME_DOWN )
NAME - Team-unique name.
BODY - Body type, used to determine how much damage is done in a collision, how far a player can throw the ball, and how far they can move each turn (Ubermorph, Mesomorph, Ectomorph in order from biggest to smallest).
TEAM - Team name.
POSITION - The current node.
HAS_BALL - yes/no.
IS_DOWN - yes/no.
TIME_DOWN - Amount of time left to stay down.

Ball Stats:
ball( POSITION, DIRECTION, SPEED, OWNER )
POSITION - The current node.
DIRECTION - Moving in given direction (only relevant when not possessed by a player).
SPEED - How many nodes it can move per turn.
OWNER - Name of the player in possession if any.

Action Results:
action( PLAYER, ACTION( INFORMATION ), COST )
PLAYER - Player doing the action ACTION - Type of action done (ie pass, attack, throw, ect.)
INFORMATION - Relevant information for the action.
COST - Cost of doing this action.

The starting environment is specified in the start_env clause.


Illustration

Initial condition:
player( red_striker, ecto, red, g, yes, no, 0 )
player( red_goalie, ecto, red, s, no, no, 0 )
player( blue_striker, meso, blue, c, no, no, 0 )
ball( g, none, 0, red_striker )
link( c, s, 20, west )
link( e, s, 40, north )
link( c, e, 50, southwest )
link( f, g, 40, north )
link( g, s, 20, east )
link( g, h, 40, north )
goal( p, g1, red )

Output:
action(blue_striker,attack(player(red_goalie,ecto,red,s,no,no,0),[c,s]),20)
action(red_goalie,attack(player(blue_striker,meso,blue,c,no,no,0),[s,c]),20)
action(red_striker,pass(player(red_goalie,ecto,red,s,no,no,0),ball(g,east,2,none)),20)


Methods

The Kanonball arena is built of a bunch of connecting nodes. I selected this method (instead of coordinates) to allow the program to specify paths around impassable objects, such as pillars or walls that could be designed into the arena.

The programs most complex function is figuring out the best path to a particular node from the current node. Situational calculus is used to determine each path, given the players initial position, and then the shortest path is selected that is less than the maximum distance the player can move in a single turn. If there is no such path, the query fails. This path is used to decide which action can be performed, since you have to be in a certain position to perform relative actions. For example, you must be on the same node as an enemy to attack him. And you must be within the line of sight of a goal to shoot at it. The hardest part of this was preventing infinite loops, since the nodes are largely interconnected.

For the ball to move, the direction it was moving added some more complications. Since the ball can only move in one direction, I was forced to limit the nodes in the environment to the 8 primary directions (N,NE,E,SE,S,SW,W,NW). This allowed me to decide which node the ball moved to by simply finding the node in that direction. It also allowed me to easily reflect the ball off boundaries of the arena, based on the previous direction.


Conclusions

I didn't get to go nearly as deep into this project as I wanted. I had intended to create a dynamic system that would update the environment after each step, and then loop in on itself. However, I could not find a decent way to update the environment effectively, after each decision was made. For instance, if one player decides to attack another, and that player decides to move to a different position, what is supposed to happen? Even worse, what if two players decide to grab the ball at the same time? Who gets it first, the closest player? What if the one further is faster? When I first started this project I didn't foresee this problem.