Search code examples
javaoopartificial-intelligenceagentloose-coupling

Java: How can an 'agent' object that is inside a 'world' object obtain information about the 'world'?


Sorry for the slightly demented wording of this question, but I'm very new to agent-oriented thinking (are these 'patterns'?) and only slightly less new to java, and I'm struggling with what feels like a very basic problem.

I'm doing a lot of this 'intuitively' (i.e. blindly) rather than trying to understand someone else's code - partly because I struggle to understand code that's 'above my level', but also because I hope doing it 'my way' will help me appreciate the right way later.

Basically, I'm modelling an agent (a robot vacuum) in an environment (a House). A House contains a collection (HashMap) of Rooms. A House has a method getRoom(int key) that returns a Room matching the given key. The Agent has a State, which at this point keeps track of a room ID (which is also the key in the House), which is the room the robot is 'in' for the purposes of navigating the world; a State also describes whether or not the room is known to be dirty. When the agent is constructed, it's initialised with an ID (It must be created 'in a room'), but it is not given the dirty/clean status of the Room. I want the agent to check for dirt - this would involve invoking the getRoom() method in House. However, with the Java I've learned so far, I don't know how to do this. I know I could access that method by creating a House inside java, or by making the method static, but those won't work - the agent needs to know about the SPECIFIC house that is in memory, the one that has been initialised with Rooms.

tl;dr: How can an Agent object obtain a reference to an object that is stored in a HashMap inside another Environment object?

P.S here is my imagined model for the 'higher level' perspective enabled by this approach: I kind of intuitively wanted the Agent to be wholly responsible for its own precepts and behaviours, so that the code higher up would look more like:

agent.percieve()                           //agent checks the room it thinks its in for dirt and exits
if (agent.gotDirt()) agent.clean()         //agent activates its cleaning device if it found dirt in this room
if (agent.gotDirt() == false) agent.move() //agent picks an exit and leaves the room


Solution

  • The vacuum cleaner (i.e. what you call an "Agent", but why name it like this since it's, in fact, a vacuum cleaner?) simply needs a reference to the House object it belongs to:

    // a single House is constructed
    House house = new House(); 
    // omitted: add rooms to the house...
    
    // create a first vacuum cleaner for the house. A reference to the house is given to this cleaner
    VacuumCleaner vacuumCleaner = new VacuumCleaner(house);
    System.out(vacuumCleaner.isRoomClean(2)); // prints false, because room 2 is full of dirt
    vacuumCleaner.cleanRoom(2);
    System.out(vacuumCleaner.isRoomClean(2)); // prints true, because the vacuum cleaner removed the dirt from room 2
    
    // now let's create a second vacuum cleaner for the same house
    VacuumCleaner vacuumCleaner2 = new VacuumCleaner(house);
    System.out(vacuumCleaner2.isRoomClean(2)); // prints true, because room 2 has no dirt: it has previously been removed from the room by the first vacuum cleaner.
    

    EDIT

    And here's how the VacuumCleaner class would look like:

    public class VacuumCleaner
        /**
         * The house that this vacuum cleaner cleans 
         */
        private House house;
    
        public VacuumCleaner(House houseToClean) {
            this.house = houseToClean;
        }
    
        public boolean isRoomDirty(int roomId) {
            // find the room in the house, and see if it contains dirt
        }
    
        public void cleanRoom(int roomId) {
            // find the room in the house, and remove dirt from it
        }
    }