![]() | Gute Spiele mit Igel | |||
| Unsere Spiele Über uns Events Sonstiges Kontakt Bestellinfo | ||||

abstract class Strategy
{
int maxSteps;
int stepBonus;
int opponents;
int maxPlayableNumber;
// You have to keep that method since it is final
final public void init(int maxSteps, int maxPlayableNumber,
int stepBonus, int opponents)
{
this.maxSteps = maxSteps;
this.stepBonus = stepBonus;
this.opponents = opponents;
this.maxPlayableNumber = maxPlayableNumber;
priv_init();
}
// Overload this procedure to do your own
// initialization:
void priv_init()
{
}
// Overload this procedure to decide your first turn:
abstract public int initial_turn();
// Overload this procedure to decide further turns:
abstract public int turn(int last_turns[], int scores[],
int carryOver, int turn_no);
// This hook is usually ignoreable but was necessary
// for the PlayYourSelf strategy!
public void destroy()
{
}
public void show()
{
}
public void hide()
{
}
}
}
|
Yes I see the coding is not entirely consistent about the naming convention for variables, but I didn't know the Sun conventions when I started that project.
To derive your own version you need to override the following methods:
| priv_init | for special initialization |
| initial_turn | for the first turn in the game |
| turn | for all further turns |
The only method of the above which uses parameters is turn . The parameters have the following meaning:
| last_turns | contains the last bets of all strategies. Note the strategies own last turn is located at index 0. The existing indices are 0 to (number of players-1). |
| scores | contains the accumulated points of all strategies. Indices work as for last_turns. |
| carryOver | contains the points of the pot carried over from last round |
| turn_no | is the number of the current round. |
To make programming easier every sub class of strategy should use the following variables which are set appropriately during initialization:
| maxPlayableNumber | The highest number a strategy can play legaly (default is 99). |
| stepBonus | amount added to the pot by the bank every turn (default is 1). |
| opponents | Number of opponents found during initialization. To find the currently living you have to count dead ones (score less or equal zero). |
| maxSteps | has no meaning yet. |
If your strategy needs any other information it could derive them from that information and should do its own bookkeeping. Somewhere below there is an example of simple bookkeeping
Note: If I get classes which exhaust CPU time or memory I might have to exclude them from participation. But I think there should be many interesting strategies with a reasonable amount of resource consumption.
This very simple strategy shows that a simple strategy is coded fairly simple:
class Strat23 extends Strategy
{
public int initial_turn()
{
return 2;
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
// What did we do last time?
return last_turns[0] == 2 ? 3 : 2;
}
}
|
You can also derive your own subclasses which have a common behaviour, e.g.:
class StratConst extends Strategy
{
public int initial_turn()
{
return 1;
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
return last_turns[0];
}
}
class Const2 extends StratConst
{
public int initial_turn()
{
return 2;
}
}
|
A randomized player:
class Random11 extends Strategy
{
public int initial_turn()
{
return (int) (Math.random() * 11.0 + 1);
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
return initial_turn();
}
}
|
This is a very simple strategy which does a bit of own bookkeeping:
class Nihilist extends Strategy
{
public int average, sum;
public int initial_turn()
{
return 0;
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
sum += carryOver;
average = sum / turn_no;
if ( carryOver > average )
return 1;
else
return 0;
}
}
|

// Play the number which would have made highest
// gain in last turn.
class Shark5 extends Strategy
{
public int initial_turn()
{
return 1;
}
// A tiny little turn-evaluator:
int eval(int turns[], int carry, int scores[])
{
int i, j, sum, t, parts, t0;
sum = carry;
parts = 0;
t0 = 0;
for (i = 0; i < opponents; i++) if ( scores[i] > 0 )
{
if ( turns[i] > 0 )
{
sum += turns[i];
t = 0;
for (j = 0; j < opponents; j++)
{
if ( turns[j] > 0 && turns[i] >= turns[j] ) t++;
}
if (i == 0) t0 = t;
parts += t;
}
}
sum += stepBonus;
if ( parts == 0 ) return 0;
return (int) ( sum * t0 ) / parts - turns[0];
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
int i, i0, w, w0;
w0 = - maxPlayableNumber;
i0 = 0;
for (i = 0; i <= maxPlayableNumber; i++)
{
last_turns[0] = i;
w = eval(last_turns, carryOver, scores);
if ( w > w0 )
{
w0 = w;
i0 = i;
}
}
return i0;
}
}
|
// Play the number which would have made highest
// gain in last 2 turns.
class Shark6 extends Shark5
{
public int initial_turn()
{
return 0;
}
int lt[];
void priv_init()
{
// Allocate memory to remember previous turns:
lt = new int[opponents];
}
public int turn(int last_turns[], int scores[],
int carryOver, int turn_no)
{
int i, i0, w, w0;
if ( turn_no <= 1 )
{
i0 = 0;
}
else
{
w0 = - maxPlayableNumber;
i0 = 0;
for (i = 0; i <= maxPlayableNumber; i++)
{
last_turns[0] = i;
lt[0] = i;
w = eval(last_turns, carryOver, scores)
+eval(lt,carryOver, scores);
if ( w > w0 )
{
w0 = w;
i0 = i;
}
}
}
for (i = 0; i < opponents; i++) lt[i] = last_turns[i];
return i0;
}
}
|
A few pages further ahead there can be found more samples of strategy source code .
And please forget about the examples: Try s.th. completely different! Just take the examples as demonstrations of the technique. 
SUN-Microsystems . There you find the JDKs: Java Development Kits. Since Numfield is stone age Java any version published should be enough (1.02 and above).OK, thats all by now. Now its your turn!