All files / src/agents simpleProblemSolvingAgent.js

100% Statements 17/17
100% Branches 8/8
100% Functions 4/4
100% Lines 17/17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69              1x                                 1x   2x 2x 2x   18x 18x   3x 3x 3x   18x   2x       16x 16x 16x                   18x               3x          
"use strict";
 
const
{
  sequenceIsEmpty,
  sequenceFirst,
  sequenceRest
} = require('../common/sequence');
 
/**
 * Simple problem solving agent.
 * 
 * Defines problem based on state of the world, searches for a sequence of steps to solve it and execute said sequence of steps.
 * 
 * It is a open loop system - ignores precepts during execution phase. I.e, it is only good for static, discrete, observable, deterministic systems. 
 * 
 * @param {object} parameters
 * @param {State} parameters.state initial state
 * @param {function(state:State, percept:Percept):State} [parameters.updateState] function to update parameters
 * @param {function(state:State):Goal} parameters.formulateGoal function to formulate goal from current state
 * @param {function(state:State,goal:Goal):Problem} [parameters.formulateProblem] function to formulate problem object from state and goal. By default it just puts state and goal into an object.
 * @param {function(problem:Problem):Sequence} parameters.search search for solution to problem
 * @return {function(percept:Percept):Action} an agent function
 */
module.exports.simpleProblemSolvingAgent = function (parameters)
{
  parameters.updateState = parameters.updateState || defaultUpdateState;
  parameters.formulateProblem = parameters.formulateProblem || defaultFormulateProblem;
  return async function (percept)
  {
    parameters.state = await parameters.updateState(parameters.state, percept);
    if (sequenceIsEmpty(parameters.sequence))
    {
      const goal = await parameters.formulateGoal(parameters.state);
      const problem = await parameters.formulateProblem(parameters.state, goal);
      parameters.sequence = await parameters.search(problem)
    }
    if (sequenceIsEmpty(parameters.sequence))
    {
      return null;
    }
    else
    {
      const action = sequenceFirst(parameters.sequence);
      parameters.sequence = sequenceRest(parameters.sequence);
      return action;
    }
  };
}
 
/**
 * @private
 */
function defaultUpdateState(state, percept)
{
  return state;
}
 
/**
 * @private
 */
function defaultFormulateProblem(state, goal)
{
  return {
    state,
    goal
  };
}