[rules-dev] pacman

Mark Proctor mproctor at codehaus.org
Mon Nov 16 08:55:01 EST 2009


For anyone interested i just did an initial commit for the rudementary 
implementation parts for a Pacman game. Loads a Grid  and a Character 
into the working memory and listens to the arrow keys to move the 
Character around (text output only). It only accepts valid directions 
and the Character cannot move off the grid, and score is updated as it 
eats Food.

It also demostrates entry and exit points. For instance this rule has 
it's "KeyListener" entry point hooked up to a KeyListener impl that 
inserts KeyEvents. From the KeyEvent it creates a Derived (not in 
working memory) possible Direction, validates that Direction. If valid 
the old Direction is retracted and the new one inserted. I use the 
exitpoint to send print information to a channel, which is appended to 
the GUI.

/**
 * Detects a new keypress (release). Creates derived possible Direction 
and validates it.
 * If the Direction is valid, delete the old Direction and replace with 
the new one.
 */
rule keyListenerRule dialect "mvel" when
    $keyEvent : KeyEvent() from entry-point "KeyListener"
    $l : Location()
    $newD : Direction() from createDirection( $l.character, $keyEvent )
    $target : Cell( row == ($l.row + $newD.vertical), col == ($l.col + 
$newD.horizontal) )
    CellContents( cell == $target, cellType != CellType.WALL )   
    $oldD : Direction( character == $l.character )
then
    exitPoints["ConsoleExitPoint" ].insert( "insert " + $newD + "\n" );
    retract( $keyEvent );
    retract( $oldD );
    insert( $newD );
end

As the Tick, simulated time, increases we attempt to change it's 
Location based on the given Direction. We make sure the new Location is 
valid, and if so schedule the new Location, in time with the Tick.
/**
 * Checks that the current Direction moves to a valid location, i.e. not 
a WALL.
 * It does not set the new direction straight away, this is because we 
need movement to be intime
 * with the Tick increase, so we schedule the new Location instead.
 */
rule validDirection dialect "mvel" when
    $l : Location( )
    $d : Direction( character == $l.character )
    $target : Cell( row == ($l.row + $d.vertical), col == ($l.col + 
$d.horizontal) )
    CellContents( cell == $target, cellType != CellType.WALL )
    not ScheduledLocationUpdate( location == $l )   
    $t : Tick() 
then
    insert( new ScheduledLocationUpdate($l, $l.row += $d.vertical, 
$l.col += $d.horizontal, $t.tock + 1) );
end

/**
 * When the Tick increases, update any Locations from inserted scheduled 
updates.
 */
rule setNewDirection dialect "mvel" when
    $s : ScheduledLocationUpdate()
    $l : Location( this == $s.location )
    Tick( tock == $s.tock )
then
   exitPoints["ConsoleExitPoint"].insert( "set new Location " + $l + 
"\n"  );
   modify( $l ) { row = $s.row, col = $s.col };
   retract( $s );
end

Notice the whole thing id driven relationally, because everything is 
linked relationally we can exploit that to drive the engine 
declaratively with only a few rules.

I've committed everything to drools-examples for now, you'll need drools 
trunk, as there are a few fixes necessary for this to work:
http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/java/org/drools/examples/pacman/
http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/resources/org/drools/examples/pacman/
http://anonsvn.jboss.org/repos/labs/labs/jbossrules/trunk/drools-examples/drools-examples-drl/src/main/rules/org/drools/examples/pacman/

The grid1.dat holds the grid layout, it's a declarative symbol layout, 
trivial to change to explore new grids.

It's still very basic. Next I want to work on variable speed for 
characters, then I'll start to add Monsters and power pellets. Once we 
have the full backend working, the idea is to hook it up to an existing 
pacman gui such as SwtPacman. SwtPacman source code is available here:
http://www.jboss.org/community/wiki/pacman

I'll probably blog this later, as a few more bits are added. But 
hopefully this will start to demonstrate to people some more complex 
problems, and also help drive the drools team on how to improve our 
language and engine.

Mark



More information about the rules-dev mailing list