http://robotypo.appspot.com
IntroductionUser Guide - for users who use Fruit War
Download
Deployment
Security model
Contact & Related links
Other projects
What is Fruit War?
How to write a Fruit War Robot?
Detailed Rules
Sample 1: MyFirstRobot
Sample 2: Focus - Let's defeat MyFirstRobot
Sample 3: FocusKiller - Beat 'Focus' perfectly!
How to upload my Robot?
How to debug my robot?
During debug, it always says "timeout"
Interface IFruitWarRobot
Interface IFruitThrower
Class EnemyInfo
Ranking
Battle result
Detailed battle result
Sample 1: MyFirstRobot
Sample 2: Focus - Let's defeat MyFirstRobot
Sample 3: FocusKiller - Beat 'Focus' perfectly!
Throw: throw at a member in opponent team.* When setting strategy, you do not know whether an rival thrower is hiding or not.
Hide: hide behind the basket.
Coward: A Fruit Thrower is decided to be a coward if he/she hides too many rounds continuously.For the limit for "too many rounds", please refer to constant value fruitwar.Rules.COWARD_LIMIT.
Out of play: If a Fruit Thrower is out of play, it will be removed from the team and can not do any action. If all throwers are out of play, most likely the team loses.* At the beginning, a Fruit Thrower has fruitwar.Rules.FRUIT_THROWER_HP hit points (HP). Each time it is hit, its HP is reduced by 1. When its HP is equal or lower than 0, it's out of play.
This is a sample Fruit War Robot. For details, please refer to Detailed Rules
Top Backimport java.util.Random;
import fruitwar.EnemyInfo;
import fruitwar.IFruitThrower;
import fruitwar.IFruitWarRobot;
import fruitwar.Rules;
public class MyFirstRobot implements IFruitWarRobot {
Random rand = new Random();
// Customize this method to set action of each thrower in the current round.
public void strategy(IFruitThrower[] throwers) {
//for each thrower in our team
for(int i = 0; i < throwers.length; i++){
IFruitThrower t = throwers[i];
//throw at a random enemy position
t.throwAt(rand.nextInt(Rules.BASKET_CNT));
}
}
// This method is called after a round. Get enemy strategy here.
public void result(EnemyInfo[] enemies) {
//nothing. This robot does not care about results.
}
}
A simple strategy is enough to defeat MyFirstRobot: if every thrower throws at the same enemy, it will be hit many times and will be out of play soon. So our new robot Focus is created:
Top Back
import fruitwar.EnemyInfo;
import fruitwar.IFruitThrower;
import fruitwar.IFruitWarRobot;
import fruitwar.Rules;
/**
*
* This robot tries to make all throwers hit the same position in
* opponent team, so it's likely that the opponent thrower at our
* "focus" will be "out of play" quickly. Then we have 3 throwers,
* while our opponent has only 2...
*
*/
public class Focus implements IFruitWarRobot{
int focus = 0; //our focus: the position we throw at.
public void strategy(IFruitThrower[] throwers) {
for(int i = 0; i < throwers.length; i++){
//all throwers focus on the same enemy!
throwers[i].throwAt(focus);
}
}
//get opponent strategy here.
public void result(EnemyInfo[] enemies) {
//at our focus, get the enemy info
EnemyInfo e = enemies[focus];
//if there's no one at focus (e == null),
//or it's just hit down (e.hp <= 0)
if(e == null || e.hp <= 0){
//changeFocus
focus++;
//In Fruit War, the max position is Rules.BASKET_ID_MAX().
//If the focus is bigger than that, we strat from 0.
if(focus > Rules.BASKET_ID_MAX())
focus = 0;
}
}
}
'Focus' is smart, but is too predictable. Let's defeat it PERFECTLY:
Top Back
import fruitwar.EnemyInfo;
import fruitwar.IFruitThrower;
import fruitwar.IFruitWarRobot;
import fruitwar.Rules;
/**
* This robot is specifically designed to defeat the robot
* 'Focus'. We know their focus, and we always let our
* thrower hide at their focus. So they can never hit us.
*/
public class FocusKiller implements IFruitWarRobot {
int enemyFocus = 0;
public void strategy(IFruitThrower[] throwers) {
for(int i = 0; i < throwers.length; i++){
IFruitThrower t = throwers[i];
//if the thrower is at enemy focus, hide.
//So enemy will not hit us.
if(t.getPosition() == enemyFocus)
t.hide();
else
//simply, we throw at the same focus they have.
//Let our opponents taste their focus!
t.throwAt(enemyFocus);
}
}
public void result(EnemyInfo[] enemies) {
//enemy focus is guaranteed to work like this.
enemyFocus++;
if(enemyFocus > Rules.BASKET_ID_MAX())
enemyFocus = 0;
}
}
Congratulations! When you need this you're starting to create some awfully good robots indeed.
First you need to download the
source code from download page. Note that the source package is one package (whose name contains "src")
inside the released package.
To setup the development environment:
Assuming you that have Eclipse with JDT (if you write java code, most likely you have).
Select "File -> Import... -> Existing Projects into Workspace" to import the Fruit War project:
Select the fruitwar_x.x.x.jar you have:
It's done! You should have the Fruit War project imported, without any error in the project. If there's any
red "x" or something alike, please contact developers.
Run the TestMyRobot.java, this is a simple case to run two robots:
Congratulations! The debug environment is ready.
Set fruitwar.Rules.ROBOT_CALCULATION_TIMEOUT to 0.
Top Backpackage fruitwar;
/**
* This is the base of Fruit War robot. Implement this interface
* to create your own robot.
*
*/
public interface IFruitWarRobot {
/**
* This method is used to set actions in the next round. Customize
* this method to set action of each thrower in the current round.
*
* @param throwers Array with dynamic length
* {max @code fruitwar.core.Rules.BASKET_CNT}, which contains only
* active throwers. If at position n the thrower is out of play,
* it will not be included in this array.
*/
public void strategy(IFruitThrower[] throwers);
/**
* The enemy info of the last round. The length of parameter
* "enemies" is fixed value: {@code fruitwar.Rules.BASKET_CNT}.
* If there's no enemy thrower at a position, the element in
* the array is null.
*
*/
public void result(EnemyInfo[] enemies);
}
package fruitwar;
/**
* Represent a thrower in Fruit War.
*
*/
public interface IFruitThrower {
/**
* Throw at the rival thrower at the given position. Range from
* 0 to {@code fruitwar.Rules.BASKET_ID_MAX}. If the position is
* out of range, your whole team loses! (Exception will be thrown).
*
* This is an action command. You can call only one action command
* each round. If action commands are invoked multiple times, only
* the last one takes effect.
*
* @param target Position of a rival fruit thrower. Range from
* 0 to {@code fruitwar.Rules.BASKET_ID_MAX}
*/
void throwAt(int target);
/**
* Hide behind basket this round.
*
* This is an action command. You can call only one action command
* each round. If action commands are invoked multiple times, only
* the last one takes effect.
*/
void hide();
/**
* Get the position of the thrower.
* @return Basket ID, range from 0 to {@code fruitwar.Rules.BASKET_ID_MAX}
*/
int getPosition();
/**
* Get hit points left of the thrower.
* @return Hit points left.
*/
int getHP();
/**
* Get how many continuous rounds this thrower has hide.
* @return Continuous rounds this thrower has hide.
*/
int getCowardCount();
}
/**
* Info of one enemy thrower in the last round.
*
*/
public class EnemyInfo {
/**
* Which position was the thrower throwing at,
* in the last round.
*/
public int target;
/**
* How many hp does the thrower left
*/
public int hp;
}
15 - abs(ranking1 - ranking2) / 15An example: robot1 battles robot2, assuming robot1 has ranking 1500, and robot2 has ranking 1515. The ranking difference is 15. If robot2 wins, it receives 15 - (1515 - 1500) / 15 = 14 ranking, and robot1 loses 14 ranking. If robot1 wins, it receives 15 - (1500 - 1515) / 15 = 16 ranking, and robot2 loses 16 ranking.
=== Round 30 ===The three numbers (55, 44, 77) in the first line represent the HP of throwers in the first robot. The second line represents the actions of throwers in the first robot. For the actions, a number means it's hitting at the position, and an "H" means it is hiding. So for the first robot, thrower 0 has 55 HP, and it's throwing at enemy 0; thrower 1 has 44 HP, and it's throwing at enemy 1; thrower 2 has 77 HP, and it's hiding.
1(hp) - 55 44 77
1(at) - 0. 1. H.
2(at) - 2. _. 2.
2(hp) - 44 0 33
=== Round 31 ===Top Back
1(hp) - 55 44 77
1(at) - 0. 0. 0.
2(at) - 0. _. 0.
2(hp) - 43 0 33