[jboss-svn-commits] JBL Code SVN: r26843 - in labs/jbossrules/contrib/lotrc: src and 24 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Jun 4 21:28:12 EDT 2009


Author: tirelli
Date: 2009-06-04 21:28:11 -0400 (Thu, 04 Jun 2009)
New Revision: 26843

Added:
   labs/jbossrules/contrib/lotrc/.classpath
   labs/jbossrules/contrib/lotrc/.project
   labs/jbossrules/contrib/lotrc/pom.xml
   labs/jbossrules/contrib/lotrc/src/
   labs/jbossrules/contrib/lotrc/src/main/
   labs/jbossrules/contrib/lotrc/src/main/java/
   labs/jbossrules/contrib/lotrc/src/main/java/org/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/Main.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/Action.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CharacterDefeatedAction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatAction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatStatus.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveAction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveStatus.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlaceCharacterAction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlayCardAction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/IsAdjacentToEvaluatorDefinition.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/TowardsEvaluatorDefinition.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/RandomSelectAccumulateFunction.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Ability.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Allegiance.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Board.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Card.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardAbility.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardImpl.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardName.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardStatus.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Character.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterAbility.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterImpl.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterName.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterStatus.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Game.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Model.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Region.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionImpl.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionName.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Winner.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/AbstractDroolsPlayer.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/FellowshipPlayer.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/Player.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/SauronPlayer.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/MakeAMove.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayACard.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayerCommand.java
   labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/SetupCharacter.java
   labs/jbossrules/contrib/lotrc/src/main/resources/
   labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/
   labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/drools.packagebuilder.conf
   labs/jbossrules/contrib/lotrc/src/main/resources/log4j.properties
   labs/jbossrules/contrib/lotrc/src/main/rules/
   labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/
   labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/fellowship.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/game/
   labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.rf
   labs/jbossrules/contrib/lotrc/src/main/rules/game/gameflow.rf
   labs/jbossrules/contrib/lotrc/src/main/rules/game/misc.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/game/move.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/game/setup.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/game/victory.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/players/
   labs/jbossrules/contrib/lotrc/src/main/rules/players/common.drl
   labs/jbossrules/contrib/lotrc/src/main/rules/sauron/
   labs/jbossrules/contrib/lotrc/src/main/rules/sauron/sauron.drl
   labs/jbossrules/contrib/lotrc/src/test/
   labs/jbossrules/contrib/lotrc/src/test/java/
   labs/jbossrules/contrib/lotrc/src/test/java/org/
   labs/jbossrules/contrib/lotrc/src/test/java/org/drools/
   labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/
   labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/TowardsEvaluatorTest.java
Modified:
   labs/jbossrules/contrib/lotrc/
Log:
Checking in the initial version of the project


Property changes on: labs/jbossrules/contrib/lotrc
___________________________________________________________________
Name: svn:ignore
   + target/*
.project
.classpath
resources/*


Added: labs/jbossrules/contrib/lotrc/.classpath
===================================================================
--- labs/jbossrules/contrib/lotrc/.classpath	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/.classpath	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main/java"/>
+	<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
+	<classpathentry excluding="**/*.java" kind="src" path="src/main/rules"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="var" path="M2_REPO/org/antlr/antlr-runtime/3.1.1/antlr-runtime-3.1.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/eclipse/jdt/core/3.4.2.v_883_R34x/core-3.4.2.v_883_R34x.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/drools/drools-api/5.0.1/drools-api-5.0.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/drools/drools-compiler/5.0.1/drools-compiler-5.0.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/drools/drools-core/5.0.1/drools-core-5.0.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-library/1.1/hamcrest-library-1.1-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/janino/janino/2.5.15/janino-2.5.15.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/jmock/jmock/2.5.1/jmock-2.5.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/joda-time/joda-time/1.6/joda-time-1.6.jar"/>
+	<classpathentry kind="var" path="M2_REPO/junit/junit/3.8.1/junit-3.8.1.jar" sourcepath="M2_REPO/junit/junit/3.8.1/junit-3.8.1-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/apache-log4j/log4j/1.2.15/log4j-1.2.15.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/mvel/mvel2/2.0.10/mvel2-2.0.10.jar"/>
+	<classpathentry kind="var" path="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar" sourcepath="M2_REPO/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c-sources.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/thoughtworks/xstream/xstream/1.3.1/xstream-1.3.1.jar"/>
+	<classpathentry kind="con" path="DROOLS/Drools"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>


Property changes on: labs/jbossrules/contrib/lotrc/.classpath
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/.project
===================================================================
--- labs/jbossrules/contrib/lotrc/.project	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/.project	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,16 @@
+<projectDescription>
+  <name>lotrc</name>
+  <comment/>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.drools.eclipse.droolsbuilder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/.project
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/pom.xml
===================================================================
--- labs/jbossrules/contrib/lotrc/pom.xml	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/pom.xml	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,98 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.drools.examples</groupId>
+	<artifactId>lotrc</artifactId>
+	<packaging>jar</packaging>
+	<version>1.0-SNAPSHOT</version>
+	<name>lotrc</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>3.8.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.jmock</groupId>
+			<artifactId>jmock</artifactId>
+			<version>2.5.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.drools</groupId>
+			<artifactId>drools-api</artifactId>
+			<version>5.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.drools</groupId>
+			<artifactId>drools-core</artifactId>
+			<version>5.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>org.drools</groupId>
+			<artifactId>drools-compiler</artifactId>
+			<version>5.0.1</version>
+		</dependency>
+		<dependency>
+			<groupId>apache-log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<version>1.2.15</version>
+		</dependency>
+		<dependency>
+			<groupId>com.thoughtworks.xstream</groupId>
+			<artifactId>xstream</artifactId>
+			<version>1.3.1</version>
+		</dependency>
+	</dependencies>
+
+	<repositories>
+		<repository>
+			<id>repository.jboss.org</id>
+			<url>http://repository.jboss.org/maven2</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+			<releases>
+				<enabled>true</enabled>
+			</releases>
+		</repository>
+	</repositories>
+
+	<build>
+		<resources>
+			<resource>
+				<directory>src/main/resources</directory>
+			</resource>
+			<resource>
+				<directory>src/main/rules</directory>
+			</resource>
+		</resources>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-eclipse-plugin</artifactId>
+				<configuration>
+					<additionalBuildcommands>
+						<buildcommand>org.drools.eclipse.droolsbuilder</buildcommand>
+					</additionalBuildcommands>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+					<archive>
+						<manifest>
+							<mainClass>${project.mainClass}</mainClass>
+							<addClasspath>true</addClasspath>
+						</manifest>
+					</archive>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+</project>


Property changes on: labs/jbossrules/contrib/lotrc/pom.xml
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/Main.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/Main.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/Main.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,122 @@
+package org.drools.examples.lotrc;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.PropertyConfigurator;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.audit.WorkingMemoryFileLogger;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
+import org.drools.builder.KnowledgeBuilderError;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.examples.lotrc.model.Card;
+import org.drools.examples.lotrc.model.Game;
+import org.drools.examples.lotrc.model.Region;
+import org.drools.examples.lotrc.player.FellowshipPlayer;
+import org.drools.examples.lotrc.player.Player;
+import org.drools.examples.lotrc.player.SauronPlayer;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.StatefulKnowledgeSession;
+
+/**
+ * The main entry point for the Lord of the Rings: Confrontation game
+ * 
+ * @author etirelli
+ */
+public class Main {
+    static final Logger                     logger = Logger.getLogger( "Game" );
+
+    private static KnowledgeBase            kbase;
+    private static StatefulKnowledgeSession ksession;
+
+    private static WorkingMemoryFileLogger audit;
+
+    public static void main(String[] args) {
+        initResources();
+        initRulebase();
+        initSession();
+        run();
+    }
+
+    private static void initResources() {
+        PropertyConfigurator.configure(Main.class.getResource( "/log4j.properties" ));
+    }
+
+    private static void initRulebase() {
+        logger.debug( "Creating knowledge base" );
+        KnowledgeBuilderConfiguration conf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
+        KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder( conf );
+        String[] resources = new String[] { "game/combat.rf", "game/gameflow.rf", "game/setup.drl", 
+                                            "game/move.drl", "game/combat.drl", "game/victory.drl", 
+                                            "game/misc.drl" };
+        addGameResources( builder, resources );
+        if ( builder.hasErrors() ) {
+            for ( KnowledgeBuilderError error : builder.getErrors() ) {
+                logger.error( error );
+            }
+            System.exit( 0 );
+        }
+        logger.debug( "Knowledge packages successfuly compiled." );
+        kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( builder.getKnowledgePackages() );
+        logger.debug( "Knowledge Base successfuly created" );
+    }
+
+    private static void addGameResources(KnowledgeBuilder builder, String[] resources ) {
+        int previous = 0;
+        for( String resource : resources ) {
+            //logger.debug( "Loading "+resource );
+            builder.add( ResourceFactory.newClassPathResource( resource ),
+                         resource.endsWith( ".rf" ) ? ResourceType.DRF : ResourceType.DRL );
+            int newSize = builder.getKnowledgePackages().iterator().next().getRules().size();
+            logger.info( "Loaded: "+resource+" with "+(newSize-previous)+" rules." );
+            previous = newSize;
+        }
+        logger.info( "All resources loaded. Total of "+previous+" rules." );
+    }
+
+    private static void initSession() {
+        logger.debug( "Creating Knowledge Session" );
+        ksession = kbase.newStatefulKnowledgeSession();
+        ksession.setGlobal( "logger", logger );
+        
+        audit = new WorkingMemoryFileLogger( ksession );
+        audit.setFileName( "game" );
+                
+        logger.debug( "Creating Game objects" );
+        Player sauron = new SauronPlayer();
+        Player fellowship = new FellowshipPlayer();
+        Game game = new Game(sauron, fellowship);
+        
+        logger.debug( "Initializing session with game data" );
+        ksession.insert( sauron );
+        ksession.insert( fellowship );
+        ksession.insert( game );
+        ksession.insert( game.getBoard() );
+        Region[][] regions = game.getBoard().getRegions();
+        for( Region[] row : regions ) {
+            for( Region site : row ) {
+                ksession.insert( site );
+            }
+        }
+        for( org.drools.examples.lotrc.model.Character character : game.getCharacters() ) {
+            ksession.insert( character );
+        }
+        for( Card card : game.getCards() ) {
+            ksession.insert( card );
+        }
+    }
+
+    private static void run() {
+        logger.debug( "Starting Game Flow" );
+        ksession.startProcess( "Game Flow" );
+        logger.debug( "Firing rules" );
+        ksession.fireAllRules();
+        logger.debug( "Session finished" );
+        if( audit != null ) {
+            audit.writeToDisk();
+        }
+    }
+    
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/Main.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/Action.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/Action.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/Action.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+
+/**
+ * An interface for all actions
+ * 
+ * @author etirelli
+ */
+public interface Action {
+    
+    /**
+     * Returns the allegiance of the player that executed the action
+     * 
+     * @return
+     */
+    public Allegiance getAllegiance(); 
+    
+    /**
+     * Returns a clone of the current action, but with equivalent 
+     * hidden information
+     * 
+     * @return
+     */
+    public Action getHidden();
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/Action.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CharacterDefeatedAction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CharacterDefeatedAction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CharacterDefeatedAction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.CharacterName;
+
+/**
+ * An action representing a character that has just been defeated
+ * 
+ * @author etirelli
+ */
+public class CharacterDefeatedAction
+    implements
+    Action {
+
+    private final Allegiance allegiance;
+    private final CharacterName character;
+
+    public CharacterDefeatedAction( Allegiance allegiance, 
+                                    CharacterName character ) {
+        super();
+        this.allegiance = allegiance;
+        this.character = character;
+    }
+    
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+    public CharacterName getCharacterName() {
+        return character;
+    }
+
+    public CharacterDefeatedAction getHidden() {
+        return this;
+    }
+    
+    @Override
+    public String toString() {
+        return "Character defeated:" + character;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CharacterDefeatedAction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatAction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatAction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatAction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.Card;
+import org.drools.examples.lotrc.model.CharacterName;
+import org.drools.examples.lotrc.model.RegionName;
+
+/**
+ * A combat action triggered by a move
+ * 
+ * @author etirelli
+ */
+public class CombatAction
+    implements
+    Action {
+
+    private final Allegiance    allegiance;
+    private final RegionName    region;
+    private final CharacterName attacker;
+    private CharacterName       defender;
+    private CombatStatus        status;
+    private Card                attackerCard;
+    private Card                defenderCard;
+    private int                 result;
+
+    public CombatAction(Allegiance allegiance,
+                        RegionName region,
+                        CharacterName attacker) {
+        super();
+        this.allegiance = allegiance;
+        this.region = region;
+        this.attacker = attacker;
+        this.status = CombatStatus.UNSETTLED;
+    }
+
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+
+    public RegionName getRegionName() {
+        return region;
+    }
+
+    public CharacterName getAttackerName() {
+        return attacker;
+    }
+
+    public CharacterName getDefenderName() {
+        return defender;
+    }
+
+    public void setDefenderName(CharacterName defender) {
+        this.defender = defender;
+    }
+
+    public CombatStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(CombatStatus status) {
+        this.status = status;
+    }
+
+    public CombatAction getHidden() {
+        return this;
+    }
+
+    public Card getAttackerCard() {
+        return attackerCard;
+    }
+
+    public void setAttackerCard(Card attackerCard) {
+        this.attackerCard = attackerCard;
+    }
+
+    public Card getDefenderCard() {
+        return defenderCard;
+    }
+
+    public void setDefenderCard(Card defenderCard) {
+        this.defenderCard = defenderCard;
+    }
+
+    public int getResult() {
+        return result;
+    }
+
+    public void setResult(int result) {
+        this.result = result;
+    }
+    
+    public void prepareForCombat() {
+        setDefenderName( null );
+        setAttackerCard( null );
+        setDefenderCard( null );
+        setResult( 0 );
+        setStatus( CombatStatus.UNSETTLED );
+    }
+
+    @Override
+    public String toString() {
+        return " => "+attacker+"("+attackerCard+") attacks "+defender+"("+defenderCard+") on "+region+" : result is "+result; 
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatAction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatStatus.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatStatus.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatStatus.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+/**
+ * The status of a ongoing combat
+ * 
+ * @author etirelli
+ */
+public enum CombatStatus {
+    
+    UNSETTLED, SETTLED;
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/CombatStatus.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveAction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveAction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveAction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.CharacterName;
+import org.drools.examples.lotrc.model.RegionName;
+
+/**
+ * A Move action representation
+ * 
+ * @author etirelli
+ */
+public class MoveAction
+    implements
+    Action {
+    
+    private final Allegiance allegiance;
+    private final CharacterName character;
+    private final RegionName fromRegion;
+    private final RegionName toRegion;
+    private MoveStatus status;
+    
+    public MoveAction(Allegiance allegiance,
+                      CharacterName character,
+                      RegionName fromRegion,
+                      RegionName toRegion) {
+        super();
+        this.allegiance = allegiance;
+        this.character = character;
+        this.fromRegion = fromRegion;
+        this.toRegion = toRegion;
+        this.status = MoveStatus.ISSUED;
+    }
+    
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+    
+    public CharacterName getCharacterName() {
+        return character;
+    }
+    
+    public RegionName getFromRegion() {
+        return fromRegion;
+    }
+    
+    public RegionName getToRegion() {
+        return toRegion;
+    }
+    
+    public MoveStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(MoveStatus status) {
+        this.status = status;
+    }
+
+    @Override
+    public String toString() {
+        return "["+allegiance+"]("+status+") Moves "+character+" from "+fromRegion+" to "+toRegion+".";
+    }
+
+    public MoveAction getHidden() {
+        return new MoveAction(allegiance, CharacterName.HIDDEN, fromRegion, toRegion );
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveAction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveStatus.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveStatus.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveStatus.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+/**
+ * The status of a move action
+ * @author etirelli
+ *
+ */
+public enum MoveStatus {
+    
+    ISSUED, EXECUTED, INVALID;
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/MoveStatus.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlaceCharacterAction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlaceCharacterAction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlaceCharacterAction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.CharacterName;
+import org.drools.examples.lotrc.model.RegionName;
+
+/**
+ * An action representing the placement of a character in a region
+ * 
+ * @author etirelli
+ */
+public class PlaceCharacterAction
+    implements
+    Action {
+
+    private final Allegiance    allegiance;
+    private final CharacterName character;
+    private final RegionName    region;
+
+    public PlaceCharacterAction(Allegiance allegiance,
+                                CharacterName character,
+                                RegionName region) {
+        super();
+        this.allegiance = allegiance;
+        this.character = character;
+        this.region = region;
+    }
+    
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+
+    public CharacterName getCharacterName() {
+        return character;
+    }
+
+    public RegionName getRegionName() {
+        return region;
+    }
+
+    public PlaceCharacterAction getHidden() {
+        return new PlaceCharacterAction(allegiance, CharacterName.HIDDEN, region );
+    }
+    
+    @Override
+    public String toString() {
+        return "["+allegiance+"] Place " + character + " at " + region;
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlaceCharacterAction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlayCardAction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlayCardAction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlayCardAction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.action;
+
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.CardName;
+
+/**
+ * Represents a card played by a given player for a given combat
+ * 
+ * @author etirelli
+ *
+ */
+public class PlayCardAction
+    implements
+    Action {
+    
+    private final Allegiance allegiance;
+    private final CardName card;
+    
+    public PlayCardAction(Allegiance allegiance,
+                          CardName card) {
+        super();
+        this.allegiance = allegiance;
+        this.card = card;
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.examples.lotrc.action.Action#getAllegiance()
+     */
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.examples.lotrc.action.Action#getHidden()
+     */
+    public Action getHidden() {
+        return this;
+    }
+
+    public CardName getCardName() {
+        return card;
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/action/PlayCardAction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/IsAdjacentToEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/IsAdjacentToEvaluatorDefinition.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/IsAdjacentToEvaluatorDefinition.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.evaluators;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.base.BaseEvaluator;
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.EvaluatorCache;
+import org.drools.base.evaluators.EvaluatorDefinition;
+import org.drools.base.evaluators.Operator;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.examples.lotrc.model.Region;
+import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
+import org.drools.rule.VariableRestriction.VariableContextEntry;
+import org.drools.spi.Evaluator;
+import org.drools.spi.FieldValue;
+import org.drools.spi.InternalReadAccessor;
+
+/**
+ * The implementation of "isAdjacentTo" evaluator
+ * 
+ * @author etirelli
+ */
+public class IsAdjacentToEvaluatorDefinition
+    implements
+    EvaluatorDefinition {
+
+    // ***********************
+    // First we add the operators to the operator registry, so that the parser can automatically
+    // understand them
+    //
+    public static final Operator  IS_ADJACENT_TO      = Operator.addOperatorToRegistry( "isAdjacentTo",
+                                                                                          false );
+    public static final Operator  IS_NOT_ADJACENT_TO  = Operator.addOperatorToRegistry( "isAdjacentTo",
+                                                                                          true );
+
+    // Just as a convenience, we create a cache of the String IDs for the operators
+    private static final String[] SUPPORTED_IDS         = {IS_ADJACENT_TO.getOperatorString()};
+
+    // And we cache the evaluators themselves, so that they can be reused.
+    // NOTE: the evaluators implement the GoF "fly weight" pattern
+    private EvaluatorCache        evaluators            = new EvaluatorCache() {
+                                                            private static final long serialVersionUID = 4782368623L;
+                                                            {
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_ADJACENT_TO,
+                                                                              IsAdjacentToEvaluator.POSITIVE_INSTANCE );
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_NOT_ADJACENT_TO,
+                                                                              IsAdjacentToEvaluator.NEGATIVE_INSTANCE );
+                                                            }
+                                                        };
+
+    // ***************************************************************
+    // The method implementations are all retrieval methods that read the cache
+    //
+
+    /**
+     * The implementation must support serialization
+     */
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        evaluators = (EvaluatorCache) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject( evaluators );
+    }
+
+    /**
+     * @inheridDoc
+     */
+    public Evaluator getEvaluator(ValueType type,
+                                  Operator operator) {
+        return this.evaluators.getEvaluator( type,
+                                             operator );
+    }
+
+    /**
+     * @inheridDoc
+     */
+    public Evaluator getEvaluator(ValueType type,
+                                  Operator operator,
+                                  String parameterText) {
+        return this.evaluators.getEvaluator( type,
+                                             operator );
+    }
+
+    public Evaluator getEvaluator(final ValueType type,
+                                  final String operatorId,
+                                  final boolean isNegated,
+                                  final String parameterText) {
+        return this.getEvaluator( type,
+                                  operatorId,
+                                  isNegated,
+                                  parameterText,
+                                  Target.FACT,
+                                  Target.FACT );
+
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Evaluator getEvaluator(final ValueType type,
+                                  final String operatorId,
+                                  final boolean isNegated,
+                                  final String parameterText,
+                                  final Target left,
+                                  final Target right) {
+        return this.evaluators.getEvaluator( type,
+                                             Operator.determineOperator( operatorId,
+                                                                         isNegated ) );
+    }
+
+    public String[] getEvaluatorIds() {
+        return SUPPORTED_IDS;
+    }
+
+    public boolean isNegatable() {
+        return true;
+    }
+
+    public Target getTarget() {
+        return Target.FACT;
+    }
+
+    public boolean supportsType(ValueType type) {
+        return this.evaluators.supportsType( type );
+    }
+
+    /*  *********************************************************
+     *           Evaluator Implementations
+     *  *********************************************************
+     */
+    public static class IsAdjacentToEvaluator extends BaseEvaluator {
+        private static final long     serialVersionUID  = 500L;
+
+        public final static Evaluator POSITIVE_INSTANCE = new IsAdjacentToEvaluator( IS_ADJACENT_TO );
+        public final static Evaluator NEGATIVE_INSTANCE = new IsAdjacentToEvaluator( IS_NOT_ADJACENT_TO );
+
+        private boolean               negated;
+
+        public IsAdjacentToEvaluator(Operator operator) {
+            super( ValueType.OBJECT_TYPE,
+                   operator );
+            this.negated = operator == IS_NOT_ADJACENT_TO;
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor,
+                                final Object object1,
+                                final FieldValue object2) {
+            // this is a beta operator, so no alpha calls supported
+            throw new UnsupportedOperationException( getOperator() + " only supports beta constraints." );
+        }
+
+        public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
+                                           final VariableContextEntry context,
+                                           final Object left) {
+            final Region toRegion = (Region) ((ObjectVariableContextEntry) context).right;
+            final Region fromRegion = (Region) context.declaration.getExtractor().getValue( workingMemory,
+                                                                                      left );
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+
+            return this.negated ^ toRegion.isAdjacentTo( fromRegion );
+        }
+
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            final Region toRegion = (Region) context.extractor.getValue( workingMemory,
+                                                                   right );
+            final Region fromRegion = (Region) ((ObjectVariableContextEntry) context).left;
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ toRegion.isAdjacentTo( fromRegion );
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor1,
+                                final Object object1,
+                                final InternalReadAccessor extractor2,
+                                final Object object2) {
+            final Region toRegion = (Region) extractor1.getValue( workingMemory,
+                                                            object1 );
+            final Region fromRegion = (Region) extractor2.getValue( workingMemory,
+                                                              object2 );
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ toRegion.isAdjacentTo( fromRegion );
+        }
+
+        public String toString() {
+            return getOperator().toString();
+        }
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/IsAdjacentToEvaluatorDefinition.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/TowardsEvaluatorDefinition.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/TowardsEvaluatorDefinition.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/TowardsEvaluatorDefinition.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.evaluators;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+
+import org.drools.base.BaseEvaluator;
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.EvaluatorCache;
+import org.drools.base.evaluators.EvaluatorDefinition;
+import org.drools.base.evaluators.Operator;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.examples.lotrc.model.Region;
+import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
+import org.drools.rule.VariableRestriction.VariableContextEntry;
+import org.drools.spi.Evaluator;
+import org.drools.spi.FieldValue;
+import org.drools.spi.InternalReadAccessor;
+
+/**
+ * The implementation of "towardsShire" and "towardsMordor" evaluators
+ * 
+ * @author etirelli
+ */
+public class TowardsEvaluatorDefinition
+    implements
+    EvaluatorDefinition {
+
+    // ***********************
+    // First we add the operators to the operator registry, so that the parser can automatically
+    // understand them
+    //
+    public static final Operator  IS_TOWARDS_SHIRE      = Operator.addOperatorToRegistry( "towardsShire",
+                                                                                          false );
+    public static final Operator  IS_NOT_TOWARDS_SHIRE  = Operator.addOperatorToRegistry( "towardsShire",
+                                                                                          true );
+
+    public static final Operator  IS_TOWARDS_MORDOR     = Operator.addOperatorToRegistry( "towardsMordor",
+                                                                                          false );
+    public static final Operator  IS_NOT_TOWARDS_MORDOR = Operator.addOperatorToRegistry( "towardsMordor",
+                                                                                          true );
+
+    // Just as a convenience, we create a cache of the String IDs for the operators
+    private static final String[] SUPPORTED_IDS         = {IS_TOWARDS_SHIRE.getOperatorString(), IS_TOWARDS_MORDOR.getOperatorString()};
+
+    // And we cache the evaluators themselves, so that they can be reused.
+    // NOTE: the evaluators implement the GoF "fly weight" pattern
+    private EvaluatorCache        evaluators            = new EvaluatorCache() {
+                                                            private static final long serialVersionUID = 4782368623L;
+                                                            {
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_TOWARDS_SHIRE,
+                                                                              TowardsShireEvaluator.POSITIVE_INSTANCE );
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_NOT_TOWARDS_SHIRE,
+                                                                              TowardsShireEvaluator.NEGATIVE_INSTANCE );
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_TOWARDS_MORDOR,
+                                                                              TowardsMordorEvaluator.POSITIVE_INSTANCE );
+                                                                addEvaluator( ValueType.OBJECT_TYPE,
+                                                                              IS_NOT_TOWARDS_MORDOR,
+                                                                              TowardsMordorEvaluator.NEGATIVE_INSTANCE );
+                                                            }
+                                                        };
+
+    // ***************************************************************
+    // The method implementations are all retrieval methods that read the cache
+    //
+
+    /**
+     * The implementation must support serialization
+     */
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        evaluators = (EvaluatorCache) in.readObject();
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        out.writeObject( evaluators );
+    }
+
+    /**
+     * @inheridDoc
+     */
+    public Evaluator getEvaluator(ValueType type,
+                                  Operator operator) {
+        return this.evaluators.getEvaluator( type,
+                                             operator );
+    }
+
+    /**
+     * @inheridDoc
+     */
+    public Evaluator getEvaluator(ValueType type,
+                                  Operator operator,
+                                  String parameterText) {
+        return this.evaluators.getEvaluator( type,
+                                             operator );
+    }
+
+    public Evaluator getEvaluator(final ValueType type,
+                                  final String operatorId,
+                                  final boolean isNegated,
+                                  final String parameterText) {
+        return this.getEvaluator( type,
+                                  operatorId,
+                                  isNegated,
+                                  parameterText,
+                                  Target.FACT,
+                                  Target.FACT );
+
+    }
+
+    /**
+     * @inheritDoc
+     */
+    public Evaluator getEvaluator(final ValueType type,
+                                  final String operatorId,
+                                  final boolean isNegated,
+                                  final String parameterText,
+                                  final Target left,
+                                  final Target right) {
+        return this.evaluators.getEvaluator( type,
+                                             Operator.determineOperator( operatorId,
+                                                                         isNegated ) );
+    }
+
+    public String[] getEvaluatorIds() {
+        return SUPPORTED_IDS;
+    }
+
+    public boolean isNegatable() {
+        return true;
+    }
+
+    public Target getTarget() {
+        return Target.FACT;
+    }
+
+    public boolean supportsType(ValueType type) {
+        return this.evaluators.supportsType( type );
+    }
+
+    /*  *********************************************************
+     *           Evaluator Implementations
+     *  *********************************************************
+     */
+    public static class TowardsShireEvaluator extends BaseEvaluator {
+        private static final long     serialVersionUID  = 500L;
+
+        public final static Evaluator POSITIVE_INSTANCE = new TowardsShireEvaluator( IS_TOWARDS_SHIRE );
+        public final static Evaluator NEGATIVE_INSTANCE = new TowardsShireEvaluator( IS_NOT_TOWARDS_SHIRE );
+
+        private boolean               negated;
+
+        public TowardsShireEvaluator(Operator operator) {
+            super( ValueType.OBJECT_TYPE,
+                   operator );
+            this.negated = operator == IS_NOT_TOWARDS_SHIRE;
+        }
+
+        private boolean isTowardsShire(final Region toRegion,
+                                       final Region fromRegion) {
+            boolean valid = toRegion.getRow() - fromRegion.getRow() == -1;
+            if ( fromRegion.getRow() > 3 ) {
+                valid = valid && ( toRegion.getCol() == fromRegion.getCol() || toRegion.getCol() == (fromRegion.getCol() + 1) );
+            } else {
+                valid = valid && ( toRegion.getCol() == fromRegion.getCol() || toRegion.getCol() == (fromRegion.getCol() - 1) );
+            }
+            return valid;
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor,
+                                final Object object1,
+                                final FieldValue object2) {
+            // this is a beta operator, so no alpha calls supported
+            throw new UnsupportedOperationException( getOperator() + " only supports beta constraints." );
+        }
+
+        public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
+                                           final VariableContextEntry context,
+                                           final Object left) {
+            final Region toRegion = (Region) ((ObjectVariableContextEntry) context).right;
+            final Region fromRegion = (Region) context.declaration.getExtractor().getValue( workingMemory,
+                                                                                      left );
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+
+            return this.negated ^ isTowardsShire( toRegion,
+                                                  fromRegion );
+        }
+
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            final Region toRegion = (Region) context.extractor.getValue( workingMemory,
+                                                                   right );
+            final Region fromRegion = (Region) ((ObjectVariableContextEntry) context).left;
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ isTowardsShire( toRegion,
+                                                  fromRegion );
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor1,
+                                final Object object1,
+                                final InternalReadAccessor extractor2,
+                                final Object object2) {
+            final Region toRegion = (Region) extractor1.getValue( workingMemory,
+                                                            object1 );
+            final Region fromRegion = (Region) extractor2.getValue( workingMemory,
+                                                              object2 );
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ isTowardsShire( toRegion,
+                                                  fromRegion );
+        }
+
+        public String toString() {
+            return getOperator().toString();
+        }
+    }
+
+    public static class TowardsMordorEvaluator extends BaseEvaluator {
+        private static final long     serialVersionUID  = 500L;
+
+        public final static Evaluator POSITIVE_INSTANCE = new TowardsMordorEvaluator( IS_TOWARDS_MORDOR );
+        public final static Evaluator NEGATIVE_INSTANCE = new TowardsMordorEvaluator( IS_NOT_TOWARDS_MORDOR );
+
+        private boolean               negated;
+
+        public TowardsMordorEvaluator(Operator operator) {
+            super( ValueType.OBJECT_TYPE,
+                   operator );
+            this.negated = operator == IS_NOT_TOWARDS_MORDOR;
+        }
+
+        private boolean isTowardsMordor(final Region toRegion,
+                                        final Region fromRegion) {
+            boolean valid = toRegion.getRow() - fromRegion.getRow() == +1;
+            if ( fromRegion.getRow() < 3 ) {
+                valid = valid && ( toRegion.getCol() == fromRegion.getCol() || toRegion.getCol() == (fromRegion.getCol() + 1) );
+            } else {
+                valid = valid && ( toRegion.getCol() == fromRegion.getCol() || toRegion.getCol() == (fromRegion.getCol() - 1) );
+            }
+            return valid;
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor,
+                                final Object object1,
+                                final FieldValue object2) {
+            // this is a beta operator, so no alpha calls supported
+            throw new UnsupportedOperationException( getOperator() + " only supports beta constraints." );
+        }
+
+        public boolean evaluateCachedRight(InternalWorkingMemory workingMemory,
+                                           final VariableContextEntry context,
+                                           final Object left) {
+            final Region toRegion = (Region) ((ObjectVariableContextEntry) context).right;
+            final Region fromRegion = (Region) context.declaration.getExtractor().getValue( workingMemory,
+                                                                                      left );
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+
+            return this.negated ^ isTowardsMordor( toRegion,
+                                                   fromRegion );
+        }
+
+        public boolean evaluateCachedLeft(InternalWorkingMemory workingMemory,
+                                          final VariableContextEntry context,
+                                          final Object right) {
+            final Region toRegion = (Region) context.extractor.getValue( workingMemory,
+                                                                   right );
+            final Region fromRegion = (Region) ((ObjectVariableContextEntry) context).left;
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ isTowardsMordor( toRegion,
+                                                   fromRegion );
+        }
+
+        public boolean evaluate(InternalWorkingMemory workingMemory,
+                                final InternalReadAccessor extractor1,
+                                final Object object1,
+                                final InternalReadAccessor extractor2,
+                                final Object object2) {
+            final Region toRegion = (Region) extractor1.getValue( workingMemory,
+                                                            object1 );
+            final Region fromRegion = (Region) extractor2.getValue( workingMemory,
+                                                              object2 );
+
+            if ( toRegion == null || fromRegion == null ) {
+                return false;
+            }
+            return this.negated ^ isTowardsMordor( toRegion,
+                                                   fromRegion );
+        }
+
+        public String toString() {
+            return getOperator().toString();
+        }
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/evaluators/TowardsEvaluatorDefinition.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/RandomSelectAccumulateFunction.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/RandomSelectAccumulateFunction.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/RandomSelectAccumulateFunction.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.functions;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.drools.base.accumulators.AccumulateFunction;
+
+/**
+ * An accumulate function that random selects one object from a list of them
+ * 
+ * @author etirelli
+ */
+public class RandomSelectAccumulateFunction
+    implements
+    AccumulateFunction {
+
+    public void readExternal(ObjectInput in) throws IOException,
+                                            ClassNotFoundException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        // functions are stateless, so nothing to serialize
+    }
+
+    public static class RandomSelectData
+        implements
+        Externalizable {
+        public List<Object> list = new ArrayList<Object>();
+        public Random random = new Random(System.currentTimeMillis());
+
+        public RandomSelectData() {
+        }
+
+        @SuppressWarnings("unchecked")
+        public void readExternal(ObjectInput in) throws IOException,
+                                                ClassNotFoundException {
+            list = (List<Object>) in.readObject();
+        }
+
+        public void writeExternal(ObjectOutput out) throws IOException {
+            out.writeObject( list );
+        }
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#createContext()
+     */
+    public Serializable createContext() {
+        return new RandomSelectData();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#init(java.lang.Object)
+     */
+    public void init(Serializable context) throws Exception {
+        RandomSelectData data = (RandomSelectData) context;
+        data.list.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#accumulate(java.lang.Object, java.lang.Object)
+     */
+    public void accumulate(Serializable context,
+                           Object value) {
+        RandomSelectData data = (RandomSelectData) context;
+        data.list.add( value );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#reverse(java.lang.Object, java.lang.Object)
+     */
+    public void reverse(Serializable context,
+                        Object value) throws Exception {
+        RandomSelectData data = (RandomSelectData) context;
+        data.list.remove( value );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#getResult(java.lang.Object)
+     */
+    public Object getResult(Serializable context) throws Exception {
+        RandomSelectData data = (RandomSelectData) context;
+        return data.list.get( data.random.nextInt( data.list.size() ) );
+    }
+
+    /* (non-Javadoc)
+     * @see org.drools.base.accumulators.AccumulateFunction#supportsReverse()
+     */
+    public boolean supportsReverse() {
+        return true;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/functions/RandomSelectAccumulateFunction.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Ability.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Ability.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Ability.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,10 @@
+package org.drools.examples.lotrc.model;
+
+/**
+ * Represents a character or card ability
+ * 
+ * @author etirelli
+ */
+public interface Ability extends Model {
+    
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Ability.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Allegiance.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Allegiance.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Allegiance.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * An interface for the allegiances in the game
+ * 
+ * @author etirelli
+ */
+public enum Allegiance implements Model {
+    
+    FELLOWSHIP, SAURON;
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Allegiance.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Board.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Board.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Board.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import static org.drools.examples.lotrc.model.RegionName.*;
+
+import java.util.Arrays;
+
+/**
+ * The actual board of the game
+ * 
+ * @author etirelli
+ */
+public class Board implements Model {
+
+    private static final long serialVersionUID = -7959119262916027202L;
+    
+    // regions are represented by row,col coordinates
+    // Shire is 0,0 and Mordor is 6,0
+    private Region[][] regions;
+
+    public Board() {
+        this.regions = new Region[7][];
+        // row 0
+        this.regions[0] = new Region[1];
+        this.regions[0][0] = new RegionImpl( SHIRE,
+                                             0,
+                                             0,
+                                             4 );
+        // row 1
+        this.regions[1] = new Region[2];
+        this.regions[1][0] = new RegionImpl( ARTHEDAIN,
+                                             1,
+                                             0,
+                                             2 );
+        this.regions[1][1] = new RegionImpl( CARDOLAN,
+                                             1,
+                                             1,
+                                             2 );
+        // row 2
+        this.regions[2] = new Region[3];
+        this.regions[2][0] = new RegionImpl( RHUDAUR,
+                                             2,
+                                             0,
+                                             2 );
+        this.regions[2][1] = new RegionImpl( HOLLIN,
+                                             2,
+                                             1,
+                                             2 );
+        this.regions[2][2] = new RegionImpl( ENEDWAITH,
+                                             2,
+                                             2,
+                                             2 );
+        // row 3
+        this.regions[3] = new Region[4];
+        this.regions[3][0] = new RegionImpl( HIGH_PASS,
+                                             3,
+                                             0,
+                                             1 );
+        this.regions[3][1] = new RegionImpl( MISTY_MOUNTAINS,
+                                             3,
+                                             1,
+                                             1 );
+        this.regions[3][2] = new RegionImpl( MORIA,
+                                             3,
+                                             2,
+                                             1 );
+        this.regions[3][3] = new RegionImpl( GAP_OF_ROHAN,
+                                             3,
+                                             3,
+                                             1 );
+        // row 4
+        this.regions[4] = new Region[3];
+        this.regions[4][0] = new RegionImpl( MIRKWOOD,
+                                             4,
+                                             0,
+                                             2 );
+        this.regions[4][1] = new RegionImpl( FANGORN,
+                                             4,
+                                             1,
+                                             2 );
+        this.regions[4][2] = new RegionImpl( ROHAN,
+                                             4,
+                                             2,
+                                             2 );
+        // row 5
+        this.regions[5] = new Region[2];
+        this.regions[5][0] = new RegionImpl( DAGORLAD,
+                                             5,
+                                             0,
+                                             2 );
+        this.regions[5][1] = new RegionImpl( GONDOR,
+                                             5,
+                                             1,
+                                             2 );
+        // row 6
+        this.regions[6] = new Region[1];
+        this.regions[6][0] = new RegionImpl( MORDOR,
+                                             6,
+                                             0,
+                                             4 );
+    }
+
+    public Region getRegion(int row,
+                            int col) {
+        return regions[row][col];
+    }
+
+    public Region[][] getRegions() {
+        return regions;
+    }
+
+    public void printBoard() {
+        for ( Region[] row : regions ) {
+            System.out.println( Arrays.toString( row ) );
+        }
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Board.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Card.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Card.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Card.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * Represents a card in the game
+ * 
+ * @author etirelli
+ */
+public interface Card extends Model {
+
+    public Allegiance getAllegiance();
+    
+    public CardName getName();
+
+    public CardAbility getAbility();
+
+    public int getPower();
+    
+    public CardStatus getStatus();
+    
+    public void setStatus( CardStatus status );
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Card.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardAbility.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardAbility.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardAbility.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * Represents a card ability
+ * 
+ * @author etirelli
+ */
+public enum CardAbility implements Model {
+
+    NONE, IGNORE_TEXT, IGNORE_POWER, SACRIFICE_BOTH, MAGIC, RETREAT_SIDEWAYS, RETREAT_BACKWARDS;
+    
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardAbility.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardImpl.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardImpl.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardImpl.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * A card implementation
+ * 
+ * @author etirelli
+ */
+public class CardImpl
+    implements
+    Card {
+
+    private static final long serialVersionUID = 417307077760796758L;
+
+    private final Allegiance  allegiance;
+    private final CardName    name;
+    private final int         power;
+    private final CardAbility ability;
+    private CardStatus status;
+
+    public CardImpl(final Allegiance allegiance,
+                    final CardName name,
+                    final int power,
+                    final CardAbility ability) {
+        this.allegiance = allegiance;
+        this.name = name;
+        this.power = power;
+        this.ability = ability;
+        this.status = CardStatus.UNPLAYED;
+    }
+
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+    
+    public CardName getName() {
+        return name;
+    }
+
+    public int getPower() {
+        return power;
+    }
+
+    public CardAbility getAbility() {
+        return ability;
+    }
+
+    public CardStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(CardStatus status) {
+        this.status = status;
+    }
+    
+    @Override
+    public String toString() {
+        return "Card( ["+allegiance+"] Power: "+power+" / "+ability+" ("+status+") )";
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardName.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardName.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardName.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,8 @@
+package org.drools.examples.lotrc.model;
+
+public enum CardName {
+    
+    P1, P2, P3, P4, P5, P6, NOBLE_SACRIFICE, 
+    ELVEN_CLOAK, RETREAT, EYE_OF_SAURON, MAGIC; 
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardName.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardStatus.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardStatus.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardStatus.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * The status of a card
+ * 
+ * @author etirelli
+ */
+public enum CardStatus implements Model {
+
+    PLAYED, UNPLAYED;
+    
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CardStatus.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Character.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Character.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Character.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,24 @@
+package org.drools.examples.lotrc.model;
+
+/**
+ * An interface for all characters in the game
+ * 
+ * @author etirelli
+ */
+public interface Character extends Cloneable, Model {
+
+    public Allegiance getAllegiance();
+
+    public CharacterName getName();
+
+    public int getStrength();
+
+    public CharacterAbility getAbility();
+
+    public CharacterStatus getStatus();
+    
+    public void setStatus( CharacterStatus status );
+    
+    public Character clone();
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Character.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterAbility.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterAbility.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterAbility.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,21 @@
+package org.drools.examples.lotrc.model;
+
+/**
+ * A representation of character abilities
+ * 
+ * @author etirelli
+ */
+public enum CharacterAbility implements Model {
+    // Sauron characters
+    IGNORE_TEXT, RETURN_TO_ROHAN, DEFEAT_ON_ATTACK, 
+    FLY_TO_PREY, IGNORE_CARD, CHARGE_TO_ATTACK, 
+    ATTACK_SIDEWAYS, NO_CARDS_ON_COMBAT, GUARDS_MORIA_TUNEL, 
+    
+    // Fellowship characters
+    RETREAT_SIDEWAYS, PROTECTS_FRODO, ATTACK_ADJACENT, 
+    RETREAT_ON_ATTACK, DEFEAT_WITCH_KING, DEFEAT_NAZGUL, 
+    DEFEAT_ORCS, PLAY_CARD_LAST, SACRIFICE, 
+    
+    // Mark up value for hidden characters 
+    UNKNOWN
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterAbility.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterImpl.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterImpl.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterImpl.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * A character implementation
+ * 
+ * @author etirelli
+ *
+ */
+public class CharacterImpl
+    implements
+    Character {
+
+    private static final long serialVersionUID = -5261840037413369523L;
+    
+    private final Allegiance       allegiance;
+    private final CharacterName    name;
+    private final int              strength;
+    private final CharacterAbility ability;
+    private CharacterStatus                 status;
+
+    public CharacterImpl(Allegiance allegiance,
+                         CharacterName name,
+                         int strength,
+                         CharacterAbility ability) {
+        this.allegiance = allegiance;
+        this.name = name;
+        this.strength = strength;
+        this.ability = ability;
+        this.status = CharacterStatus.INIT;
+    }
+
+    public CharacterStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(CharacterStatus status) {
+        this.status = status;
+    }
+
+    public Allegiance getAllegiance() {
+        return allegiance;
+    }
+
+    public CharacterName getName() {
+        return name;
+    }
+
+    public int getStrength() {
+        return strength;
+    }
+
+    public CharacterAbility getAbility() {
+        return ability;
+    }
+
+    @Override
+    public String toString() {
+        return this.name + "[" + this.strength + "]";
+    }
+
+    @Override
+    public Character clone() {
+        return new CharacterImpl( allegiance,
+                                  name,
+                                  strength,
+                                  ability );
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if ( this == obj ) return true;
+        if ( obj == null ) return false;
+        if ( getClass() != obj.getClass() ) return false;
+        CharacterImpl other = (CharacterImpl) obj;
+        if ( name == null ) {
+            if ( other.name != null ) return false;
+        } else if ( !name.equals( other.name ) ) return false;
+        return true;
+    }
+    
+    
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterName.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterName.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterName.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,50 @@
+package org.drools.examples.lotrc.model;
+
+/**
+ * An enum to serve as characters ID
+ * 
+ * @author etirelli
+ */
+public enum CharacterName implements Model {
+    
+    // Sauron
+    CAVE_TROLL("Cave Troll"),
+    BALROG("Balrog"),
+    BLACK_RIDER("Black Rider"),
+    FLYING_NAZGUL("Flying Nazgul"),
+    ORCS("Orcs"),
+    SARUMAN("Saruman"),
+    SHELOB("Shelob"),
+    WARG("Warg"),
+    WITCH_KING("Witch King"),
+    
+    // Fellowship
+    ARAGORN("Aragorn"),
+    BOROMIR("Boromir"),
+    FRODO("Frodo"),
+    GANDALF("Gandalf"),
+    GIMLI("Gimli"),
+    LEGOLAS("Legolas"),
+    MERRY("Merry"),
+    PIPPIN("Pippin"),
+    SAM("Sam"), 
+    
+    // Mark up constant for hidden characters
+    HIDDEN("[hidden]");
+    
+    private final String name;
+    
+    CharacterName( String name ) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+    
+    @Override
+    public String toString() {
+        return this.name;
+    }
+    
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterName.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterStatus.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterStatus.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterStatus.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * The status of a character
+ * 
+ * @author etirelli
+ */
+public enum CharacterStatus implements Model {
+    
+    INIT, DEFEATED, HIDDEN, EXPOSED;
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/CharacterStatus.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Game.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Game.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Game.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.examples.lotrc.player.Player;
+
+/**
+ * A class to manage the game
+ * 
+ * @author etirelli
+ */
+public class Game implements Model {
+
+    private static final long serialVersionUID = 7644689948063266496L;
+    
+    private final Player          sauron;
+    private final Player          fellowship;
+    private final Board           board;
+    private final List<Character> characters;
+    private final List<Card>      cards;
+
+    private Player                activePlayer;
+
+    public Game(Player sauron,
+                Player fellowship) {
+        this.sauron = sauron;
+        this.fellowship = fellowship;
+        this.characters = new ArrayList<Character>();
+        this.cards = new ArrayList<Card>();
+        this.board = new Board();
+        this.activePlayer = sauron;
+
+        // create the cards for Sauron
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P1,
+                                 1,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P2,
+                                 2,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P3,
+                                 3,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P4,
+                                 4,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P5,
+                                 5,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.P6,
+                                 6,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.MAGIC,
+                                 0,
+                                 CardAbility.MAGIC ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.EYE_OF_SAURON,
+                                 0,
+                                 CardAbility.IGNORE_TEXT ) );
+        cards.add( new CardImpl( Allegiance.SAURON,
+                                 CardName.RETREAT,
+                                 0,
+                                 CardAbility.RETREAT_SIDEWAYS ) );
+
+        // create the cards for the Fellowship
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.P1,
+                                 1,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.P2,
+                                 2,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.P3,
+                                 3,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.P4,
+                                 4,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.P5,
+                                 5,
+                                 CardAbility.NONE ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.NOBLE_SACRIFICE,
+                                 0,
+                                 CardAbility.SACRIFICE_BOTH ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.MAGIC,
+                                 0,
+                                 CardAbility.MAGIC ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.ELVEN_CLOAK,
+                                 0,
+                                 CardAbility.IGNORE_POWER ) );
+        cards.add( new CardImpl( Allegiance.FELLOWSHIP,
+                                 CardName.RETREAT,
+                                 0,
+                                 CardAbility.RETREAT_BACKWARDS ) );
+
+        // create the characters for Sauron
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.WARG,
+                                           2,
+                                           CharacterAbility.IGNORE_TEXT ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.SHELOB,
+                                           5,
+                                           CharacterAbility.RETURN_TO_ROHAN ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.ORCS,
+                                           2,
+                                           CharacterAbility.DEFEAT_ON_ATTACK ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.FLYING_NAZGUL,
+                                           3,
+                                           CharacterAbility.FLY_TO_PREY ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.CAVE_TROLL,
+                                           9,
+                                           CharacterAbility.IGNORE_CARD ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.BLACK_RIDER,
+                                           3,
+                                           CharacterAbility.CHARGE_TO_ATTACK ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.WITCH_KING,
+                                           5,
+                                           CharacterAbility.ATTACK_SIDEWAYS ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.SARUMAN,
+                                           4,
+                                           CharacterAbility.NO_CARDS_ON_COMBAT ) );
+        characters.add( new CharacterImpl( Allegiance.SAURON,
+                                           CharacterName.BALROG,
+                                           5,
+                                           CharacterAbility.GUARDS_MORIA_TUNEL ) );
+
+        // create the characters for the Fellowship
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.FRODO,
+                                           1,
+                                           CharacterAbility.RETREAT_SIDEWAYS ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.SAM,
+                                           2,
+                                           CharacterAbility.PROTECTS_FRODO ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.ARAGORN,
+                                           4,
+                                           CharacterAbility.ATTACK_ADJACENT ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.PIPPIN,
+                                           1,
+                                           CharacterAbility.RETREAT_ON_ATTACK ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.MERRY,
+                                           2,
+                                           CharacterAbility.DEFEAT_WITCH_KING ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.LEGOLAS,
+                                           3,
+                                           CharacterAbility.DEFEAT_NAZGUL ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.GIMLI,
+                                           3,
+                                           CharacterAbility.DEFEAT_ORCS ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.GANDALF,
+                                           5,
+                                           CharacterAbility.PLAY_CARD_LAST ) );
+        characters.add( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                           CharacterName.BOROMIR,
+                                           0,
+                                           CharacterAbility.SACRIFICE ) );
+    }
+
+    public final Player getSauron() {
+        return sauron;
+    }
+
+    public final Player getFellowship() {
+        return fellowship;
+    }
+
+    public final Board getBoard() {
+        return board;
+    }
+
+    public List<Character> getCharacters() {
+        return characters;
+    }
+
+    public List<Card> getCards() {
+        return cards;
+    }
+
+    public Player getActivePlayer() {
+        return activePlayer;
+    }
+
+    public void setActivePlayer(Player activePlayer) {
+        this.activePlayer = activePlayer;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Game.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Model.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Model.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Model.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import java.io.Serializable;
+
+/**
+ * A top level interface for all Model classes
+ * 
+ * @author etirelli
+ */
+public interface Model
+    extends
+    Serializable {
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Model.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Region.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Region.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Region.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import java.util.List;
+
+/**
+ * An actual board region
+ * 
+ * @author etirelli
+ */
+public interface Region extends Model {
+    
+    public RegionName getName();
+    
+    public int getRow();
+    
+    public int getCol();
+    
+    public int getCapacity();
+    
+    public List<Character> getCharacters();
+    
+    public void addCharacter( Character character );
+    
+    public boolean removeCharacter( Character character );
+    
+    public boolean isAdjacentTo( Region region );
+    
+    public boolean isMountain();
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Region.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionImpl.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionImpl.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionImpl.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * The region implementation
+ * 
+ * @author etirelli
+ */
+public class RegionImpl
+    implements
+    Region {
+
+    private static final long serialVersionUID = 3228332055793827395L;
+    
+    private final RegionName      name;
+    private final int             row;
+    private final int             col;
+    private final int             capacity;
+    private final List<Character> characters;
+
+    public RegionImpl(RegionName name,
+                      int row,
+                      int col,
+                      int capacity) {
+        super();
+        this.name = name;
+        this.row = row;
+        this.col = col;
+        this.capacity = capacity;
+        this.characters = new ArrayList<Character>();
+    }
+
+    public RegionName getName() {
+        return name;
+    }
+
+    public int getRow() {
+        return row;
+    }
+
+    public int getCol() {
+        return col;
+    }
+
+    public int getCapacity() {
+        return capacity;
+    }
+
+    public List<Character> getCharacters() {
+        return Collections.unmodifiableList( characters );
+    }
+
+    public void addCharacter(Character character) {
+        this.characters.add( character );
+    }
+
+    public boolean removeCharacter(Character character) {
+        return this.characters.remove( character );
+    }
+
+    @Override
+    public String toString() {
+        return "Region( " + this.name + " characters=" + this.characters + " )";
+    }
+
+    public boolean isAdjacentTo(Region region) {
+        boolean isAdjacent = ( this.row == region.getRow() && Math.abs( this.col - region.getCol() ) == 1 );
+        if( this.row != region.getRow() ) {
+            Region fwd = this.row > region.getRow() ? this : region;
+            Region bwd = this.row < region.getRow() ? this : region;
+            if( fwd.getRow() == bwd.getRow()+1 ) {
+                if ( fwd.getRow() > 3 ) {
+                    isAdjacent = ( fwd.getCol() == bwd.getCol() || fwd.getCol() == (bwd.getCol() + 1) );
+                } else {
+                    isAdjacent = ( fwd.getCol() == bwd.getCol() || fwd.getCol() == (bwd.getCol() - 1) );
+                }
+            }
+        }
+        return isAdjacent;
+    }
+
+    public boolean isMountain() {
+        // all regions in row 3 are mountain regions
+        return row == 3;
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionImpl.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionName.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionName.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionName.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+/**
+ * @author etirelli
+ *
+ */
+public enum RegionName implements Model {
+    
+    MORDOR("Mordor"),
+    GONDOR("Gondor"),
+    DAGORLAD("Dagorlad"),
+    ROHAN("Rohan"),
+    FANGORN("Fangorn"),
+    MIRKWOOD("Mirkwood"),
+    GAP_OF_ROHAN("Gap of Rohan"),
+    MORIA("Moria"),
+    MISTY_MOUNTAINS("Misty Mountains"),
+    HIGH_PASS("High Pass"),
+    ENEDWAITH("Enedwaith"),
+    HOLLIN("Hollin"),
+    RHUDAUR("Rhudaur"),
+    CARDOLAN("Cardolan"),
+    ARTHEDAIN("Arthedain"),
+    SHIRE("Shire");
+    
+    private final String name;
+    RegionName( String name ) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/RegionName.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Winner.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Winner.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Winner.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.model;
+
+import org.drools.examples.lotrc.player.Player;
+
+/**
+ * A winner representation
+ * 
+ * @author etirelli
+ */
+public class Winner implements Model {
+    
+    private static final long serialVersionUID = 4286339102504245979L;
+
+    private final Player winner;
+
+    public Winner(Player winner) {
+        this.winner = winner;
+    }
+
+    public Player getWinner() {
+        return winner;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/model/Winner.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/AbstractDroolsPlayer.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/AbstractDroolsPlayer.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/AbstractDroolsPlayer.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,283 @@
+package org.drools.examples.lotrc.player;
+
+import org.apache.log4j.Logger;
+import org.drools.KnowledgeBase;
+import org.drools.KnowledgeBaseFactory;
+import org.drools.builder.KnowledgeBuilder;
+import org.drools.builder.KnowledgeBuilderConfiguration;
+import org.drools.builder.KnowledgeBuilderError;
+import org.drools.builder.KnowledgeBuilderFactory;
+import org.drools.builder.ResourceType;
+import org.drools.examples.lotrc.action.CharacterDefeatedAction;
+import org.drools.examples.lotrc.action.CombatAction;
+import org.drools.examples.lotrc.action.MoveAction;
+import org.drools.examples.lotrc.action.PlaceCharacterAction;
+import org.drools.examples.lotrc.action.PlayCardAction;
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.Board;
+import org.drools.examples.lotrc.model.CardAbility;
+import org.drools.examples.lotrc.model.CardImpl;
+import org.drools.examples.lotrc.model.CardName;
+import org.drools.examples.lotrc.model.CharacterAbility;
+import org.drools.examples.lotrc.model.CharacterImpl;
+import org.drools.examples.lotrc.model.CharacterName;
+import org.drools.examples.lotrc.model.Region;
+import org.drools.examples.lotrc.player.command.MakeAMove;
+import org.drools.examples.lotrc.player.command.PlayACard;
+import org.drools.examples.lotrc.player.command.SetupCharacter;
+import org.drools.io.ResourceFactory;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
+
+public abstract class AbstractDroolsPlayer
+    implements
+    Player {
+
+    protected Logger                   logger;
+    protected KnowledgeBase            kbase;
+    protected StatefulKnowledgeSession ksession;
+
+    public AbstractDroolsPlayer(String identifier,
+                                String[] ruleFiles) {
+        logger = Logger.getLogger( identifier );
+        initRulebase( ruleFiles );
+        initSession();
+    }
+
+    public abstract Allegiance getAllegiance();
+
+    public void notify(PlaceCharacterAction action) {
+        updateSession( action );
+    }
+
+    public void notify(MoveAction action) {
+        updateSession( action );
+    }
+
+    public void notify(PlayCardAction action) {
+        updateSession( action );
+    }
+
+    public void notify(CharacterDefeatedAction action) {
+        updateSession( action );
+    }
+
+    private void updateSession(Object fact) {
+        FactHandle handle = ksession.insert( fact );
+        ksession.fireAllRules();
+        ksession.retract( handle );
+    }
+
+    public PlaceCharacterAction setupCharacter(CharacterName character) {
+        SetupCharacter sc = new SetupCharacter( character );
+        updateSession( sc );
+        return sc.getAction();
+    }
+
+    public MoveAction makeAMove() {
+        MakeAMove mam = new MakeAMove();
+        updateSession( mam );
+        return mam.getAction();
+    }
+
+    public PlayCardAction playACard(CombatAction combat) {
+        PlayACard pac = new PlayACard( combat );
+        updateSession( pac );
+        return pac.getAction();
+    }
+
+    public void printBoard() {
+        ksession.insert( "Print Board" );
+        ksession.fireAllRules();
+    }
+
+    private void initRulebase(String[] ruleFiles) {
+        logger.debug( "Creating knowledge base" );
+        KnowledgeBuilderConfiguration conf = KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration();
+        KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder( conf );
+        for ( String ruleFile : ruleFiles ) {
+            logger.debug( "Loading: " + ruleFile );
+            builder.add( ResourceFactory.newClassPathResource( ruleFile ),
+                         ResourceType.DRL );
+        }
+        if ( builder.hasErrors() ) {
+            for ( KnowledgeBuilderError error : builder.getErrors() ) {
+                logger.error( error );
+            }
+            System.exit( 0 );
+        }
+        logger.debug( "Knowledge packages successfuly compiled." );
+        kbase = KnowledgeBaseFactory.newKnowledgeBase();
+        kbase.addKnowledgePackages( builder.getKnowledgePackages() );
+        logger.debug( "Knowledge Base successfuly created" );
+    }
+
+    private void initSession() {
+        logger.debug( "Creating Knowledge Session" );
+        ksession = kbase.newStatefulKnowledgeSession();
+        ksession.setGlobal( "logger",
+                            logger );
+        logger.debug( "Initializing session with game data" );
+        Board board = new Board();
+        ksession.insert( board );
+        Region[][] regions = board.getRegions();
+        for ( Region[] row : regions ) {
+            for ( Region region : row ) {
+                ksession.insert( region );
+            }
+        }
+        // Sauron characters
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.WARG,
+                                            2,
+                                            CharacterAbility.IGNORE_TEXT ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.SHELOB,
+                                            5,
+                                            CharacterAbility.RETURN_TO_ROHAN ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.ORCS,
+                                            2,
+                                            CharacterAbility.DEFEAT_ON_ATTACK ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.FLYING_NAZGUL,
+                                            3,
+                                            CharacterAbility.FLY_TO_PREY ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.CAVE_TROLL,
+                                            9,
+                                            CharacterAbility.IGNORE_CARD ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.BLACK_RIDER,
+                                            3,
+                                            CharacterAbility.CHARGE_TO_ATTACK ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.WITCH_KING,
+                                            5,
+                                            CharacterAbility.ATTACK_SIDEWAYS ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.SARUMAN,
+                                            4,
+                                            CharacterAbility.NO_CARDS_ON_COMBAT ) );
+        ksession.insert( new CharacterImpl( Allegiance.SAURON,
+                                            CharacterName.BALROG,
+                                            5,
+                                            CharacterAbility.GUARDS_MORIA_TUNEL ) );
+        // create the characters for the Fellowship
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.FRODO,
+                                            1,
+                                            CharacterAbility.RETREAT_SIDEWAYS ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.SAM,
+                                            2,
+                                            CharacterAbility.PROTECTS_FRODO ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.ARAGORN,
+                                            4,
+                                            CharacterAbility.ATTACK_ADJACENT ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.PIPPIN,
+                                            1,
+                                            CharacterAbility.RETREAT_ON_ATTACK ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.MERRY,
+                                            2,
+                                            CharacterAbility.DEFEAT_WITCH_KING ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.LEGOLAS,
+                                            3,
+                                            CharacterAbility.DEFEAT_NAZGUL ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.GIMLI,
+                                            3,
+                                            CharacterAbility.DEFEAT_ORCS ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.GANDALF,
+                                            5,
+                                            CharacterAbility.PLAY_CARD_LAST ) );
+        ksession.insert( new CharacterImpl( Allegiance.FELLOWSHIP,
+                                            CharacterName.BOROMIR,
+                                            0,
+                                            CharacterAbility.SACRIFICE ) );
+
+        // create the cards for Sauron
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P1,
+                                       1,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P2,
+                                       2,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P3,
+                                       3,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P4,
+                                       4,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P5,
+                                       5,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.P6,
+                                       6,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.MAGIC,
+                                       0,
+                                       CardAbility.MAGIC ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.EYE_OF_SAURON,
+                                       0,
+                                       CardAbility.IGNORE_TEXT ) );
+        ksession.insert( new CardImpl( Allegiance.SAURON,
+                                       CardName.RETREAT,
+                                       0,
+                                       CardAbility.RETREAT_SIDEWAYS ) );
+
+        // create the cards for the Fellowship
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.P1,
+                                       1,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.P2,
+                                       2,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.P3,
+                                       3,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.P4,
+                                       4,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.P5,
+                                       5,
+                                       CardAbility.NONE ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.NOBLE_SACRIFICE,
+                                       0,
+                                       CardAbility.SACRIFICE_BOTH ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.MAGIC,
+                                       0,
+                                       CardAbility.MAGIC ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.ELVEN_CLOAK,
+                                       0,
+                                       CardAbility.IGNORE_POWER ) );
+        ksession.insert( new CardImpl( Allegiance.FELLOWSHIP,
+                                       CardName.RETREAT,
+                                       0,
+                                       CardAbility.RETREAT_BACKWARDS ) );
+
+        logger.debug( "Done." );
+    }
+
+}
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/AbstractDroolsPlayer.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/FellowshipPlayer.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/FellowshipPlayer.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/FellowshipPlayer.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player;
+
+import org.drools.examples.lotrc.model.Allegiance;
+
+/**
+ * A fellowship player implementation
+ * 
+ * @author etirelli
+ */
+public class FellowshipPlayer extends AbstractDroolsPlayer {
+
+    public FellowshipPlayer() {
+        super( "Fellowship Player", new String[]{ "players/common.drl", "fellowship/fellowship.drl" } );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.drools.examples.lotrc.model.Player#getAllegiance()
+     */
+    public Allegiance getAllegiance() {
+        return Allegiance.FELLOWSHIP;
+    }
+
+    @Override
+    public String toString() {
+        return "Fellowship Player";
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/FellowshipPlayer.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/Player.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/Player.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/Player.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player;
+
+import org.drools.examples.lotrc.action.CharacterDefeatedAction;
+import org.drools.examples.lotrc.action.CombatAction;
+import org.drools.examples.lotrc.action.MoveAction;
+import org.drools.examples.lotrc.action.PlaceCharacterAction;
+import org.drools.examples.lotrc.action.PlayCardAction;
+import org.drools.examples.lotrc.model.Allegiance;
+import org.drools.examples.lotrc.model.CharacterName;
+
+/**
+ * A player abstraction
+ * 
+ * @author etirelli
+ */
+public interface Player {
+
+    /**
+     * Returns the allegiance of the player
+     */
+    public Allegiance getAllegiance();
+
+    /**
+     * Sets up all characters in the board
+     */
+    public PlaceCharacterAction setupCharacter( CharacterName character );
+    
+    /**
+     * Makes a move returning the corresponding move action
+     */
+    public MoveAction makeAMove();
+    
+    /**
+     * Plays a card for the given combat action
+     * 
+     * @param combat the current combat
+     * 
+     * @return the card to 
+     */
+    public PlayCardAction playACard( CombatAction combat );
+    
+    /**
+     * Notifies a player that a PlaceCharacterAction was acknowledged by the system
+     * 
+     * @param action 
+     */
+    public void notify( PlaceCharacterAction action );
+    
+    /**
+     * Notifies a player that a MoveAction was acknowledge by the system
+     * 
+     * @param action
+     */
+    public void notify( MoveAction action );
+    
+    /**
+     * Notifies a player that a PlayCardAction was acknowledge by the system
+     * 
+     * @param action
+     */
+    public void notify( PlayCardAction action );
+    
+    /**
+     * Notifies a player that a Character was defeated
+     * 
+     * @param action
+     */
+    public void notify( CharacterDefeatedAction action );
+    
+    public void printBoard();    
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/Player.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/SauronPlayer.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/SauronPlayer.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/SauronPlayer.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player;
+
+import org.drools.examples.lotrc.model.Allegiance;
+
+/**
+ * A Sauron player implementation
+ * 
+ * @author etirelli
+ */
+public class SauronPlayer extends AbstractDroolsPlayer {
+
+    public SauronPlayer() {
+        super( "Sauron Player", new String[]{ "players/common.drl", "sauron/sauron.drl" } );
+    }
+    
+    /* (non-Javadoc)
+     * @see org.drools.examples.lotrc.model.Player#getAllegiance()
+     */
+    public Allegiance getAllegiance() {
+        return Allegiance.SAURON;
+    }
+
+    @Override
+    public String toString() {
+        return "Sauron Player";
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/SauronPlayer.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/MakeAMove.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/MakeAMove.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/MakeAMove.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player.command;
+
+import org.drools.examples.lotrc.action.MoveAction;
+
+/**
+ * Make a move command
+ * 
+ * @author etirelli
+ */
+public class MakeAMove implements PlayerCommand<MoveAction> {
+
+    private MoveAction action;
+
+    public MakeAMove() {
+    }
+    
+    public MoveAction getAction() {
+        return action;
+    }
+
+    public void setAction(MoveAction action) {
+        this.action = action;
+    }
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/MakeAMove.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayACard.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayACard.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayACard.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player.command;
+
+import org.drools.examples.lotrc.action.CombatAction;
+import org.drools.examples.lotrc.action.PlayCardAction;
+
+/**
+ * @author etirelli
+ *
+ */
+public class PlayACard
+    implements
+    PlayerCommand<PlayCardAction> {
+    
+    private final CombatAction combatAction;
+    private PlayCardAction card;
+
+    public PlayACard(CombatAction combatAction) {
+        super();
+        this.combatAction = combatAction;
+    }
+
+    public PlayCardAction getAction() {
+        return card;
+    }
+
+    public void setAction(PlayCardAction action) {
+        this.card = action;
+    }
+
+    public CombatAction getCombatAction() {
+        return combatAction;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayACard.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayerCommand.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayerCommand.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayerCommand.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,16 @@
+package org.drools.examples.lotrc.player.command;
+
+import org.drools.examples.lotrc.action.Action;
+
+/**
+ * A markup interface for Drools players command classes
+ * 
+ * @author etirelli
+ */
+public interface PlayerCommand<T extends Action> {
+    
+    public void setAction( T action );
+    
+    public T getAction();
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/PlayerCommand.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/SetupCharacter.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/SetupCharacter.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/SetupCharacter.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Red Hat
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.drools.examples.lotrc.player.command;
+
+import org.drools.examples.lotrc.action.PlaceCharacterAction;
+import org.drools.examples.lotrc.model.CharacterName;
+
+/**
+ * A setup character command
+ * 
+ * @author etirelli
+ */
+public class SetupCharacter implements PlayerCommand<PlaceCharacterAction> {
+
+    private CharacterName name;
+    private PlaceCharacterAction action;
+    
+    public SetupCharacter(CharacterName name) {
+        super();
+        this.name = name;
+    }
+    public CharacterName getName() {
+        return name;
+    }
+    public void setName(CharacterName name) {
+        this.name = name;
+    }
+    public PlaceCharacterAction getAction() {
+        return action;
+    }
+    public void setAction(PlaceCharacterAction action) {
+        this.action = action;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/main/java/org/drools/examples/lotrc/player/command/SetupCharacter.java
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/drools.packagebuilder.conf
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/drools.packagebuilder.conf	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/drools.packagebuilder.conf	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,4 @@
+drools.evaluator.towards = org.drools.examples.lotrc.evaluators.TowardsEvaluatorDefinition
+drools.evaluator.adjacent = org.drools.examples.lotrc.evaluators.IsAdjacentToEvaluatorDefinition
+
+drools.accumulate.function.randomSelect = org.drools.examples.lotrc.functions.RandomSelectAccumulateFunction


Property changes on: labs/jbossrules/contrib/lotrc/src/main/resources/META-INF/drools.packagebuilder.conf
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/resources/log4j.properties
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/resources/log4j.properties	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/resources/log4j.properties	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,19 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, CONSOLE
+log4j.logger.SauronPlayer=SAURON
+
+# CONSOLE is set to be a ConsoleAppender.
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+# CONSOLE uses PatternLayout.
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+# SAURON is set to be a ConsoleAppender.
+log4j.appender.SAURON=org.apache.log4j.RollingFileAppender
+log4j.appender.SAURON.File=sauron.log
+log4j.appender.SAURON.MaxFileSize=100KB
+# Keep one backup file
+log4j.appender.SAURON.MaxBackupIndex=1
+log4j.appender.SAURON.layout=org.apache.log4j.PatternLayout
+log4j.appender.SAURON.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+


Property changes on: labs/jbossrules/contrib/lotrc/src/main/resources/log4j.properties
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/fellowship.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/fellowship.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/fellowship.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,57 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.drools.examples.lotrc.player.command.*
+import org.apache.log4j.Logger
+
+global Logger logger
+ 
+rule "Setup Character"
+when
+    $s : SetupCharacter( $name : name, action == null )
+    $c : Character( name == $name )
+    $r : Region( row < 3, characters.empty == true || ( name == RegionName.SHIRE && characters.size < 4 ) )
+then
+    logger.info("Placing "+$name+" in "+$r );
+    PlaceCharacterAction pca = new PlaceCharacterAction( Allegiance.FELLOWSHIP, $name, $r.getName() );
+    modify( $s ) { 
+        setAction( pca ) 
+    }
+end
+ 
+rule "Make a move"
+    no-loop
+when
+    $m : MakeAMove( action == null )
+    $c : Character( allegiance == Allegiance.FELLOWSHIP )
+    $f : Region( characters contains $c )
+    $t : Region( this towardsMordor $f )
+    Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.FELLOWSHIP ) from $t.characters,
+                      count( 1 ) )
+then
+    MoveAction move = new MoveAction( Allegiance.FELLOWSHIP, $c.getName(), $f.getName(), $t.getName() );
+    modify( $m ) { 
+        setAction( move ) 
+    }
+end  
+
+rule "Play a card"
+    no-loop 
+when 
+    $p : PlayACard( action == null )
+    $c : CombatAction( ) from $p.combatAction
+    $a : Character( name == $c.attackerName )
+    $d : Character( name == $c.defenderName )
+    $r : Card( ) from accumulate(
+             $card : Card( allegiance == Allegiance.FELLOWSHIP, status == CardStatus.UNPLAYED ),
+             randomSelect( $card ) )
+then
+    PlayCardAction action = new PlayCardAction(Allegiance.FELLOWSHIP, $r.getName() );
+    modify( $p ) {
+        setAction( action )
+    }
+end
+


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/fellowship/fellowship.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,200 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "Combat starts"
+    ruleflow-group "resolve characters"
+    lock-on-active
+    salience 100
+when
+    $c : CombatAction()
+then
+    modify( $c ) { 
+        prepareForCombat()
+    }
+end
+
+rule "Select characters for the combat"
+    ruleflow-group "resolve characters"
+when
+    $c : CombatAction( defenderName == null, status == CombatStatus.UNSETTLED )
+    $r : Region( name == $c.regionName ) 
+    $a : Character( name == $c.attackerName )
+    $d : Character( ) from accumulate(
+            $def : Character( allegiance != $a.allegiance ) from $r.characters,
+            randomSelect( $def ) )
+then
+    modify( $c ) { 
+        setDefenderName( $d.getName() )
+    }
+    modify( $a ) {
+        setStatus( CharacterStatus.EXPOSED )
+    }
+    modify( $d ) {
+        setStatus( CharacterStatus.EXPOSED )
+    }
+    logger.info( "Combat started on "+$r.getName()+". "+$a.getName()+" attacks "+$d.getName()+"." ); 
+end
+
+rule "Merry defeats the Witch King"
+    ruleflow-group "resolve characters"
+when
+    $c : CombatAction( status == CombatStatus.UNSETTLED )
+    $m : Character( name == CharacterName.MERRY, name in ($c.attackerName, $c.defenderName) )
+    $w : Character( name == CharacterName.WITCH_KING, name in ($c.attackerName, $c.defenderName) )
+then
+    modify( $c ) {
+        setStatus( CombatStatus.SETTLED )
+    }
+    modify( $w ) {
+        setStatus( CharacterStatus.DEFEATED )
+    }
+    logger.info( "Merry immediately defeats the Witch King" );
+end
+
+rule "Select Cards to play" 
+    ruleflow-group "select cards"
+when
+    $c : CombatAction( status == CombatStatus.UNSETTLED )
+    $f : Player( allegiance == Allegiance.FELLOWSHIP )
+    $s : Player( allegiance == Allegiance.SAURON )
+then
+    PlayCardAction fc = $f.playACard( $c.getHidden() );
+    logger.info( "Fellowship player selected a card to play: "+fc.getCardName() );
+    PlayCardAction sc = $s.playACard( $c.getHidden() );
+    logger.info( "Sauron player selected a card to play: "+sc.getCardName() );
+    // REMOVE_THIS
+    if( fc == null || sc == null || fc.getCardName() == null || sc.getCardName() == null ) {
+        logger.fatal("ABNORMAL TERMINATION: "+fc+" / "+sc );
+        drools.halt();
+    } 
+    insert( fc ); 
+    insert( sc );
+end
+
+rule "Attacker plays his card"
+    ruleflow-group "play cards"
+when
+    $c    : CombatAction( status == CombatStatus.UNSETTLED, attackerCard == null )
+    $char : Character( name == $c.attackerName )
+    $pca  : PlayCardAction( allegiance == $char.allegiance )
+    $card : Card( status == CardStatus.UNPLAYED, allegiance == $pca.allegiance, name == $pca.cardName )
+    $ap   : Player( allegiance == $pca.allegiance )
+    $dp   : Player( allegiance != $pca.allegiance )
+then
+    logger.info( "Attacker plays: "+$card );
+    modify( $c ) {
+        setAttackerCard( $card )
+    }
+    modify( $card ) {
+        setStatus( CardStatus.PLAYED )
+    }
+    retract( $pca );
+    // notify players
+    $ap.notify( $pca ); 
+    $dp.notify( $pca ); 
+end
+ 
+
+rule "Defender plays his card"
+    ruleflow-group "play cards"
+when
+    $c    : CombatAction( status == CombatStatus.UNSETTLED, defenderCard == null )
+    $char : Character( name == $c.defenderName )
+    $pca  : PlayCardAction( allegiance == $char.allegiance )
+    $card : Card( status == CardStatus.UNPLAYED, allegiance == $pca.allegiance, name == $pca.cardName )
+    $ap   : Player( allegiance != $pca.allegiance )
+    $dp   : Player( allegiance == $pca.allegiance )
+then
+    logger.info( "Defender plays: "+$card );
+    modify( $c ) {
+        setDefenderCard( $card )
+    }
+    modify( $card ) {
+        setStatus( CardStatus.PLAYED )
+    }
+    retract( $pca );
+    // notify players
+    $ap.notify( $pca ); 
+    $dp.notify( $pca ); 
+end
+ 
+rule "Calculate combat result"
+    ruleflow-group "casualties"
+    lock-on-active
+when
+    $c    : CombatAction( status == CombatStatus.UNSETTLED )
+    $att  : Character( name == $c.attackerName )
+    $def  : Character( name == $c.defenderName )
+then
+    int result = $att.getStrength() + $c.getAttackerCard().getPower() -
+                 $def.getStrength() - $c.getDefenderCard().getPower();
+    modify( $c ) {
+        setResult( result ),
+        setStatus( CombatStatus.SETTLED );
+    }
+    logger.info( "Combat results: "+$c );
+end
+
+rule "Attacker is defeated"
+    ruleflow-group "casualties"
+when
+    $c    : CombatAction( status == CombatStatus.SETTLED, result <= 0 )
+    $att  : Character( name == $c.attackerName, status == CharacterStatus.EXPOSED )
+    $ap   : Player( allegiance == $c.allegiance )
+    $dp   : Player( allegiance != $c.allegiance )
+then
+    logger.info( "The attacker ( "+$att+" ) was defeated." );
+    modify( $att ) {
+        setStatus( CharacterStatus.DEFEATED )
+    }
+    // notify players
+    CharacterDefeatedAction cda = new CharacterDefeatedAction( $att.getAllegiance(), $att.getName() );
+    $ap.notify( cda );
+    $dp.notify( cda );
+end
+
+rule "Defender is defeated"
+    ruleflow-group "casualties"
+when
+    $c    : CombatAction( status == CombatStatus.SETTLED, result >= 0 )
+    $def  : Character( name == $c.defenderName, status == CharacterStatus.EXPOSED )
+    $ap   : Player( allegiance == $c.allegiance )
+    $dp   : Player( allegiance != $c.allegiance )
+then
+    logger.info( "The defender ( "+$def+" ) was defeated." );
+    modify( $def ) {
+        setStatus( CharacterStatus.DEFEATED )
+    }
+    // notify players
+    CharacterDefeatedAction cda = new CharacterDefeatedAction( $def.getAllegiance(), $def.getName() );
+    $ap.notify( cda );
+    $dp.notify( cda );
+end
+
+rule "Remove casualties"
+    ruleflow-group "casualties"
+when
+    $c    : CombatAction( status == CombatStatus.SETTLED )
+    $r    : Region( name == $c.regionName )
+    $char : Character( status == CharacterStatus.DEFEATED, this memberOf $r.characters )
+then
+    logger.info("Removing defeated character : "+$char );
+    modify( $r ) {
+        removeCharacter( $char )
+    }
+end
+
+rule "Clean up combat"
+    ruleflow-group "combat end"
+when
+    $c : CombatAction( )
+then
+    retract( $c );
+end
+


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.rf
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.rf	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.rf	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="Combat Flow" id="Combat Flow" package-name="org.drools.examples.lotrc" >
+
+  <header>
+    <imports>
+      <import name="org.drools.examples.lotrc.model.*" />
+    </imports>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="43" y="94" width="80" height="40" />
+    <ruleSet id="2" name="Reveal Characters" x="630" y="251" width="113" height="40" ruleFlowGroup="resolve characters" />
+    <ruleSet id="3" name="Select Cards" x="459" y="250" width="104" height="40" ruleFlowGroup="select cards" />
+    <ruleSet id="4" name="Play Cards" x="308" y="248" width="96" height="40" ruleFlowGroup="play cards" />
+    <ruleSet id="5" name="Casualties" x="149" y="250" width="108" height="40" ruleFlowGroup="casualties" />
+    <end id="6" name="End" x="959" y="97" width="80" height="40" />
+    <split id="7" name="Is there a combat?" x="621" y="99" width="129" height="40" type="2" >
+      <constraints>
+        <constraint toNodeId="9" toType="DROOLS_DEFAULT" name="No" priority="1" type="rule" dialect="mvel" >not( 
+    $c1 : Character( $a : allegiance ) and 
+    $c2 : Character( allegiance != $a )  and
+    Region( characters contains $c1, characters contains $c2 ) 
+)</constraint>
+        <constraint toNodeId="2" toType="DROOLS_DEFAULT" name="Yes" priority="1" type="rule" dialect="java" >exists( 
+    $c1 : Character( $a : allegiance ) and 
+    $c2 : Character( allegiance != $a )  and
+    Region( characters contains $c1, characters contains $c2 ) 
+)</constraint>
+      </constraints>
+    </split>
+    <join id="8" name="Combat" x="156" y="96" width="100" height="40" type="2" />
+    <ruleSet id="9" name="No More Conflicts" x="803" y="98" width="118" height="40" ruleFlowGroup="combat end" />
+  </nodes>
+
+  <connections>
+    <connection from="7" to="2" />
+    <connection from="2" to="3" />
+    <connection from="3" to="4" />
+    <connection from="4" to="5" />
+    <connection from="9" to="6" />
+    <connection from="8" to="7" />
+    <connection from="5" to="8" />
+    <connection from="1" to="8" />
+    <connection from="7" to="9" />
+  </connections>
+
+</process>
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/combat.rf
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/gameflow.rf
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/gameflow.rf	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/gameflow.rf	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?> 
+<process xmlns="http://drools.org/drools-5.0/process"
+         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+         xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
+         type="RuleFlow" name="Game Flow" id="Game Flow" package-name="org.drools.examples.lotrc" >
+
+  <header>
+    <imports>
+      <import name="org.drools.examples.lotrc.model.*" />
+      <import name="org.drools.examples.lotrc.model.Winner" />
+      <import name="org.drools.examples.lotrc.player.*" />
+      <import name="org.drools.examples.lotrc.player.SauronPlayer" />
+    </imports>
+  </header>
+
+  <nodes>
+    <start id="1" name="Start" x="32" y="130" width="80" height="40" />
+    <ruleSet id="2" name="Setup" x="138" y="130" width="80" height="40" ruleFlowGroup="setup" />
+    <ruleSet id="3" name="Move" x="222" y="212" width="104" height="40" ruleFlowGroup="move" />
+    <split id="5" name="Victory?" x="372" y="290" width="80" height="40" type="2" >
+      <constraints>
+        <constraint toNodeId="9" toType="DROOLS_DEFAULT" name="There is a winner" priority="10" type="rule" dialect="mvel" >exists( Winner() )</constraint>
+        <constraint toNodeId="15" toType="DROOLS_DEFAULT" name="No Winner" priority="1" type="rule" dialect="mvel" >not( Winner() )</constraint>
+      </constraints>
+    </split>
+    <split id="6" name="Victory?" x="808" y="289" width="80" height="40" type="2" >
+      <constraints>
+        <constraint toNodeId="9" toType="DROOLS_DEFAULT" name="There is a Winner" priority="10" type="rule" dialect="mvel" >exists( Winner() )</constraint>
+        <constraint toNodeId="14" toType="DROOLS_DEFAULT" name="No Winner" priority="1" type="rule" dialect="mvel" >not( Winner() )</constraint>
+      </constraints>
+    </split>
+    <ruleSet id="7" name="Game End" x="601" y="424" width="80" height="40" ruleFlowGroup="game end" />
+    <join id="8" name="New turn" x="233" y="129" width="80" height="40" type="2" />
+    <join id="9" name="Game End" x="601" y="354" width="80" height="40" type="2" />
+    <end id="10" name="End" x="605" y="504" width="80" height="40" />
+    <ruleSet id="12" name="Check Victory" x="227" y="290" width="96" height="40" ruleFlowGroup="check victory" />
+    <ruleSet id="13" name="Check Victory" x="663" y="288" width="96" height="40" ruleFlowGroup="check victory" />
+    <ruleSet id="14" name="End of Turn" x="807" y="131" width="80" height="40" ruleFlowGroup="end of turn" />
+    <subProcess id="15" name="Combat" x="516" y="289" width="111" height="40" processId="Combat Flow" >
+    </subProcess>
+  </nodes>
+
+  <connections>
+    <connection from="1" to="2" />
+    <connection from="8" to="3" />
+    <connection from="12" to="5" />
+    <connection from="13" to="6" />
+    <connection from="9" to="7" />
+    <connection from="2" to="8" />
+    <connection from="14" to="8" />
+    <connection from="5" to="9" bendpoints="[411,372]" />
+    <connection from="6" to="9" bendpoints="[847,372]" />
+    <connection from="7" to="10" />
+    <connection from="3" to="12" />
+    <connection from="15" to="13" />
+    <connection from="6" to="14" />
+    <connection from="5" to="15" />
+  </connections>
+
+</process>
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/gameflow.rf
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/misc.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/misc.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/misc.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,21 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "Next player"
+    ruleflow-group "end of turn"
+    lock-on-active
+when
+    $g : Game( $activePlayer : activePlayer )
+    $n : Player( this != $activePlayer )
+then
+    logger.info( "Next turn. Active player is now: "+$n );
+    modify( $g ) {
+        setActivePlayer( $n )
+    }
+end 
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/misc.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/move.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/move.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/move.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,320 @@
+###########################################################################################
+#
+#  This file contains all the moving phase rules, including special character abilities
+#  that affect or are affected by move.
+#
+#  @author etirelli
+#
+###########################################################################################
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+#**********************************************************************
+#    The active player must make a move
+# 
+rule "Active player makes a move"
+    ruleflow-group "move"
+    lock-on-active 
+	when
+		$g : Game( $active : activePlayer )
+		$p : Player( this == $active )
+	then 
+		MoveAction ma = $p.makeAMove();
+		insert( ma );
+		update( $g );
+end
+ 
+#**********************************************************************
+#    A move for the Sauron player is valid if it is moving a Sauron
+# character, towards Shire, and the destination region still has room
+# for the moving character. 
+# 
+rule "Move is made to an adjacent forward region by Sauron Character"
+    ruleflow-group "move"
+    when 
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.SAURON )
+        $c : Character( name == $m.characterName, allegiance == Allegiance.SAURON )
+        $f : Region( name == $m.fromRegion, characters contains $c )
+        $t : Region( name == $m.toRegion, this towardsShire $f, $characters : characters )
+        Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.SAURON ) from $characters,
+                      count( 1 ) )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c )
+        }
+        modify( $t ) {
+            addCharacter( $c )
+        }
+end
+
+#**********************************************************************
+#    A move for the Fellowship player is valid if it is moving a 
+# Fellowship character, towards Mordor, and the destination region still 
+# has room for the moving character. 
+# 
+rule "Move is made to an adjacent forward region by Fellowship Character"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.FELLOWSHIP )
+        $c : Character( name == $m.characterName, allegiance == Allegiance.FELLOWSHIP )
+        $f : Region( name == $m.fromRegion, characters contains $c )
+        $t : Region( name == $m.toRegion, this towardsMordor $f, $characters : characters )
+        Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.FELLOWSHIP ) from $characters,
+                      count( 1 ) )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    The Fellowship player can also use the Tunnel of Moria to move
+# characters from Hollin directly to Fangorn, as long as Fangorn still
+# has room for the moving character. 
+# 
+rule "Fellowship Characters can use the Tunnel of Moria to move from Hollin to Fangorn"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.FELLOWSHIP )
+        $c : Character( name == $m.characterName, allegiance == Allegiance.FELLOWSHIP )
+        $f : Region( name == $m.fromRegion && == RegionName.HOLLIN, characters contains $c )
+        $t : Region( name == $m.toRegion && == RegionName.FANGORN, $characters : characters )
+        Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.FELLOWSHIP ) from $characters,
+                      count( 1 ) )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    The Fellowship player can also use the Anduin River to move
+# characters from Mirkwood directly to Fangorn, as long as Fangorn still
+# has room for the moving character. 
+# 
+rule "Fellowship Characters can use the Anduin River to move from Mirkwood to Fangorn"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.FELLOWSHIP )
+        $c : Character( name == $m.characterName, allegiance == Allegiance.FELLOWSHIP )
+        $f : Region( name == $m.fromRegion && == RegionName.MIRKWOOD, characters contains $c )
+        $t : Region( name == $m.toRegion && == RegionName.FANGORN, $characters : characters )
+        Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.FELLOWSHIP ) from $characters,
+                      count( 1 ) )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    The Fellowship player can also use the Anduin River to move
+# characters from Fangorn directly to Rohan, as long as Rohan still
+# has room for the moving character. 
+# 
+rule "Fellowship Characters can use the Anduin River to move from Fangorn to Rohan"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.FELLOWSHIP )
+        $c : Character( name == $m.characterName, allegiance == Allegiance.FELLOWSHIP )
+        $f : Region( name == $m.fromRegion && == RegionName.FANGORN, characters contains $c )
+        $t : Region( name == $m.toRegion && == RegionName.ROHAN, $characters : characters )
+        Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.FELLOWSHIP ) from $characters,
+                      count( 1 ) )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    Which King's ability allows him to move sideways when 
+# attacking an adjacent character, but not if he is in the mountains. 
+# 
+rule "The Witch king can move sideways to attack an enemy"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.SAURON, characterName == CharacterName.WITCH_KING )
+        $c : Character( name == CharacterName.WITCH_KING )
+        $f : Region( name == $m.fromRegion, characters contains $c, mountain == false );
+        $t : Region( name == $m.toRegion, this isAdjacentTo $f, row == $f.row, $characters : characters )
+        exists( Character( allegiance == Allegiance.FELLOWSHIP ) from $characters ) 
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    Aragorns's ability allows him to move to any adjacent region when 
+# attacking, but not if he is in the mountains. 
+# 
+rule "Aragorn can move to any adjacent region to attack an enemy"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.FELLOWSHIP, characterName == CharacterName.ARAGORN )
+        $c : Character( name == CharacterName.ARAGORN )
+        $f : Region( name == $m.fromRegion, characters contains $c );
+        $t : Region( name == $m.toRegion, this isAdjacentTo $f, $characters : characters, mountain == false || != $f.mountain )
+        exists( Character( allegiance == Allegiance.SAURON ) from $characters )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    The Flying Nazgul's ability allows him to move to any region, 
+# as long as that region contains a single fellowship character
+# 
+rule "Flying Nazgul can move to any region to attack a solitary enemy"
+    ruleflow-group "move"
+    when  
+        $m : MoveAction( status == MoveStatus.ISSUED, allegiance == Allegiance.SAURON, characterName == CharacterName.FLYING_NAZGUL )
+        $c : Character( name == CharacterName.FLYING_NAZGUL )
+        $f : Region( name == $m.fromRegion, characters contains $c );
+        $t : Region( name == $m.toRegion,  characters.size == 1 )
+        exists( Character( allegiance == Allegiance.FELLOWSHIP ) from $t.characters )
+    then  
+        # execute the move 
+        logger.info( $m );
+        modify( $m ) {
+            setStatus( MoveStatus.EXECUTED )
+        }
+        modify( $f ) {
+            removeCharacter( $c );
+        }
+        modify( $t ) {
+            addCharacter( $c );
+        }
+end
+
+#**********************************************************************
+#    If the Balrog is in Moria, though, and a Fellowship character 
+# moves through the Tunnel of Moria, the Balrog immediately defeats 
+# him.
+# 
+rule "If the Balrog is in Moria when a character moves through the tunnel, defeat the character"
+    ruleflow-group "move"
+    salience 10
+    when
+        $m  : MoveAction( status == MoveStatus.EXECUTED, fromRegion == RegionName.HOLLIN, toRegion == RegionName.FANGORN )
+        $c  : Character( name == $m.characterName, status in ( CharacterStatus.HIDDEN, CharacterStatus.EXPOSED ) )
+        $t  : Region( name == RegionName.FANGORN )
+        $b  : Character( name == CharacterName.BALROG )
+              Region( name == RegionName.MORIA, characters contains $b )
+    	$sp : Player( allegiance == Allegiance.SAURON )
+        $fp : Player( allegiance == Allegiance.FELLOWSHIP )
+    then
+        logger.info("Balrog is in Moria and instantly defeats "+$c+" when he tries to use the tunels.");
+        modify( $c ) {
+            setStatus( CharacterStatus.DEFEATED )
+        }
+        modify( $t ) {
+            removeCharacter( $c )
+        }
+        // notify players
+        CharacterDefeatedAction cda = new CharacterDefeatedAction( Allegiance.FELLOWSHIP, $c.getName() );
+        $sp.notify( cda );
+        $fp.notify( cda );
+end
+
+
+#**********************************************************************
+#    If a character moves into a region where there are characters
+# from the opposing allegiance, a combat is initiated, having the 
+# moving character as the attacker.
+# 
+rule "Is the move an attack?"
+    ruleflow-group "move"
+    when
+        $m : MoveAction( status == MoveStatus.EXECUTED )
+        $a : Character( name == $m.characterName )
+        $t : Region( name == $m.toRegion )
+        exists( Character( allegiance != $a.allegiance ) from $t.characters )
+    then
+        CombatAction ca = new CombatAction( $a.getAllegiance(), $t.getName(), $a.getName() );
+        insert( ca );
+end
+
+#**********************************************************************
+#    In any case, if a move is successfuly executed, we need to notify
+# the players, and then we can remove the move action fact, since it is
+# no longer necessary.
+# 
+rule "If the move was successful, notify players and remove it"
+    ruleflow-group "move"
+    salience -10
+    when
+        $m : MoveAction( status == MoveStatus.EXECUTED )
+    	$a : Player( allegiance == $m.allegiance )
+        $o : Player( allegiance != $m.allegiance )
+    then
+        retract( $m );
+    	$a.notify( $m );
+    	$o.notify( $m.getHidden() );
+end


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/move.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/setup.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/setup.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/setup.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,100 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "Setup Fellowship Characters"
+    ruleflow-group "setup"
+    salience 10
+	when
+	    $c : Character( status == CharacterStatus.INIT, allegiance == Allegiance.FELLOWSHIP )
+	    $p : Player( allegiance == Allegiance.FELLOWSHIP )
+	then 
+		PlaceCharacterAction pca = $p.setupCharacter( $c.getName() );
+		insert( pca ); 
+end 
+ 
+rule "Setup Sauron Characters"
+	ruleflow-group "setup"
+	when
+	    $c : Character( status == CharacterStatus.INIT, allegiance == Allegiance.SAURON )
+	    $p : Player( allegiance == Allegiance.SAURON )
+	then 
+		PlaceCharacterAction pca = $p.setupCharacter( $c.getName() );
+		insert( pca ); 
+end 
+
+rule "Is legal PCA for the Fellowhisp?" 
+    ruleflow-group "setup"
+    salience 100
+when
+    $pca : PlaceCharacterAction( allegiance == Allegiance.FELLOWSHIP )
+    $c   : Character( status == CharacterStatus.INIT, name == $pca.characterName, allegiance == Allegiance.FELLOWSHIP )
+    $r   : Region( name == $pca.regionName, row < 3, ( name == RegionName.SHIRE && characters.size < capacity ) || characters.empty == true )
+    $s   : Player( allegiance == Allegiance.SAURON )
+    $f   : Player( allegiance == Allegiance.FELLOWSHIP )
+then
+    logger.info( $pca );
+    retract( $pca ); 
+    modify( $r ) { 
+        addCharacter( $c ) 
+    }
+    modify( $c ) {
+        setStatus( CharacterStatus.HIDDEN )
+    }
+    $s.notify( $pca.getHidden() );
+    $f.notify( $pca );
+end 
+
+rule "Is legal PCA for Sauron?" 
+    ruleflow-group "setup"
+    salience 100
+when
+    $pca : PlaceCharacterAction( allegiance == Allegiance.SAURON )
+    $c   : Character( status == CharacterStatus.INIT, name == $pca.characterName, allegiance == Allegiance.SAURON )
+    $r   : Region( name == $pca.regionName, row > 3, ( name == RegionName.MORDOR && characters.size < capacity ) || characters.empty == true )
+    $s   : Player( allegiance == Allegiance.SAURON )
+    $f   : Player( allegiance == Allegiance.FELLOWSHIP )
+then
+    logger.info( $pca );
+    retract( $pca ); 
+    modify( $r ) { 
+        addCharacter( $c )
+    }
+    modify( $c ) {
+        setStatus( CharacterStatus.HIDDEN )
+    }
+    $s.notify( $pca );
+    $f.notify( $pca.getHidden() );
+end  
+
+rule "Is illegal PCA"
+    ruleflow-group "setup" 
+    salience 90
+when
+    $pca : PlaceCharacterAction( )
+    $p   : Player( allegiance == $pca.allegiance )
+then
+    retract( $pca );
+    logger.fatal( "Invalid Place Character Action: "+$pca );
+    logger.fatal( "Game will be terminated." );
+    drools.halt();
+end
+
+rule "Setup is done, Sauron plays first"
+    ruleflow-group "setup"
+    no-loop
+when
+    not( Character( status == CharacterStatus.INIT ) )
+    $g : Game()
+    $p : Player( allegiance == Allegiance.SAURON )
+then
+    logger.info("Lets start... Sauron player plays first.");
+    modify( $g ) { 
+        setActivePlayer( $p )
+    } 
+end
\ No newline at end of file


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/setup.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/game/victory.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/game/victory.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/game/victory.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,65 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "Frodo reached Mordor, so the Fellowship wins"
+    ruleflow-group "check victory"
+when
+    $f : Character( name == CharacterName.FRODO )
+    $r : Region( name == RegionName.MORDOR, characters contains $f )
+    $p : Player( allegiance == Allegiance.FELLOWSHIP )
+then
+    insert( new Winner( $p ) );
+end
+
+rule "Frodo is defeated, so Sauron wins"
+    ruleflow-group "check victory"
+when
+    $f : Character( name == CharacterName.FRODO, status == CharacterStatus.DEFEATED )
+    $p : Player( allegiance == Allegiance.SAURON )
+then
+    insert( new Winner( $p ) );
+end
+
+rule "Sauron has 3 or more charactes in the Shire, so Sauron wins"
+    ruleflow-group "check victory"
+when
+    $r : Region( name == RegionName.SHIRE, $characters : characters )
+    Number( intValue >= 3 ) from accumulate( 
+                 Character( allegiance == Allegiance.SAURON ) from $characters,
+                 count( 1 ) ) 
+    $p : Player( allegiance == Allegiance.SAURON )
+then
+    insert( new Winner( $p ) );
+end
+
+rule "Player is unable to move a character, so opposing player wins"
+    ruleflow-group "check victory"
+when
+    $p : Player( )
+    $g : Game( activePlayer == $p )
+    $m : MoveAction( status in ( MoveStatus.ISSUED, MoveStatus.INVALID ) )
+    $o : Player( this != $p )
+then
+    retract( $m ); 
+    $p.printBoard();
+    $o.printBoard(); 
+    logger.fatal( "Invalid Move Action: "+$m );
+    logger.fatal( "Game will be terminated." );
+    insert( new Winner( $o ) );
+end         
+
+rule "There is a winner"
+    ruleflow-group "game end"
+when
+    Winner( $p : winner )
+then
+    logger.info( "And the winner is....... "+$p );
+end    
+
+     


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/game/victory.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/players/common.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/players/common.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/players/common.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,89 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.drools.examples.lotrc.player.command.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "PlaceCharacterAction Acknowledged"
+    no-loop
+when
+    $p : PlaceCharacterAction( characterName != CharacterName.HIDDEN )
+    $r : Region( name == $p.regionName )
+    $c : Character( name == $p.characterName )
+then
+    modify( $r ) {
+        addCharacter( $c )
+    }
+end
+
+rule "PlaceCharacterAction Acknowledged for Hidden Character"
+    no-loop
+when
+    $p : PlaceCharacterAction( characterName == CharacterName.HIDDEN )
+    $r : Region( name == $p.regionName )
+then
+    CharacterImpl hidden = new CharacterImpl( $p.getAllegiance(),
+                                          CharacterName.HIDDEN,
+                                          0,
+                                          CharacterAbility.UNKNOWN );
+    modify( $r ) {
+        addCharacter( hidden ) 
+    }
+end
+
+rule "Ackowledge a move"
+when
+    $m : MoveAction( )
+    $f : Region( name == $m.fromRegion )
+    $t : Region( name == $m.toRegion ) 
+    $c : Character( name == $m.characterName ) from $f.characters
+then
+    retract( $m );
+    modify( $f ) {
+        removeCharacter( $c );
+    }
+    modify( $t ) {
+        addCharacter( $c );
+    }
+end 
+
+rule "Acknowledge a card play"
+    no-loop
+when
+    $pca  : PlayCardAction()
+    $card : Card( allegiance == $pca.allegiance, name == $pca.cardName )
+then
+    modify( $card ) {
+        setStatus( CardStatus.PLAYED )
+    }
+end
+
+rule "Acknowledge a character defeat"
+    no-loop
+when
+    $cda  : CharacterDefeatedAction()
+    $char : Character( name == $cda.characterName )
+    $r    : Region( characters contains $char )
+then
+    modify( $char ) {
+        setStatus( CharacterStatus.DEFEATED )
+    }
+    modify( $r ) {
+        removeCharacter( $char )
+    }
+end
+
+
+rule "Print board"
+when
+    String( this == "Print Board" )
+    $b : Board()
+then
+    $b.printBoard();
+end 
+       
+


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/players/common.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/main/rules/sauron/sauron.drl
===================================================================
--- labs/jbossrules/contrib/lotrc/src/main/rules/sauron/sauron.drl	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/main/rules/sauron/sauron.drl	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,57 @@
+package org.drools.examples.lotrc
+
+import org.drools.examples.lotrc.model.*
+import org.drools.examples.lotrc.action.*
+import org.drools.examples.lotrc.player.*
+import org.drools.examples.lotrc.player.command.*
+import org.apache.log4j.Logger
+
+global Logger logger
+
+rule "Setup Character"
+when
+    $s : SetupCharacter( $name : name, action == null )
+    $c : Character( name == $name )
+    $r : Region( row > 3, characters.empty == true || ( name == RegionName.MORDOR && characters.size < 4 ) )
+then
+    logger.info("Placing "+$name+" in "+$r );
+    PlaceCharacterAction pca = new PlaceCharacterAction( Allegiance.SAURON, $name, $r.getName() );
+    modify( $s ) { 
+        setAction( pca ) 
+    }
+end
+
+rule "Make a move"
+    no-loop
+when
+    $m : MakeAMove( action == null )
+    $c : Character( allegiance == Allegiance.SAURON )
+    $f : Region( characters contains $c )
+    $t : Region( this towardsShire $f )
+    Number( intValue < $t.capacity ) from accumulate( 
+                      Character( allegiance == Allegiance.SAURON ) from $t.characters,
+                      count( 1 ) )
+then
+    MoveAction move = new MoveAction( Allegiance.SAURON, $c.getName(), $f.getName(), $t.getName() );
+    modify( $m ) { 
+        setAction( move ) 
+    }
+end  
+
+rule "Play a card"
+    no-loop
+when 
+    $p : PlayACard( action == null )
+    $c : CombatAction( ) from $p.combatAction
+    $a : Character( name == $c.attackerName )
+    $d : Character( name == $c.defenderName )
+    $r : Card( ) from accumulate(
+             $card : Card( allegiance == Allegiance.SAURON, status == CardStatus.UNPLAYED ),
+             randomSelect( $card ) )
+then 
+    PlayCardAction action = new PlayCardAction(Allegiance.SAURON, $r.getName() );
+    modify( $p ) {
+        setAction( action ) 
+    }
+end
+


Property changes on: labs/jbossrules/contrib/lotrc/src/main/rules/sauron/sauron.drl
___________________________________________________________________
Name: svn:executable
   + *

Added: labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/TowardsEvaluatorTest.java
===================================================================
--- labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/TowardsEvaluatorTest.java	                        (rev 0)
+++ labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/TowardsEvaluatorTest.java	2009-06-05 01:28:11 UTC (rev 26843)
@@ -0,0 +1,319 @@
+package org.drools.examples;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.drools.base.ValueType;
+import org.drools.base.evaluators.EvaluatorRegistry;
+import org.drools.common.InternalWorkingMemory;
+import org.drools.examples.lotrc.evaluators.TowardsEvaluatorDefinition;
+import org.drools.examples.lotrc.model.Board;
+import org.drools.examples.lotrc.model.Region;
+import org.drools.rule.Declaration;
+import org.drools.rule.VariableRestriction.ObjectVariableContextEntry;
+import org.drools.rule.VariableRestriction.VariableContextEntry;
+import org.drools.spi.Evaluator;
+import org.drools.spi.InternalReadAccessor;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+
+public class TowardsEvaluatorTest extends TestCase {
+
+    private Mockery mockery = new Mockery();
+
+    private EvaluatorRegistry registry = new EvaluatorRegistry();
+    private Region[][] regions = new Board().getRegions();
+    
+    @Override
+    protected void setUp() throws Exception {
+        registry.addEvaluatorDefinition( new TowardsEvaluatorDefinition() );
+    }
+    
+    public void testTowardsShire() {
+        final List<Object[]> dataList = new ArrayList<Object[]>();
+        for( Region[] row : regions ) {
+            for( Region fromRegion : row ) {
+                for( Region[] trow : regions ) {
+                    for( Region toRegion : trow ) {
+                        Object[] tcase = new Object[4];
+                        tcase[0] = toRegion;
+                        tcase[1] = "towardsShire";
+                        tcase[2] = fromRegion;
+                        boolean result = (toRegion.getRow() - fromRegion.getRow()) == -1;
+                        if( fromRegion.getRow() > 3 ) {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()-1)) );
+                        } else {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()+1)) );
+                        }
+                        tcase[3] = Boolean.valueOf( result );
+                        dataList.add( tcase );
+                    }
+                }
+            }
+        }
+        
+        final Object[][] data = new Object[dataList.size()][];
+        int i = 0;
+        for( Object[] tcase : dataList ) {
+            data[i++] = tcase;
+        }
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+
+    }
+
+    public void testNotTowardsShire() {
+        final List<Object[]> dataList = new ArrayList<Object[]>();
+        for( Region[] row : regions ) {
+            for( Region fromRegion : row ) {
+                for( Region[] trow : regions ) {
+                    for( Region toRegion : trow ) {
+                        Object[] tcase = new Object[4];
+                        tcase[0] = toRegion;
+                        tcase[1] = "not towardsShire";
+                        tcase[2] = fromRegion;
+                        boolean result = (toRegion.getRow() - fromRegion.getRow()) == -1;
+                        if( fromRegion.getRow() > 3 ) {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()-1)) );
+                        } else {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()+1)) );
+                        }
+                        tcase[3] = Boolean.valueOf( !result );
+                        dataList.add( tcase );
+                    }
+                }
+            }
+        }
+        
+        final Object[][] data = new Object[dataList.size()][];
+        int i = 0;
+        for( Object[] tcase : dataList ) {
+            data[i++] = tcase;
+        }
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+
+    }
+
+    public void testTowardsMordor() {
+        final List<Object[]> dataList = new ArrayList<Object[]>();
+        for( Region[] row : regions ) {
+            for( Region fromRegion : row ) {
+                for( Region[] trow : regions ) {
+                    for( Region toRegion : trow ) {
+                        Object[] tcase = new Object[4];
+                        tcase[0] = toRegion;
+                        tcase[1] = "towardsMordor";
+                        tcase[2] = fromRegion;
+                        boolean result = (toRegion.getRow() - fromRegion.getRow()) == +1;
+                        if( fromRegion.getRow() < 3 ) {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()-1)) );
+                        } else {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()+1)) );
+                        }
+                        tcase[3] = Boolean.valueOf( result );
+                        dataList.add( tcase );
+                    }
+                }
+            }
+        }
+        
+        final Object[][] data = new Object[dataList.size()][];
+        int i = 0;
+        for( Object[] tcase : dataList ) {
+            data[i++] = tcase;
+        }
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+
+    }
+
+    public void testNotTowardsMordor() {
+        final List<Object[]> dataList = new ArrayList<Object[]>();
+        for( Region[] row : regions ) {
+            for( Region fromRegion : row ) {
+                for( Region[] trow : regions ) {
+                    for( Region toRegion : trow ) {
+                        Object[] tcase = new Object[4];
+                        tcase[0] = toRegion;
+                        tcase[1] = "not towardsMordor";
+                        tcase[2] = fromRegion;
+                        boolean result = (toRegion.getRow() - fromRegion.getRow()) == +1;
+                        if( fromRegion.getRow() < 3 ) {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()-1)) );
+                        } else {
+                            result = result && ((fromRegion.getCol()==toRegion.getCol())|| (fromRegion.getCol()==(toRegion.getCol()+1)) );
+                        }
+                        tcase[3] = Boolean.valueOf( !result );
+                        dataList.add( tcase );
+                    }
+                }
+            }
+        }
+        
+        final Object[][] data = new Object[dataList.size()][];
+        int i = 0;
+        for( Object[] tcase : dataList ) {
+            data[i++] = tcase;
+        }
+
+        runEvaluatorTest( data,
+                          ValueType.OBJECT_TYPE );
+
+    }
+
+    /**
+     * Test utility to play the data through the evaluators.
+     * @param data The data to try out : Array of {arg1, operator, arg2}
+     * @param valueType The Evaluator.**_TYPE to test
+     */
+    private void runEvaluatorTest(final Object[][] data,
+                                  final ValueType valueType) {
+        final InternalReadAccessor extractor = mockery.mock( InternalReadAccessor.class );
+        for ( int i = 0; i < data.length; i++ ) {
+            final Object[] row = data[i];
+            mockery.checking( new Expectations() {{
+                allowing(extractor).getValue( with( row[0] ) ); will( returnValue( row[0] ) );
+                allowing(extractor).getValue( with( row[2] ) ); will( returnValue( row[2] ) );
+                allowing(extractor).getValue( with( any( InternalWorkingMemory.class) ), with( row[0] ) ); will( returnValue( row[0] ) );
+                allowing(extractor).getValue( with( any( InternalWorkingMemory.class) ), with( row[2] ) ); will( returnValue( row[2] ) );
+            }} );
+            
+            boolean isNegated = ((String) row[1]).startsWith( "not " );
+            String evaluatorStr = isNegated ? ((String) row[1]).substring( 4 ) : (String) row[1];
+            final Evaluator evaluator = (Evaluator) registry.getEvaluatorDefinition( evaluatorStr ).getEvaluator( valueType,
+                                                                                                      evaluatorStr,
+                                                                                                      isNegated,
+                                                                                                      null );
+            checkEvaluatorMethodCachedRight( valueType,
+                                             extractor,
+                                             row,
+                                             evaluator );
+            checkEvaluatorMethodCachedLeft( valueType,
+                                            extractor,
+                                            row,
+                                            evaluator );
+            checkEvaluatorMethodWith2Extractors( valueType,
+                                                 extractor,
+                                                 row,
+                                                 evaluator );
+
+            assertEquals( valueType,
+                          evaluator.getValueType() );
+
+        }
+    }
+
+    /**
+     * @param valueType
+     * @param extractor
+     * @param row
+     * @param evaluator
+     */
+    private void checkEvaluatorMethodCachedRight(final ValueType valueType,
+                                                 final InternalReadAccessor extractor,
+                                                 final Object[] row,
+                                                 final Evaluator evaluator) {
+        final VariableContextEntry context = this.getContextEntry( evaluator,
+                                                                   extractor,
+                                                                   valueType,
+                                                                   row );
+        final boolean result = evaluator.evaluateCachedRight( null,
+                                                              context,
+                                                              row[2] );
+        final String message = "The evaluator type: [" + valueType + "] with CachedRight incorrectly returned " + result + " for [" + row[0] + " " + row[1] + " " + row[2] + "]. It was asserted to return " + row[3];
+
+        if ( row[3] == Boolean.TRUE ) {
+            assertTrue( message,
+                        result );
+        } else {
+            assertFalse( message,
+                         result );
+        }
+    }
+
+    /**
+     * @param valueType
+     * @param extractor
+     * @param row
+     * @param evaluator
+     */
+    private void checkEvaluatorMethodCachedLeft(final ValueType valueType,
+                                                final InternalReadAccessor extractor,
+                                                final Object[] row,
+                                                final Evaluator evaluator) {
+        final VariableContextEntry context = this.getContextEntry( evaluator,
+                                                                   extractor,
+                                                                   valueType,
+                                                                   row );
+        final boolean result = evaluator.evaluateCachedLeft( null,
+                                                             context,
+                                                             row[0] );
+        final String message = "The evaluator type: [" + valueType + "] with CachedLeft incorrectly returned " + result + " for [" + row[0] + " " + row[1] + " " + row[2] + "]. It was asserted to return " + row[3];
+
+        if ( row[3] == Boolean.TRUE ) {
+            assertTrue( message,
+                        result );
+        } else {
+            assertFalse( message,
+                         result );
+        }
+    }
+
+    /**
+     * @param valueType
+     * @param extractor
+     * @param row
+     * @param evaluator
+     */
+    private void checkEvaluatorMethodWith2Extractors(final ValueType valueType,
+                                                     final InternalReadAccessor extractor,
+                                                     final Object[] row,
+                                                     final Evaluator evaluator) {
+        final boolean result = evaluator.evaluate( null,
+                                                   extractor,
+                                                   row[0],
+                                                   extractor,
+                                                   row[2] );
+        final String message = "The evaluator type: [" + valueType + "] with 2 extractors incorrectly returned " + result + " for [" + row[0] + " " + row[1] + " " + row[2] + "]. It was asserted to return " + row[3];
+
+        if ( row[3] == Boolean.TRUE ) {
+            assertTrue( message,
+                        result );
+        } else {
+            assertFalse( message,
+                         result );
+        }
+    }
+
+    private VariableContextEntry getContextEntry(final Evaluator evaluator,
+                                                 final InternalReadAccessor extractor,
+                                                 final ValueType valueType,
+                                                 final Object[] row) {
+        final Declaration declaration = new Declaration( "test",
+                                                         extractor,
+                                                         null );
+
+        final ObjectVariableContextEntry context = new ObjectVariableContextEntry( extractor,
+                                                                                   declaration,
+                                                                                   evaluator );
+        if ( row[2] == null ) {
+            context.leftNull = true;
+        } else {
+            context.left = row[2];
+        }
+
+        if ( row[0] == null ) {
+            context.rightNull = true;
+        } else {
+            context.right = row[0];
+        }
+        return context;
+    }
+
+}


Property changes on: labs/jbossrules/contrib/lotrc/src/test/java/org/drools/examples/TowardsEvaluatorTest.java
___________________________________________________________________
Name: svn:executable
   + *




More information about the jboss-svn-commits mailing list