/*
* NanoInterpreter by Kinsen Choy
* http://robowiki.net/cgi-bin/robowiki?Kinsen
*/
import robocode.AdvancedRobot;
import robocode.ScannedRobotEvent;
public class NanoInterpreter extends AdvancedRobot
{
/*
* Command Usage
* CMD_SET CMD_SET [Index] [Value]
* CMD_IF CMD_IF [Location] [Condition]
* -------
* CMD_CALL CMD_CALL [# Parameters] [Parameters...] [Class Name] [Method Name]
* [Object Index (0: Robot, 1: Event)]
* CMD_VAR_VAL CMD_VAR_VAL [Index]
* CMD_SUBTRACT CMD_SUBTRACT [Value0] [Value1]
* CMD_DIVIDE CMD_DIVIDE [Value0] [Value1]
*
* Only the first two commands can start a "line" of commands
* Numbers that represent a command must be an integer and numbers representing a number must be a double (e.g. 0.0)
* CMD_IF will set the interpreter location at the [Location]th token (delimited by spaces) if [Condition] == 0D
* CMD_VAR_VAL gets the value stored at [Index]
*/
private static final int ARRAY_SIZE = 8192; // 2 ^ 13
private static final int CMD_SET = -1;
private static final int CMD_CALL = 0;
private static final int CMD_VAR_VAL = 1;
private static final int CMD_SUBTRACT = 2;
// Hidden commands:
// CMD_IF
// CMD_DIVIDE
private static final String COMMANDS[] =
""
.split(" ");
private static int myInstruction;
private static final int RUN_START = 0;
private static final int SCANNED_START = 0;
private static double myVariables[] = new double[ARRAY_SIZE];
private static Object myObjects[];
public void run()
{
(myObjects = new Object[2])[0] = this;
/*setAdjustGunForRobotTurn(true);
setAdjustRadarForGunTurn(true);
setAdjustRadarForRobotTurn(true);*/
executeCommands(RUN_START);
}
public void onScannedRobot(ScannedRobotEvent e)
{
myObjects[1] = e;
executeCommands(SCANNED_START);
}
private static String getNext()
{
return COMMANDS[myInstruction++];
}
private static void executeCommands(int startIndex)
{
myInstruction = startIndex;
try
{
while(true)
{
// 2 codesize used to maintain prefix convention
int command = Integer.parseInt(getNext());
int value0 = (int) getNextValue();
double value1 = getNextValue();
if (command == CMD_SET)
{
myVariables[value0] = value1;
}
// Default to CMD_IF
// For goto use CMD_IF [Location] 0.0
else
{
//double value0 = getNextValue();
if (value1 == 0D)
{
myInstruction = value0;
}
}
}
}
catch (Exception ex)
{
// This should occur whenever there is no more code to execute
// OR if there is syntax error in the code being interpreted
//ex.printStackTrace();
}
}
private static double getNextValue()
{
String command = getNext();
try
{
int nextInt;
if ((nextInt = Integer.parseInt(command)) == CMD_CALL)
{
// Syntax: [# Parameters] [Parameters] [Class Name] [Method Name] [Object Index]
// Since there is no try-catch block dedicated to the method call,
// CMD_CALL is returned if the method returns null
//try
{
Class classes[] = new Class[(int) getNextValue()];
Object objects[] = new Object[classes.length];
for (int i = 0; i < classes.length; i++)
{
classes[i] = double.class;
objects[i] = Double.valueOf(getNextValue());
}
return ((Number) Class.forName(getNext()).getMethod(getNext(), classes).invoke
(myObjects[(int) getNextValue()], objects)).doubleValue();
}
//catch (NullPointerException ex)
//{
//}
//catch (Exception ex)
//{
//ex.printStackTrace();
//}
//return 0D;
}
double value0 = getNextValue();
if (nextInt == CMD_VAR_VAL)
{
return myVariables[(int) value0];
}
if (nextInt == CMD_SUBTRACT)
{
return value0 - getNextValue();
}
//if (nextInt == CMD_DIVIDE)
return value0 / getNextValue();
}
catch (Exception ex)
{
//ex.printStackTrace();
// Integer.parseInt(getNext()) consumes the double so it has to go back
return Double.parseDouble(command);
}
}
}