/MarioAI

MarioAI Challenge

Primary LanguageTypeScriptOtherNOASSERTION

Mario AI

Overview

The MarioAI project aims to allow school and university students to learn artificial intelligence in a entertaining context. Students merely require a Java IDE or their choice and the MarioAI .jar file that is produced with the maven build. Students can then use the provided API to implement an AI agent. A simple rules-based algorithm can easily be created within 10 minutes.

Setup

Setting up the IDE

Download the marioAI-<version>.jar from the repository. Create a new project in the IDE of your choice and include the MarioaAI.jar as a project dependency.

Eclipse

In Eclipse this can be achieved by right-clicking on the project → build path → Java build path. In the libraries tab click on "Add External JARs" and select the marioAI-<version>.jar

IntelliJ IDEA

In the menu click File → Project Structure → Libraries → "+" and select the marioAI-<version>.jar

Creating a Basic Agent

Create a new class that extends the Class MarioAiAgent. The MarioAiAgent class specifies two abstract methods which need to be implemented as can be seen in the snippet below.

public class Demo extends MarioAiAgent {

    @Override
    public String getName() {
        return "Demo Agent";
    }

    @Override
    public MarioInput doAiLogic() {
        moveRight();
        return getMarioInput();
    }

    public static void main(String[] args) {
	MarioAiRunner runner = new MarioAiRunnerBuilder()
		.addAgent(new Demo())
		.setLevelConfig(LevelConfig.LEVEL_1)
		.construct();

    	runner.run();
}

Add a main method as shown in the snippet and start MarioAI by running the method from your IDE. A window should open which show Mario walking right in a flat level.

MarioAI

User Interface

The user interface shows information on the current state of the game which can be useful to observe, including the current score as shown in the bottom left hand corner. The size of the window can be increased or decreased by pressing the +/- keys. To reset the window size, press #. More functions that can be accessed can be found the the chapter "Keyboard Functions" below.

Keyboard Functions

While MarioAI is running you can trigger the following functions from your keyboard

Function/Toggle Key
Increase window size +
Decrease window size -
Reset window size #
Increase FPS j
Decrease FPS k
Reset FPS to default (24) l
Toggle pause p
Pause and advance to next frame (i.e. tick()) t
Toggle path visualisation o
Pause game and show current level state in console i

MarioAI API

The MarioAI API is quite extensive. The following three chapters "Controlling Mario", "Reading the Environment" and "Configuration" will provide an overview of the most important aspects of the API. For more information, please refer to the JavaDocs provided in the jar file.

Controlling Mario

Controlling Mario is fairly straightfoward. There is a method that can be called for each action mario can carry out (i.e. move right, move left, jump and sprint/shoot fireballs. Please note that the last two actions are mapped to the same button in the game, as in the original game. To carry out one or more actions, simply call the associated method in the API

Action Corresponding API method
Move right moveRight()
Move left moveLeft()
Jump jump()
Sprint sprint()
Shoot shoot()
The doAiLogic() method must return a MarioInput object. By calling the aforementioned methods you can set the actions to perform in an existing MarioInput object and return it with getMarioInput() as can bee seen below (ex. Mario will sprint right and jump)
@Override
public MarioInput doAiLogic() {
    moveRight();
    sprint();
    jump();
    return getMarioInput();
}

Reading the environment

Reading Mario's environment via the MarioAI API can be achieved either via convinience methods or via more advanced methods. Let's begin by looking at the convienience methods provided by MarioAI which allow for quickly creating a simple rules-based AI algorithm (i.e. if this, do that).

Environment Query Method
Is there a brick (i.e. unpassable object) ahead? isBrickAhead()
Is there an enemy ahead? isEnemyAhead()
Is there a deep slope ahead? isDeepSlopeAhead()
Is Mario falling (i.e. has a positive y-vector) isFalling()
Is there a hole ahead (i.e. a hole which will kill Mario)? isHoleAhead()
Is there a question brick above Mario? isQuestionbrickAbove()

Running & Configuration

You can run your Agent by using the MarioAiRunner class. The simplest way of obtaining a Runner to run your agent is using the builder MarioAiRunnerBuilder . You can specify different parameters with the corresponding methods. For example you can pass an instance of your agent to the builder object with addAgent(). Then you can construct a MarioAiRunner instance with the builder and the method construct(). By calling the method run() of the newly created MarioAiRunner, you can start a run with your agent.

MarioAI offers many ways of customizing the level for your purposes. The simplest way to configure the game is to simply use preconfigured levels provided in the enums provided in LevelConfig and set it as used level of the builder with setLevelConfig().

    public static void main(String[] args) {
	MarioAiRunner runner = new MarioAiRunnerBuilder()
		.addAgent(new Demo())
		.setLevelConfig(LevelConfig.LEVEL_1)
		.construct();
    	
    	runner.run();
    }

If you would like to specify your own level (including the type of level, enemies, difficulty, etc. ) you can use the many paramenters that can be passed to the constructor of LevelConfig described below

Parameter Usage
seed The seed of the generated level layout. Using the same seed will result in the same level layout.
presetDiffulty A value which specifies the difficulty by influencing the amount of enemies which are spawned.
type Sets the type of level (i.e. OVERGROUND, UNDERGROUND, CASTLE)
enemies Toggles enemies
bricks Toggles bricks
coins Toggles coins
length The length of the level.
odds Array with length of 5, determines the percentage of level parts [STRAIGHT, HILLS, TUBES, HOLES, BULLETBILL]

Evaluation

You can evaluate how well your agent performed in the level by either reading the score at the end of the level from the UI, the console or the logs. Alternatively you can read the current score from the API using the getActualScore() method within the agent.

The following table shows all rewards and penalties that can be accrued during the level.

Event or Condition Reward/Penalty
Reach the end of the level +1024 points
Remaining time at the end of the level +8 points per second left
Distance passed +1 point per distance unit
Collecting coins +16 per coin
Defeated enemies +42 per enemy
... by stomping +12 points
... by hitting with a shell +17 points
... by fireball +4 points
Collecting non-coin items (i.e. fire-flowers, mushrooms) +58 per item
Getting hit by enemy or projectile -42 per hit