package org.gregcode.mnb global Monkeyverse monkeyverseGlobal; declare trait HungryMonkey end rule "foo" salience 10 when monkey : Monkey() then HungryMonkey hungry = don(monkey, HungryMonkey.class); end rule "init_finished" salience 10 when monkeyverse : Monkeyverse( initialized == false) then monkeyverse.setInitialized(true); update( monkeyverse ); end /** * Have the monkeyverse create some Bananas and add them to WorkingMemory. **/ rule "init_bananas" salience 10 when monkeyverse : Monkeyverse( initialized == false, bananaCount < bananaLimit ) then Bananas bananas = monkeyverse.makeBananas(); insert(bananas); update(monkeyverse); end /** * Have the monkeyverse create a Monkey and add it to WorkingMemory. **/ rule "init_monkeys" salience 10 when monkeyverse : Monkeyverse( initialized == false, monkeyCount < monkeyLimit ) then Monkey monkey = monkeyverse.makeMonkey(); insert(monkey); update(monkeyverse); end /** * Have the monkeyverse create a Block and add it to WorkingMemory. **/ rule "init_blocks" salience 10 when monkeyverse : Monkeyverse( initialized == false, blockCount < blockLimit ) then Block block = monkeyverse.makeBlock(); insert(block); update(monkeyverse); end /** * If the Monkey is hungry, holding nothing, and doesn't have Bananas on the brain * then it should move to a Location it hasn't been to much. **/ rule "monkey_wanders" when monkey : Monkey( hungry == true, holding == null, memory == null ) then modify(monkey) { move(monkeyverseGlobal.getLessVisitedMove(monkey)) } end /** * If the Monkey is hungry, holding nothing, doesn't have Bananas on the brain, * and it looks up to find some Bananas, then it should remember the Bananas. **/ rule "monkey_finds_bananas" when monkey : Monkey( hungry == true, holding == null, memory == null ) bananas : Bananas( isAbove(monkey) ) then modify(monkey) { setMemory(bananas) } update(bananas); end /** * If the Monkey is hungry, holding nothing, has Bananas on the brain, * and there's a block that's not already under the remembered Bananas or in the monkey's location, * wander to someplace it hasn't been to much. * NOTE: This is a very inefficient rule! **/ rule "monkey_searches_for_blocks" when monkey : Monkey( hungry == true, holding == null, memory != null ) bananas : Bananas( this == monkey.memory ) block : Block( location != monkey.location, !isBelow(bananas) ) then modify(monkey) { move(monkeyverseGlobal.getLessVisitedMove(monkey)) } end /** * If the Monkey is hungry, holding nothing, has Bananas on the brain, * and it's above a block that's not already under the remembered Bananas, * pick up that block. **/ rule "monkey_finds_block" when monkey : Monkey( hungry == true, holding == null, memory != null ) bananas : Bananas( this == monkey.memory ) block : Block( isUnder(monkey), !isBelow(bananas) ) then modify(monkey) { setHolding(block) } update(block); //Block modified in Monkey.setHolding() end /** * If the Monkey is hungry, holding someentity, and has Bananas on the brain, * then walk one location along the floor towards the Bananas. **/ rule "monkey_returns_block" when monkey : Monkey( hungry == true, holding != null, memory != null ) then Monkeyverse.Move bestMove = monkey.getLocation().getBestFloorMoveTo(monkey.getMemory().getLocation()); if(bestMove != null) { modify(monkey) { move(bestMove) } update(monkey.getHolding()); } end /** * If the Monkey is hungry, holding someentity, has Bananas on the brain, * and is below the remembered Bananas, then drop the block. **/ rule "monkey_drops_block" when monkey : Monkey( hungry == true, holding != null, memory != null ) held : Entity( this == monkey.holding ) bananas : Bananas( this == monkey.memory, isAbove(monkey) ) then modify(monkey) { setHolding(null) } update(held); //Held Entity modified in Monkey.setHolding() end /** * If a Monkey occupies the same Location as a Block it's not holding, * then the Monkey climbs on top of the block. **/ rule "monkey_climbs" when monkey : Monkey( ) block : Block( this != monkey.holding, location == monkey.location ) then modify(monkey) { move(monkeyverseGlobal.MOVE_TOWARDS_CEILING) } if(monkey.getHolding() != null) { update(monkey.getHolding()); } end /** * If there's a hungry Monkey, some Bananas that it remembers, and they're in the same Location, * then the Monkey grabs the Bananas. **/ rule "wake_up_and_smell_the_bananas" salience 1 no-loop true when monkey : Monkey( hungry == true ) bananas : Bananas( this == monkey.memory, location == monkey.location ) then modify(monkey) { setHolding(bananas) } update(bananas); //Bananas modified in Monkey.setHolding() end /** * If there's a hungry Monkey, some Bananas that it remembers, and the Monkey is holding them * there Bananas, then eat 'em! **/ rule "triumph_thy_name_is_monkey" when monkey : Monkey( ) bananas : Bananas( this == monkey.memory, this == monkey.holding ) then modify(monkey) { eat(bananas) } retract(bananas); end /** * PHYSICS RULE: * If there's a Entity that has an attachment to the floor with nothing in the Location below it, * then it falls down one Location. **/ rule "entities_fall" salience 1000 when entity : Entity( attachment == Monkeyverse.Attachment.FLOOR, !location.onFloor, entitiesUnder.empty ) then modify(entity) { move(monkeyverseGlobal.MOVE_TOWARDS_FLOOR) } end /** * PHYSICS RULE: * Blocks occupying the same Location (with neither being held) forces one of the Blocks to be on top of the other. **/ rule "block_pushed_up" salience 100 when block1: Block( holds == null ) block2: Block(this != block1, holds == null, location == block1.location) then modify(block2) { move(monkeyverseGlobal.MOVE_TOWARDS_CEILING) } end /** * PHYSICS RULE: * Blocks occupying the same Location (with neither being held) and both are on the ceiling forces them apart **/ rule "block_pushed_apart" salience 100 when block1: Block( holds == null, location.onCeiling ) block2: Block(this != block1, holds == null, location == block1.location ) then modify(block2) { move(block2.getLocation().getRandomPossibleMove()) } end