Assignments 1.1
Updated version for MoJ 1.1 beta
updated : 1-10-2005 : added additional manifest tag.
Writing an assignment for Masters of Java 1.1 consists of 4 steps :
- Writing the assignment text.
- Writing Source Code for the contestant to use.
- Writing the test cases to verify the implementation.
- Make a package of it
This is the first bit that the contestant reads. It should consist of four parts :
- an introduction, setting the scene of the assignment.
- Then the assignment itself listing the concrete points to implement.
- Followed by an example, making the it real.
- And finally some hints on how to proceed.
Step 2 : Writing the Java Sources
These are the source code files presented to the contestant to use, one of which is editable. Typically this is an interface, a concrete class to implement and maybe some utility classes to shorten implementation time. To aid the contestant these classes and interfaces should be fully javadocced. Also note that these classes should reside in the 'default' package (i.e. no package statement)
These files should be plain text files with a .java extension.
Step 3 : Writing the TestCases
This is done by implementing the nl.moj.model.Tester.Testable interface. In version 1.1 of MoJ the base class to extend from nl.moj.test.AbstractTestable is deprecated. There is no longer any need to randomize the tests yourself, the engine will do this. If you want backward compatability with MoJ 1.0 however you should still extend this class. There are still 4 methods to implement :
| int getTestCount() | returns the number of tests in this testable. |
| String getTestName(int nr); | returns the name of the test with index nr. |
| String getTestDescription(int nr); | returns the description of the test with index nr. |
| boolean performTest(int nr) throws Throwable; | performs the specified test. Returns true if succesful. |
If you want to create an assignment that produces visual output you need to implement another interface : nl.moj.model.Tester.AnimatedTestable. This interface extends Testable and declares one additional method :
| performTest(int nr,Anim[] a) throws Throwable; | performs the specified test. Returns true if succesful. Allows the setting of an animation as a result. |
As this method is basically a replacement for the performTest method in Testable, you should provide a stub implementation for backward compatibility :
/**
* Method for backward compatibility with Tester.Testable
* @see nl.moj.model.Tester.Testable#performTest(int)
*/
public boolean performTest(int nr) throws Throwable {
return performTest(nr,new Anim[getTestCount()]);
}
A good test-set not only verifies the correctness of the solution, but also has an increasing level of difficulty. The first test-cases should be easy to solve without having to read the full assignment description. This allows the guy behind the keyboard to start typing right away while the other team member reads the assignment fully.
Creating animation is very much beta at this moment, but typically involves the following steps:
- Create a new LayeredAnim()
- Create the required Bitmap,Shape and Sprite resources.
- Create a new Frame.
- Add the resources you want in this frame to the frame together with the position(x,y) and angle.
- Repeat the previous two steps until your animation is complete.
// LayeredAnim a=new LayeredAnim(); // LayeredAnim.BitMapResource whiteSheep=a.createBitmapResource(); whiteSheep.setImageData( nl.moj.client.Sheep.whiteSheepColors, nl.moj.client.Sheep.pixels ); // LayeredAnim.ShapeResource grass=a.createShapeResource().set( LayeredAnim.ShapeResource.SHAPE_RECT, new Color(0xE0FFE0),(short)100,(short)100 ); // LayeredAnim.AnimFrame frame=a.createNewFrame(); // frame.add(grass,0,0,0); frame.add(whiteSheep,50,50,180); // frame=a.createNewFrame(); // frame.add(grass,0,0,0); frame.add(whiteSheep,50,52,178); //
The resources are re-used each frame. Only the position and rotation are stored. If you want to re-use an image (to create lotsa sheep :-) you can use the createSpriteResource(Resource) method. Note that the resulting animation should not contain too many objects or too many frames. Good rule of thumb values are max 15 objects and 200 frames.
Step 4 : Packaging
Packaging has changed a lot in MoJ 1.1. In the old MoJ 'packaging' was creating 3 different files. In MoJ 1.1 a package is a single jar file containing both the test-classes, source code, description and packaging information. A lot better !
The contents of a typical MoJ 1.1 assignment jar file looks like this :
- assignment.txt - SomeJavaSource.java - TheEditableJavaSource.java - AnotherJavaSource.java - TestSet.class - TestSet$1.class - HelperClass.class - meta-inf/manifest.mf - icon.png - sponsor.png
The text file contains the assignment description. The .java are the files the player will see. Only one can be editable. The .class files form the test-set. The manifest.mf file lists the important features of the assignment the MoJ needs to know :
- Editable : lists the (space separated) user editable files in the jar. Note that the current client can handle only one editable file.
- Monospaced : if the description must be rendered in a monospace font.
- SecurityDelegate : the class name of the security delegate (optional)
- TestClass : the class name of the test class.
- SubmitClass : the class name of the submit class (may be identical to the test class)
- TestClassTimeout : max duration in seconds of the tests.
- SubmitClassTimeout : max duration in seconds of the submit tests.
- Author : the (optional) Author of the assignment.
- Icon : the (optional) file name of the assignment Icon (64x64).
- SponsorImage : the (optional) file name of the sponsor image (96x64).
- DisplayName : the (optional) name for displaying purposes.
Manifest-Version: 1.0 Editable: TheEditableJavaSource.java Monospaced: True TestClass: TestSet SubmitClass: TestSet TestClassTimeout: 15 SubmitClassTimeout: 20 Author: Ing.R.A.Bor Icon: icon.png SponsorImage: sponsor.png DisplayName: Major Headache
The SecurityDelegate attribute allows you to replace the default testcase Security module with your own (to allow more things - like reflection :-) Its value is a class-name. This class should have a no-args constructor and implement the nl.moj.model.Tester.SecurityDelegate interface. Have a look at nl.moj.security.DefaultSecurityDelegate for details.

