Adding a Java Class
If you have not already, open the Project Malmö project in your IDE. I use IntelliJ, and so will be presenting the steps for it, but the steps in Eclipse should be about the same.
Now, we are going to add a new Java class. In IntelliJ, look for the
folder MissionHandlers
. Then, right-click on the folder,
select New
and then Java Class
. When a pop-up window opens,
type the name as RewardForStructureCopyingImplementation
.
The name must be exactly this since the function
createHandlerFromParams
in the class MissionBehavior
looks
for a class named RewardForStructureCopying
(the Schema name)
followed by Implementation
. Try to verify this by opening the
MissionBehavior
class. To do so, you can use one of the many nifty
tools IntelliJ and IDEs in general provide: Search. In IntelliJ, you
can click the shift button twice to bring up Search.
Subclassing and Interfaces
Open the RewardForStructureConstruction
class again.
At this point, have a look at the code for some of the other Reward
Handlers under MissionHandlers
. There are a few things
that are worth noting. Firstly, all of them extend or in other words
subclassHandlerBase
(meaning some fields or functions are
inherited from the superclass HandlerBase
while others must be
implemented or "overriden" so as to change the functionality of some
methods). Also, all of the Reward Handlers implement
IRewardProducer
, an interface. This means that all the Reward
Handlers follow some protocol and can be treated in the same manner
given that they implement the methods necessary according to the
Interface.
With the above said, change the RewardForStructureCopying
class
so that you make the two changes. This means that you will now have
something like this:
public class RewardForStructureCopyingImplementation extends HandlerBase implements IRewardProducer{
}
Generate Superclass and Interface functions
You might now notice that the IDE complains about some errors. These errors are due to the fact that we have not yet implemented some functions we have guaranteed to based on our class definition (in particular the extends and implements bit).
We will now add some functions from the classes we have inherited or
the interfaces we have said we will implement. In IntelliJ, right-click
anywhere inside the brackets enclosing the class definitions and fields.
Now, choose Generate...
followed by Override Methods...
.
Alternatively, place your cursor between the brackets and hit
Ctrl + o
. Now, choose
parseParameters(params:Object):boolean
under
com.microsoft.Malmo.MissionHandlers.HandlerBase
. Next,
hold the Ctrl
key and without leaving the key select
getReward(missionInit:MissionInit):float
,
prepare(missionInit:MissionInit):void
and
cleanup():void
, all of which are under
com.microsoft.Malmo.MissionHandlerInterfaces.IRewardProducer
.
You may leave the Ctrl
key and now using the using the mouse,
if they are not already checked,
click on Copy JavaDoc
and Insert @Override
.
Note: the Ctrl
key may not work if you are on a Mac for example.
In this case, just choose the above methods one by one by
repeating the steps.
You should now have something like this:
public class RewardForStructureConstructionImplementation extends HandlerBase implements IRewardProducer {
/**
* Attempt to parse the given object as a set of parameters for this handler.
*
* @param params the parameter block to parse
* @return true if the object made sense for this handler; false otherwise.
*/
@Override
public boolean parseParameters(Object params) {
return super.parseParameters(params);
}
/**
* Get the reward value for the current Minecraft state.
*
* @param missionInit the MissionInit object for the currently running mission,
* which may contain parameters for the reward requirements.
* @return a float determining the current reward signal for the learning agent
*/
@Override
public float getReward(MissionInit missionInit) {
return 0;
}
/**
* Called once before the mission starts - use for any necessary initialisation.
*
* @param missionInit
*/
@Override
public void prepare(MissionInit missionInit) {
}
/**
* Called once after the mission ends - use for any necessary cleanup.
*/
@Override
public void cleanup() {
}
}