|
From: Magnus L. <io...@ne...> - 2003-01-18 14:13:38
|
Hi!
Some thoughts on architechture around rules:
I have intentionally shorted the code so there
are few modifiers and no throws clauses here.
The Basic idea is: When a Move is to be made we find
the Rules that applies to that move. Checks if the move
is legal, then the Move is executed. After that the Rules
get to check the new GameState to see if we should alter
it. For example enter a new Phase or declare the end
of the Game.
The intention to encourage the implementer of a Game to
structure the rules instead of writing one huge Rule class
with "if-else if" clauses. And also make it possible to
have rules that applies to certain pieces or cards.
-- Code section --
/**
* Generic Move interface used to describe an action that
* a player makes. Could be moving a piece, playing a Card etc
*
*/
interface Move {
GameBean[] getInvolvedBeans();
Player getPlayer();
/**
* Updates the game state when this Move is made.
* This method will only be called if it is legal
* to execute this Move.
*/
void update(GameState gs);
}
interface Player { }
interface Game {
GameState getCurrentState();
RuleBook getRuleBook();
/**
* Checks if the move is legal and if so will update the
* GameState.
*/
void execute(Move m);
}
/**
* Holds all information about the current game situation.
* Such as stage, phase, pieces, cards played etc etc.
*/
interface GameState {}
interface RuleBook {
/**
* Checks all rules that applies to the move and current game state
* sorts them and returns them.
*/
Rule[] getRules(Move m, GameState gs);
void addRule(Rule r);
/**
* Overrides an old Rule with a new one.
* If the Condition for the new Rule is met then only that Rule
* will be checked. If the old Rule's Condition is met and the
* not the newVersion's, then the old rule is checked.
*
*/
void overrideRule(Rule toOverride, Rule newVersion);
}
interface Rule extends Comparable {
Condition getCondition();
boolean isLegal(Move m, GameState gs);
//Possibly there should be different types of rules
//One for legal checks and another for post conditions.
void postMoveCheck(GameState gs);
int compareTo(Object obj);
}
/**
* Used to describe when a Rule applies.
*/
interface Condition {
boolean doesApply(Move m, GameState gs);
/**
* Condition for rules that should always be checked.
*/
Condition ALWAYS = new Condition(){
public boolean doesApply(Move m, GameState gs){
return true;
}
}
}
/**
* Used to describe a Condition for Rules that
* applies when certain GameBeans are involved
* in the Move.
*/
class BasicCondition {
GameBean[] appliesTo;
public boolean doesApply(Move m, GameState gs){
for(int i = 0; i < appliesTo.length; i++){
for(int j = 0; j < m.getInvolvedBeans().length; j++){
if(appliesTo[i].equals(m.getInvolvedBeans()[j])){
return true;
}
}
}
return false;
}
}
--
Magnus Lundgren
|