Robotypo Help - Fruit Day

Table of Content

What is Fruit Day?
Rules
    Example 1: MyFirstRobot
    Example 2: Focus - Let's defeat MyFirstRobot
    Example 3: FocusKiller - Beat 'Focus' perfectly!
Fight Result
Knowing Opponent's Strategy
Base Robot Class Details: Fruitday

Common Help For All Sub-platforms
    Upload A Robot
    Advanced Rules
    Debugging
    Member Variables, Initialization, and Using Java Utilities



What is Fruit Day?

Fruit Day is a sub-platform in Robotypo. Fruit Day hosts fights between Fruit Day robots.

You can create your own Fruit Day robots and upload them to this platform, and challenge other robots. A Fruit Day Robot is simply a Java program, which normally consists of only a few lines of code. Even you are not familiar with Java, you may create robots based on examples. Neither Java tool, nor IDE is a must.


Robots fight with others. Each match has two robots, and consists of multiple rounds. Before each round, each robot sets its strategy for the round. Your robot never knows for sure what the opponent's strategy is, and vice versa. It is up to you to create a strategy, and if necessary, analyze opponent's strategy and adjust yours to win.



Top    Back



Rules

  • The team: The match consists of two teams (one robot controls one team). Each team has 3 peasants. Each peasant has 100 HP.
  • Action: The match consists of 1000 rounds. In each round, each peasant chooses one and only one action. The action can be either HIT or HIDE.
  • HIT: Choose a peasant (0, 1, or 2) in the opponent team to hit. If a peasant chooses to hit, then others can hit him in this round, too. The HIT action is assured to hit the target if it does not hide.
  • HIDE: If a peasant chooses to hide, then others can not hit him in this round, and he can not hit others, too.
  • Out-of-play: Each time a peasant is hit, its HP is reduced by one. If the HP decreases to 0, then the peasant can not throw fruit any more. It is considered as out-of-play.
  • End of game: If all peasants in a team are out-of-play, the game ends and the opponent team wins. If there are too many rounds passed, the game ends, too. In this case, the winner is the team which has more total HP.
  • Coward: If a peasant hides more than 3 rounds continuously, it is called coward and it is out-of-play.

Before each round, the strategy() method of each robot is called. In this method, your robot needs to set actions for each peasant in your team. When setting the strategy, a robot never knows for sure what the opponent's strategy is. So it is up to you to analysis opponent's strategy, and adjust yours. In the round, hit or miss is calculated, and member variables (e.g. HP) are updated to reflect the changes.


It is recommended to read through the following three examples:
Example 1: MyFirstRobot
Example 2: Focus - Let's defeat MyFirstRobot
Example 3: FocusKiller - Beat 'Focus' perfectly!
Top    Back



Example 1: MyFirstRobot

MyFirstRobot shows what a Fruit Day robot looks like. It is simple. Each peasant in the team always target at a random opponent (from 0 to 2) in the opponent team.

public class MyFirstRobot extends Fruitday {

 

    //This is the method called before each round.

    public void strategy() {

 

        for (int i = 0; i < 3; i++) {      //For each peasant in our team,

 

            Peasant p = myTeam[i];

            p.action = random.nextInt(3);  //Hit a random opponent peasant.

 

            //You can also tell peasant to hide, like this:

            //p.action = HIDE;

        }

    }

}

Top    Back



Example 2: Focus - Let's defeat MyFirstRobot

A simple strategy is enough to defeat MyFirstRobot: if everyone hit the same opponent, it will be hit many times and will be out of play soon. So the new robot - Focus - is created:

/**

 * With the robot "Focus", all peasants in our team hit one

 * opponent peasant intensively, so it will be out-of-play

 * quickly. That's good for us.

 */

public class Focus extends Fruitday {

 

    int focus = 0;  //A member variable which stores our focus

   

    public void strategy() {

 

        //Get the opponent peasant at our focus

        Peasant p = opponentTeam[focus];

       

        //If it is out-of-play...

        if (p.hp == 0    

                //OR: (we are smart) if it is hiding in the previous round...

                || p.action == HIDE) { //(The p.action stores the action of the peasant in the PREVIOUS round)

           

            //Move the focus to the next one.

            if (++focus > 2)

                focus = 0; 

        }

       

        //All fire at the focus!

        for (int i = 0; i < 3; i++)

            myTeam[i].action = focus;

    }

}

Top    Back



Example 3: FocusKiller - Defeat 'Focus' perfectly!

'Focus' is smart, but it is too predictable. Let's defeat it PERFECTLY:

/**

 * The robot Focus is good. However it is too predictable.

 * Let's defeat it, simply, and *perfectly*.

 */

public class FocusKiller extends Fruitday {

 

    int focus = 0;

   

    public void strategy() {

 

        for (int i = 0; i < 3; i++)

            //If I'm at opponent's focus, I hide, otherwise I hit.

            myTeam[i].action = i == focus ? HIDE : focus;

       

        //Move focus.

        if (++focus > 2)

            focus = 0;

    }

}


Top    Back



Fight Result

The fight result looks like "0:32". It means that after the fight, the first robot has 0 HP left, and the second robot has 32 HP left in total. The robot who has more total HP wins. In this case, it is the second robot. If a number is -1, error occurred in the corresponding robot, probably exception is thrown, or it is timeout during calculation.


The detailed fight result shows the exact action of each peasant. The result consists of blocks of each round, looks like this:

_0_   _1_   _2_  

[1] HP 9810099
Action000
Action200
HP 97100100

[2] HP 9810096
Action000
Action222
HP 94100100


The number between [ ] is the round number. In this example, Round 1 and 2 are shown.

Details about Round 1 shown the example:
The first row represents the HP of peasants in team 1.
The second row represents the actions of peasants in team 1.
The third row represents the actions of peasants in team 2.
The fourth row represents the HP of peasants in team 2.
The 3 columns to the right are for peasant 0, 1, and 2 respectively.

Note that HP is the HP after the round. In this example, all 3 peasants in team 1 hit at position 0. So in team 2, the peasant at position 0 has 97 HP (100-3). The peasant 0 in team 2 hits at position 2. So peasant 2 in team 1 has 99 HP (100-1). The peasant at position 1 and 2 in team 2 hit at position 0, so peasant 0 in team 1 has hp 98 (100-2).


Top    Back



Knowing Opponent's Strategy

You can record and analysis the strategy of your opponent robot, by reading the opponentTeam member in the robot class. Before each round (in the strategy() method), the member variables myTeam and opponentTeam represent the state at the end of the previous round. So myTeam[i].action is the action of your peasant (at position i), and opponentTeam[i].action is your opponent's action at position i.

You can analysis the strategy of your opponent robot. Before each round (at the beginning of each strategy() method call), the following member variables represent the state at the end of the previous round:

  • opponentTeam
  • myTeam

Each team object is an array of three elements, with type Peasant. For example:

  • myTeam[0].action: the action this peasant was set. Could be HIDE (-1), or 0, 1, 2, which represents hitting at position 0, 1, 2 respectively.
  • myTeam[0].hp: The HP left of peasant 0.
  • myTeam[0].cowardCount: The count of continuous hidding.

All previous history records can also be retrieved from the history member variable. history[0] represents the state of round 0, history[i] represents the state of round 1, and so on. For example:

  • history[0].myTeam: represents my team state after round 0. history[0].myTeam[0] refers to the first peasant in the team.
  • history[0].opponentTeam: opponent team state after round 0

  • history[1].myTeam: myTeam state in round 1
  • ...

Further, you can create class member variables to form your own data structures and store your own data.


Further, you can create class member variables to form your own data structures and store your own data. For example, recording the opponent's actions of the last two rounds...


Read the next section Base Class Details: Fruitday for more details.


Top    Back



Base Class Details: Fruitday

Here's the source code for the base class Fruitday. Generally for each robot, there are 4 useful members:
  • Peasant[] myTeam
  • Peasant[] opponentTeam
  • Random random
  • int round
Read the comments for details.

/**

 * The base class for Fruitday robots.

*/

public abstract class Fruitday {

 

   public static final int TOTAL_ROUNDS = 1000;

   public static final int MAX_HP = 100;

 

   /**

    * Peasant actions

    */

   public static final int HIDE = -1;

   public static final int HIT0 = 0;

   public static final int HIT1 = 1;

   public static final int HIT2 = 2;

  

   /**

    * Max continuous HIDE count. If a peasant hides

    * more than this number continuously, it's out of play.

    */

   public static final int COWARD_LIMIT = 3;

  

   /**

    * A Peasant represents one peasant in

    * a Fruitday team.

    */

   public static class Peasant {

      /**

       * The action for this peasant. This value needs to be

       * set in the <code>strategy()</code> method.

       * Possible values are:

       * <li> HIDE: hide.</li>

       * <li> 0: hit the first peasant in the opponent team.</li>

       * <li> 1: hit the second peasant in the opponent team.</li>

       * <li> 2: hit the third peasant in the opponent team.</li>

       */

      public int action;   

      /**

       * The hit points left for this peasant. If <code>hp</code> is 0, the

       * peasant is out of play, and can not throw fruit anymore.

       * This is a read only value, and changing it has no effect.

       */

      public int hp;

      /**

       * The coward count for this peasant. Read only.

       * This value goes up each time when a peasant hides. If it's more

       * than 3, this peasant is considered as a coward and is out of play.

       * By throwing at one opponent peasant (set <code>action</code>), this value

       * is reset to 0.

       * This is a read only value, and changing it has no effect.

       */

      public int cowardCount;

     

      /**

       * Copy data from the given peasant

       * @param p

       */

      public void copy(Peasant p);

   }

  

   /**

    * The 3 peasants in our team. In each round, you need to

    * set <code>action</code> of each peasant in the <code>strategy()</code> method.

    * Their member variables represent the state at the end of the previous round.

    * Read them for strategy.

    */

   public Peasant[] myTeam;

   /**

    * The 3 peasants in the opponent team.

    * Their member variables represent the state at the end of the previous round.

    * These values are read only, and changing them has no effect.

    */

   public Peasant[] opponentTeam;

 

   /**

    * Utility for generating random values.

    */

   protected Random random;

  

   /**

    * Helper. Stores the current round number.

    */

   public int round;

 

   /**

    * Set the hit or hide strategy (the <code>action</code> member) for

    * each peasant in our team (<code>myTeam</code>).

    *

    * This method is called before each round.

    *

    * Read <code>opponentTeam</code> to analysis the opponent.

    */

   public abstract void strategy();

  

   //////////////////////////////////////////////////////////

   // Helper for history records

   //////////////////////////////////////////////////////////

  

   public static class Record {

      public Peasant[] myTeam;

      public Peasant[] opponentTeam;

   }

  

   /**

    * Stores all previous records.

    */

   public Record[] history;

}


Top    Back



Common Help For All Sub-platforms

This part of help applies to app sub-platforms in Robotypo. It tells you some common rules of creating robots.




Upload A Robot

Click My Robots! in the left navigation area, you may need to login with Google account or an Open ID. Then click the Create button. Example code is already there. You can create your robots base on that.


Top    Back



Advanced Rules

Besides the basic rules, there are some other advanced rules:

  • Time limit: Each strategy() call must not take too long, and the accumulated time a robot consumes must not take too long. Exceeding the limit will result exception from the robot. This rule protects the system from being blocked by deadlock robots. Normally the time is enough. For example, the time limit per round for each robot is about 3 seconds, and the total accumulated time limit for each robot is about 15 seconds. However, since robot code runs in a complex and secured environment, it runs much slower than on your PC. So optimize your code, and use simple structure as much as possible (e.g. int[]).
  • Exception: If the action is out of range, (not HIDE, 0, 1, or 2), then exception occurs and the robot loses. Also, avoid modifying things except the action. For example, surely it is OK to set myTeam to null from perspective of Java language, but that will cause your robot exceptions.
Top    Back



Debugging

When you need this, you're likely creating some really good robots. Refer to the guide Setup Debug Environment for details.


Top    Back



Member Variables, Initialization, and Using Java Utilities

Since each robot is a Java class, you can create member variables to record and analyze opponent strategy. However, note that all opponent information of the previous round is already stored in some member variables, and you do not need to create additional member variables for that. Refer to the base class document of each platform for details. In addition, custom funtions, inner classes, and Java utilities can also be used. For example, the collection classes in package java.util. They are imported by default.


If you want to do some custom initialization, you can create a class constructor function to do this, or just inside a non-static initialization block (recommended). For example:


public class MyRobot extends ... {

 

    // A custom class

    static class MyData {

       //...

    }

   

    // A custom member variable

    List<MyData> items = new ArrayList<MyData>();

   

    // Initialization block

    {

       // Your class initialization code here

    }

 

    //A custom function

    void analyzeOpponentStrategy() {

       //...

    }

   

    public void strategy() {

      

       analyzeOpponentStrategy();

      

       // Other stuff

       // ...

    }

}


Top    Back



Common Help For All Sub-platforms

This part of help applies to app sub-platforms in Robotypo. It tells you some common rules of creating robots.




Upload A Robot

Click My Robots! in the left navigation area, you may need to login with Google account or an Open ID. Then click the Create button. Example code is already there. You can create your robots base on that.


Top    Back



Advanced Rules

Besides the basic rules, there are some other advanced rules:

  • Time limit: Each strategy() call must not take too long, and the accumulated time a robot consumes must not take too long. Exceeding the limit will result exception from the robot. This rule protects the system from being blocked by deadlock robots. Normally the time is enough. For example, the time limit per round for each robot is about 3 seconds, and the total accumulated time limit for each robot is about 15 seconds. However, since robot code runs in a complex and secured environment, it runs much slower than on your PC. So optimize your code, and use simple structure as much as possible (e.g. int[]).
  • Exception: If the action is out of range, (not HIDE, 0, 1, or 2), then exception occurs and the robot loses. Also, avoid modifying things except the action. For example, surely it is OK to set myTeam to null from perspective of Java language, but that will cause your robot exceptions.
Top    Back



Debugging

When you need this, you're likely creating some really good robots. Refer to the guide Setup Debug Environment for details.


Top    Back



Member Variables, Initialization, and Using Java Utilities

Since each robot is a Java class, you can create member variables to record and analyze opponent strategy. However, note that all opponent information of the previous round is already stored in some member variables, and you do not need to create additional member variables for that. Refer to the base class document of each platform for details. In addition, custom funtions, inner classes, and Java utilities can also be used. For example, the collection classes in package java.util. They are imported by default.


If you want to do some custom initialization, you can create a class constructor function to do this, or just inside a non-static initialization block (recommended). For example:


public class MyRobot extends ... {

 

    // A custom class

    static class MyData {

       //...

    }

   

    // A custom member variable

    List<MyData> items = new ArrayList<MyData>();

   

    // Initialization block

    {

       // Your class initialization code here

    }

 

    //A custom function

    void analyzeOpponentStrategy() {

       //...

    }

   

    public void strategy() {

      

       analyzeOpponentStrategy();

      

       // Other stuff

       // ...

    }

}


Top    Back



For more help, visit forum.