Question

The AI code for my little soccer game basically works like this: There is a function that derives facts that describe the current situation on the pitch:

deriveFacts :: GameState -> [Fact]

... where the facts look kind of like this:

data Fact =
    FactCanIntercept ObjId ObjId
  | FactBestPosition Team Spot Spot
  | FactKickOff
  | FactBallCarrier ObjId
  | FactBestShootingVector Velocity3
  | FactBestPassingVector Velocity3
  | ...

... and there are rules that look uniformly like this:

rule_shoot facts = do
    FactBallCarrier ballCarrier <- checkBallCarrier facts
    FactBestShootingVector goalVector <- checkBestShootingVector facts
    return [message (ballCarrier, shoot goalVector)]

And then there is a rule engine that runs all the rules and gathers up the resulting messages.

That's fine so far and works quite nicely. What's kind of annoying, though: In this approach, I need an "accessor" function like this for every Fact:

checkBestShootingVector :: [Fact] -> Maybe Fact
checkBestShootingVector facts = 
   listToMaybe [e | e@(FactBestShootingVector {}) <- facts]

This approach leads to a lot of ugly boilerplate code. My question: Is there an elegant solution that removes the need for creating these accessor functions by hand?

Was it helpful?

Solution

You could refactor most of your Fact data as a record object

data FactRec = FR {
   canIntercept :: [(ObjId,ObjId)], -- use lists for things you previously had multiple times
   factBestPosition :: [(Team,Spot,Spot)], -- not sure about this one, maybe two entries not one list 
   kickOff :: Bool,
   ballCarrier :: ObjID,
   factBestShootingVector :: Velocity3, 
   factBestPassingVector :: Velocity3,
   .....
   }

Which gives you bulti-in accessor functions

if kickOff fr then something else somethingelse

So you wouldn't need to write all the check functions, but instead do

rule_shoot facts = message (ballCarrier facts, shoot $ goalVector facts)

If there are facts that genuinely might or might not be there, they could be of type Maybe something, and if there are facts that can be there an arbitrary number of times, they can be lists.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top