Пример #1
0
        public static bool TryQueryStructure(
            Structure term,
            PrologContext context,
            out ELNode foundNode,
            out ELNodeEnumerator enumerator)
        {
            //
            // Dispatch based on the functor and arity.
            //

            // Handle root queries, i.e. /Key
            if (term.IsFunctor(Symbol.Slash, 1))
                return TryRootQuery(term, context, out foundNode, out enumerator);

            if (!IsELTerm(term))
                throw new Exception("Malformed EL query: " + ISOPrologWriter.WriteToString(term));

            if (term.IsFunctor(SBindNodeOperator, 2))
            {
                var variableToBind = term.Argument(1) as LogicVariable;
                if (variableToBind == null)
                    throw new ArgumentException("RHS of >> must be an uninstantiated variable: "+ ISOPrologWriter.WriteToString(term.Argument(1)));
                foundNode = null;
                return TryNodeBindingQuery(out enumerator, term.Argument(0), variableToBind, context);
            }

            return TryChildQuery(
                out foundNode,
                out enumerator,
                term.Argument(0),
                term.Argument(1),
                term.Functor == Symbol.Colon,
                context);
        }
Пример #2
0
    private void UpdateLocomotion()
    {
        UpdateLocomotionBidsAndPath();

        if (CurrentlyDockedWith != null && !CurrentlyDockedWith.DockingTiles().Contains(transform.position))
        {
            // We were docked with an object, but are not anymore.
            perceptionRoot.DeleteKey(SDockedWith);
            CurrentlyDockedWith = null;
        }

        if (currentPath != null)
        {
            // Update the steering
            if (currentPath.UpdateSteering(steering) ||
                (Vector2.Distance(transform.position, currentDestination.transform.position) < 0.75 &&
                 currentDestination.IsCharacter()))
            {
                // Finished the path
                CurrentlyDockedWith = CurrentDestination;
                ELNode.Store(perceptionRoot / SDockedWith % CurrentlyDockedWith);
                ELNode.Store(lastDestination % CurrentDestination);
                currentPath        = null;
                currentDestination = null;
                (motorRoot / SWalkingTo).DeleteSelf();
                Face(CurrentlyDockedWith);
                steering.Stop();
                QueueEvent("arrived_at", CurrentlyDockedWith);
            }
        }
    }
Пример #3
0
        public static bool TryChildQuery(
            out ELNode foundNode,
            out ELNodeEnumerator enumerator,
            object parentExpression,
            object keyExpression,
            bool isExclusive,
            PrologContext context)
        {
            // Decode the parent expression
            ELNode parentNode;
            ELNodeEnumerator parentEnumerator;
            if (!TryQuery(parentExpression, context, out parentNode, out parentEnumerator))
            {
                // Parent failed, so we fail
                enumerator = null;
                foundNode = null;
                return false;
            }

            //
            // Decode the key argument
            //
            var key = keyExpression;
            var v = key as LogicVariable;

            return isExclusive?TryExclusiveQuery(out foundNode, out enumerator, parentNode, parentEnumerator, key, v)
                : TryNonExclusiveQuery(out foundNode, out enumerator, parentNode, key, v, parentEnumerator);
        }
Пример #4
0
    void UpdateLocomotionBidsAndPath()
    {
        //foreach (var pair in bidTotals)
        //    bidTotals[pair.Key] = 0;
        bidTotals.Clear();
        elRoot.WalkTree(SConcerns, this.updateConcernBids);

        GameObject winner     = null;
        float      winningBid = 0;

        foreach (var pair in bidTotals)
        {
            if (pair.Value > winningBid)
            {
                winningBid = pair.Value;
                winner     = pair.Key;
            }
        }

        if (winner != null)
        {
            // Replan if destination has changed or if destination has moved away from current path.
            var newDestination = (winner != CurrentDestination && winner != CurrentlyDockedWith);
            if (newDestination ||
                (currentDestination != null && currentPath != null && !CurrentDestination.DockingTiles().Contains(currentPath.FinalTile)))
            {
                if (newDestination)
                {
                    ELNode.Store(eventHistory / new Structure("goto", winner)); // Log change for debugging purposes.
                }
                this.CurrentDestination = winner;
                this.currentPath        = planner.Plan(gameObject.TilePosition(), this.CurrentDestination.DockingTiles());
            }
        }
    }
Пример #5
0
 void UpdateConcernBids(ELNode concern)
 {
     // Make sure this isn't the EL root (it's not an actual concern node).
     if (concern.Key != null)
     {
         ELNode bids;
         if (concern.TryLookup(SLocationBids, out bids))
         {
             // Add its bids in
             foreach (var bid in bids.Children)
             {
                 var destination = bid.Key as GameObject;
                 if (destination == null)
                 {
                     throw new Exception("Location bid is not a GameObject: " + bid.Key);
                 }
                 var bidValue = Convert.ToSingle(bid.ExclusiveKeyValue <object>());
                 if (bidTotals.ContainsKey(destination))
                 {
                     bidTotals[destination] += bidValue;
                 }
                 else
                 {
                     bidTotals[destination] = bidValue;
                 }
             }
         }
     }
 }
Пример #6
0
        public static bool TryQuery(object term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator)
        {
            // Dereference any top-level variables.
            var t = Term.Deref(term);

            // Dereference indexicals
            var i = t as Indexical;
            if (i != null)
                t = i.GetValue(context);

            // A game object means the gameobject's EL KB.
            var g = t as GameObject;
            if (g != null)
                t = g.KnowledgeBase().ELRoot;

            // If it's already an ELNode, use that.
            var n = t as ELNode;
            if (n != null)
            {
                foundNode = n;
                enumerator = null;
                return true;
            }

            // Otherwise, it's an expression, so evaluate it.
            var s = t as Structure;
            if (s != null)
                return TryQueryStructure(s, context, out foundNode, out enumerator);

            var v = t as LogicVariable;
            if (v != null && !v.IsBound)
                throw new Exception("EL query root is an unbound variable: " + v);
            throw new Exception("Malformed EL query: " + ISOPrologWriter.WriteToString(term));
        }
Пример #7
0
 /// <summary>
 /// Call into Prolog to respond to EVENTDESCRIPTION
 /// </summary>
 /// <param name="eventDescription">Term representing the event</param>
 private void NotifyEvent(object eventDescription)
 {
     ELNode.Store(eventHistory / Term.CopyInstantiation(eventDescription));
     if (!this.IsTrue(new Structure(SNotifyEvent, eventDescription)))
     {
         Debug.LogError("notify_event/1 failed: " + ISOPrologWriter.WriteToString(eventDescription));
     }
 }
 /// <summary>
 /// Thrown when attempting to write a non-exclusive value to an exclusive value or vice-versa.
 /// </summary>
 public ELNodeExclusionException(string message, ELNode node, object key)
     : base(string.Format("{0}: {1}{2}{3}", 
                          message, 
                          node,
                          node.IsExclusive?ELProlog.ExclusiveOperator:ELProlog.NonExclusiveOperator,
                          ISOPrologWriter.WriteToString(key)))
 {
 }
Пример #9
0
 private void SetSpeechTimeout(string speech)
 {
     currentlySpeaking = true;
     ELNode.Store(motorRoot / SIAmSpeaking);
     clearSpeechTime = Time.time
                       + Math.Max(
         SpeechDelayMinimum,
         Math.Min(SpeechDelayMaximum, speech.Length * SpeechDelaySecondsPerChar));
 }
Пример #10
0
 internal void Start()
 {
     lastPlayerActivity = KnowledgeBase.Global.ELRoot.StoreNonExclusive(Symbol.Intern("last_player_activity"));
     lastPlayerActivity.StoreExclusive(-1, true);
     elRoot               = this.KnowledgeBase().ELRoot;
     haloElNode           = elRoot / Symbol.Intern("halo");
     mouseSelectionELNode = elRoot / Symbol.Intern("perception") / Symbol.Intern("mouse_selection");
     talkingToElNode      = elRoot / Symbol.Intern("social_state") / Symbol.Intern("talking_to");
     MouseSelection       = null;
 }
Пример #11
0
#pragma warning restore 649
    #endregion

    internal void Start()
    {
        this.lastPlayerActivity = KnowledgeBase.Global.ELRoot.StoreNonExclusive(Symbol.Intern("last_player_activity"));
        this.lastPlayerActivity.StoreExclusive(-1, true);

        var theCamera  = Camera.main;
        var bottomOfUI = Math.Min(InputRect.yMin, Math.Min(CommentaryRect.yMin, ResponseRect.yMin));
        var r          = theCamera.pixelRect;

        r.height           -= bottomOfUI + 50;
        theCamera.pixelRect = r;
        FindObjectOfType <TileMap>().UpdateCamera(theCamera);
        Tile.UpdateTileSize(theCamera);
    }
Пример #12
0
 public KnowledgeBase(string kbName, GameObject gameObject, KnowledgeBase parent, params KnowledgeBase[] otherImports)
 {
     if (kbName == null) throw new ArgumentNullException("kbName");
     Name = kbName;
     this.Parent = parent;
     this.GameObject = gameObject;
     this.ELRoot = new ELNode(null, Symbol.Intern("root"));
     //if (parent == null) throw new ArgumentNullException("parent");
     if (otherImports == null) throw new ArgumentNullException("otherImports");
     foreach (var import in otherImports)
         if (import == null) throw new ArgumentNullException("otherImports");
     if (parent != null)
         imports.Add(parent);
     imports.AddRange(otherImports);
 }
Пример #13
0
    private void UpdateLocations()
    {
        // TODO: FIX THIS SO THAT DESTROYED OBJECTS GET THEIR ENTRIES GC'ed.
        foreach (var p in Registry <PhysicalObject>())
        {
            var o = p.gameObject;
            var n = locationRoot.ChildWithKey(o);
            // Don't do anything if /perception/location/O:Location:override in database,
            // which would mean the character is brainwashed about O's position.
            if (n == null || n.Children.Count == 0 || !n.Children[0].ContainsKey(brainwashedSymbol))
            {
                if (!p.Exists)
                {
                    // Dead; remove it.
                    locationRoot.DeleteKey(o);
                }
                // Determine if it's inside something
                else if (p.Container == null)
                {
                    // It's not inside another object, so find what room it's in.

                    if (n == null || !n.ExclusiveKeyValue <GameObject>().GetComponent <Room>().Contains(o))
                    {
                        var r        = TileMap.TheTileMap.TileRoom(o);
                        var location = r != null?(r.gameObject):null;
                        if (location == null && p is Door)
                        {
                            location = ((Door)p).ForceRoom;
                        }
                        ELNode.Store(locationRoot / o % location);
                        if (o == gameObject)
                        {
                            myCurrentRoom = r;
                        }
                    }
                }
                else
                {
                    if (!p.IsHidden)
                    {
                        ELNode.Store((locationRoot / o % p.Container));
                    }
                }
            }
        }
    }
Пример #14
0
    private void UpdateStatusTextBids(ELNode concern)
    {
        var textRoot = concern.ChildWithKey(SStatusText);

        if (textRoot != null && textRoot.Children.Count > 0)
        {
            var text = textRoot.Children[0];
            if (text.Children.Count > 0)
            {
                var bid = Convert.ToSingle(text.Children[0].Key);
                if (bid > maxStatusBid)
                {
                    maxStatusBid = bid;
                    maxBidStatus = text.Key.ToString();
                }
            }
        }
    }
Пример #15
0
    private void UpdateLocations()
    {
        foreach (var p in Registry <PhysicalObject>())
        {
            var o = p.gameObject;
            var n = this.locationRoot.ChildWithKey(o);
            // Don't do anything if /perception/location/O:Location:override in database,
            // which would mean the character is brainwashed about O's position.
            if (n == null || n.Children.Count == 0 || !n.Children[0].ContainsKey(this.brainwashedSymbol))
            {
                // Determine if it's inside something
                if (p.Container == null)
                {
                    // It's not inside another object, so find what room it's in.

                    if (n == null || !n.ExclusiveKeyValue <GameObject>().GetComponent <Room>().Contains(o))
                    {
                        foreach (var r in Registry <Room>())
                        {
                            if (r.Contains(o))
                            {
                                ELNode.Store(this.locationRoot / o % (r.gameObject));
                                if (o == this.gameObject)
                                {
                                    this.myCurrentRoom = r;
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (!p.IsHidden)
                    {
                        ELNode.Store((this.locationRoot / o % p.Container));
                    }
                }
            }
        }
    }
Пример #16
0
 internal void Start()
 {
     updateConcernBids        = this.UpdateConcernBids;
     elRoot                   = this.KnowledgeBase().ELRoot;
     this.perceptionRoot      = elRoot / Symbol.Intern("perception");
     this.locationRoot        = perceptionRoot / Symbol.Intern("location");
     this.conversationalSpace = perceptionRoot / Symbol.Intern("conversational_space");
     this.socialSpace         = perceptionRoot / Symbol.Intern("social_space");
     this.motorRoot           = elRoot / Symbol.Intern("motor_state");
     this.physiologicalStates = elRoot / Symbol.Intern("physiological_states");
     this.eventHistory        = elRoot / Symbol.Intern("event_history");
     this.lastDestination     = elRoot / Symbol.Intern("last_destination");
     ELNode.Store(lastDestination % null);  // Need a placeholder last destination so that /last_destination/X doesn't fail.
     if (!KB.Global.IsTrue("register_character", gameObject))
     {
         throw new Exception("Can't register character " + name);
     }
     if (greyOutTexture == null)
     {
         greyOutTexture = new Texture2D(1, 1);
         greyOutTexture.SetPixel(0, 0, new Color(0, 0, 0, 128));
     }
 }
Пример #17
0
        private static bool TryRootQuery(Structure term, PrologContext context, out ELNode foundNode, out ELNodeEnumerator enumerator)
        {
            // Expression is /Key.
            var arg0 = term.Argument(0);

            // This is a "/constant" expression, i.e. a top-level lookup.
            if (arg0 is LogicVariable)
            {
                throw new NotImplementedException("Lookups of the form /Variable are not supported.");
            }
            enumerator = null;
            return context.KnowledgeBase.ELRoot.TryLookup(arg0, out foundNode);
        }
Пример #18
0
 public void SetKB(KnowledgeBase kb)
 {
     root = kb.ELRoot;
     displayChildren.Add(root);
 }
Пример #19
0
 private static bool TryNonExclusiveQueryEnumeratedParent(
     out ELNode foundNode,
     out ELNodeEnumerator enumerator,
     object key,
     LogicVariable v,
     ELNodeEnumerator parentEnumerator)
 {
     // Enumerated parent path
     // NonUniqueParent/Something
     foundNode = null;
     if (v == null)
     {
         // NonUniqueParent/Key
         // Enumerate parent, then do deterministic lookup for child.
         enumerator = new ELNodeEnumeratorFixedChildFromParentEnumerator(parentEnumerator, key);
         return true;
     }
     if (parentEnumerator.BindsVar(v))
     {
         // We're doing a search for a variable that's aready bound.
         enumerator = new ELNodeEnumeratorPreboundVariable(parentEnumerator, v, false);
         return true;
     }
     // NonUniqueParent/Variable
     // Enumerate both parent and child.
     enumerator = new ELNodeEnumeratorLogicVariableFromParentEnumerator(parentEnumerator, v);
     return true;
 }
Пример #20
0
 private static bool TryNonExclusiveQuery(out ELNode foundNode, out ELNodeEnumerator enumerator, ELNode parentNode, object key, LogicVariable v, ELNodeEnumerator parentEnumerator)
 {
     if (parentNode != null)
     {
         return TryNonExclusiveQueryDeterministicParent(out foundNode, out enumerator, parentNode, key, v);
     }
     return TryNonExclusiveQueryEnumeratedParent(out foundNode, out enumerator, key, v, parentEnumerator);
 }
Пример #21
0
        private static bool TryNonExclusiveQueryDeterministicParent(
            out ELNode foundNode,
            out ELNodeEnumerator enumerator,
            ELNode parentNode,
            object key,
            LogicVariable v)
        {
            // Deterministic parent path
            // The expression is UniqueParent/Something
            if (parentNode.IsExclusive)
            {
                throw new ELNodeExclusionException("Non-exclusive query of an exclusive node", parentNode, key);
            }

            if (v == null)
            {
                // fully deterministic path
                // UniqueParent/Key corresponds to at most one ELNode.
                enumerator = null;
                return parentNode.TryLookup(key, out foundNode);
            }
            // UniqueParent/Variable, so do a singly-nested iteration.
            foundNode = null;
            enumerator = new ELNodeEnumeratorLogicVariableFromNode(parentNode, v);
            return true;
        }
Пример #22
0
 public ELNodeEnumeratorLogicVariableFromNode(ELNode parentNode, LogicVariable v)
 {
     this.parentNode = parentNode;
     this.variable = v;
     childIndex = parentNode.Children.Count - 1;
 }
Пример #23
0
 internal void Start()
 {
     updateConcernBids = this.UpdateConcernBids;
     elRoot = this.KnowledgeBase().ELRoot;
     this.perceptionRoot = elRoot / Symbol.Intern("perception");
     this.conversationalSpace = perceptionRoot / Symbol.Intern("conversational_space");
     this.socialSpace = perceptionRoot / Symbol.Intern("social_space");
     this.motorRoot = elRoot / Symbol.Intern("motor_state");
     this.eventHistory = elRoot / Symbol.Intern("event_history");
     this.lastDestination = elRoot / Symbol.Intern("last_destination");
     ELNode.Store(lastDestination % null);  // Need a placeholder last destination so that /last_destination/X doesn't fail.
     if (string.IsNullOrEmpty(CharacterName))
         CharacterName = name;
     if (!KB.Global.IsTrue("register_character", gameObject, Symbol.Intern(CharacterName)))
         throw new Exception("Can't register prop " + name);
     try
     {
         gameObject.IsTrue(Symbol.Intern("do_all_character_initializations"));
     }
     catch (Exception e)
     {
         Debug.LogError("Exception while initializing character "+gameObject.name);
         Debug.LogException(e);
     }
 }
Пример #24
0
 public void SetKB(KnowledgeBase kb)
 {
     root = kb.ELRoot;
     displayChildren.Add(root);
     WindowTitle = kb.Name + " KB";
 }
Пример #25
0
        private static bool TryExclusiveQuery(
            out ELNode foundNode,
            out ELNodeEnumerator enumerator,
            ELNode parentNode,
            ELNodeEnumerator parentEnumerator,
            object key,
            LogicVariable v)
        {
            //
            // Expression is Parent:Something
            //
            if (parentNode != null)
            {
                return TryExclusiveQueryDeterministicParent(out foundNode, out enumerator, parentNode, key, v);
            }

            return TryExclusiveQueryEnumeratedParent(out foundNode, out enumerator, parentEnumerator, key, v);
        }
Пример #26
0
 private float RenderAt(ELNode node, float x, float y)
 {
     stringBuilder.Length = 0;
     var go = node.Key as GameObject;
     stringBuilder.Append(go != null ?
         ('$'+go.name)
         : (node.Key == null?
             "null"
             : node.Key.ToString()));
     stringBuilder.Append(node.ModeString);
     var suppressChildren = node.Children.Count > 1 && !displayChildren.Contains(node);
     if (suppressChildren)
         stringBuilder.Append(" ...");
     var key = new GUIContent(stringBuilder.ToString());
     var size = Style.CalcSize(key);
     if (mouseClicked && mouseClickY >= y && mouseClickY < y + size.y)
         ToggleNode(node);
     GUI.Label(new Rect(x, y, size.x, size.y), key, Style);
     x += size.x;
     if (node.Children.Count == 0 || suppressChildren)
         y += size.y;
     else
         foreach (var child in node.Children)
         {
             y = this.RenderAt(child, x, y);
         }
     return y;
 }
Пример #27
0
 private void ToggleNode(ELNode node)
 {
     if (displayChildren.Contains(node))
         displayChildren.Remove(node);
     else
     {
         displayChildren.Add(node);
     }
 }
Пример #28
0
 void UpdateConcernBids(ELNode concern)
 {
     // Make sure this isn't the EL root (it's not an actual concern node).
     if (concern.Key != null)
     {
         ELNode bids;
         if (concern.TryLookup(SLocationBids, out bids))
         {
             // Add its bids in
             foreach (var bid in bids.Children)
             {
                 var destination = bid.Key as GameObject;
                 if (destination == null)
                     throw new Exception("Location bid is not a GameObject: "+bid.Key);
                 var bidValue = Convert.ToSingle(bid.ExclusiveKeyValue<object>());
                 if (bidTotals.ContainsKey(destination))
                     bidTotals[destination] += bidValue;
                 else
                     bidTotals[destination] = bidValue;
             }
         }
     }
 }
Пример #29
0
    /// <summary>
    /// Update the set of character's within this characters' conversational space
    /// and generate any necessary enter/leave events.
    /// </summary>
    private void UpdateSpace(Collider2D[] colliders, float radius, ELNode statusNode, string enterEvent, string exitEvent, bool updateNobodySpeaking)
    {
        var characterCount = Physics2D.OverlapCircleNonAlloc(
            transform.position,
            radius,
            colliders,
            1 << gameObject.layer);
        if (characterCount==MaxConversationalSpaceColliders)
            throw new Exception("Too many colliders in conversational space!");

        // Clean out entries that are no longer in the area
        statusNode.DeleteAll(
            node =>
            {
                // Look to see if node's key (a character) appears in the colliders
                for (var i = 0; i<characterCount;i++)
                    if (ReferenceEquals(node.Key, colliders[i].gameObject))
                        return false;
                // It doesn't, so the character left this character's conversational space.

                // Tell this character about it
                QueueEvent(exitEvent, node.Key);

                // Remove the character
                return true;
            });

        // Add new entries
        for (var i = 0; i<characterCount;i++)
        {
            var character = colliders[i].gameObject;
            if (character != gameObject && !statusNode.ContainsKey(character) && myCurrentRoom.Contains(character))
            {
                // The character just arrived in this character's conversational space

                // Tell this character
                QueueEvent(enterEvent, character);

                // Update the KB
                ELNode.Store(statusNode/character);
            }
        }

        if (updateNobodySpeaking)
        {
            bool nobodySpeaking = true;
            for (var i = 0; i<characterCount; i++)
                if (colliders[i].GetComponent<SimController>().IsSpeaking)
                    nobodySpeaking = false;
            if (nobodySpeaking)
                ELNode.Store(perceptionRoot/SNobodySpeaking);
            else
            {
                if (perceptionRoot.ContainsKey(SNobodySpeaking))
                {
                    perceptionRoot.DeleteKey(SNobodySpeaking);
                    pollActions = true;
                }
            }
        }
    }
Пример #30
0
    /// <summary>
    /// Update the set of character's within this characters' conversational space
    /// and generate any necessary enter/leave events.
    /// </summary>
    private void UpdateSpace(Collider2D[] colliders, float radius, ELNode statusNode, string enterEvent, string exitEvent, bool updateNobodySpeaking)
    {
        var characterCount = Physics2D.OverlapCircleNonAlloc(
            transform.position,
            radius,
            colliders,
            1 << gameObject.layer);

        if (characterCount == MaxConversationalSpaceColliders)
        {
            throw new Exception("Too many colliders in conversational space!");
        }

        // Clean out entries that are no longer in the area
        statusNode.DeleteAll(
            node =>
        {
            // Look to see if node's key (a character) appears in the colliders
            for (var i = 0; i < characterCount; i++)
            {
                if (ReferenceEquals(node.Key, colliders[i].gameObject))
                {
                    return(false);
                }
            }
            // It doesn't, so the character left this character's conversational space.

            // Tell this character about it
            QueueEvent(exitEvent, node.Key);

            // Remove the character
            return(true);
        });

        // Add new entries
        for (var i = 0; i < characterCount; i++)
        {
            var character = colliders[i].gameObject;
            if (character != gameObject && !statusNode.ContainsKey(character) && myCurrentRoom != null && myCurrentRoom.Contains(character))
            {
                // The character just arrived in this character's conversational space

                // Tell this character
                QueueEvent(enterEvent, character);

                // Update the KB
                ELNode.Store(statusNode / character);
            }
        }

        if (updateNobodySpeaking)
        {
            bool nobodySpeaking = true;
            for (var i = 0; i < characterCount; i++)
            {
                if (colliders[i].GetComponent <SimController>().IsSpeaking)
                {
                    nobodySpeaking = false;
                }
            }
            if (currentlySpeaking)
            {
                nobodySpeaking = false;
            }
            if (nobodySpeaking)
            {
                ELNode.Store(perceptionRoot / SNobodySpeaking);
            }
            else
            {
                if (perceptionRoot.ContainsKey(SNobodySpeaking))
                {
                    perceptionRoot.DeleteKey(SNobodySpeaking);
                    pollActions = true;
                }
            }
        }
    }
Пример #31
0
 public ELNodeEnumeratorBindAndUnbindVariable(ELNode child, LogicVariable v)
 {
     this.child = child;
     this.variable = v;
 }
Пример #32
0
        private static bool TryExclusiveQueryDeterministicParent(
            out ELNode foundNode,
            out ELNodeEnumerator enumerator,
            ELNode parentNode,
            object key,
            LogicVariable v)
        {
            // Deterministic parent path
            // UniqueParent:Something

            if (parentNode.IsNonExclusive)
            {
                throw new ELNodeExclusionException("Exclusive query of an non-exclusive node", parentNode, key);
            }

            if (v == null)
            {
                // Deterministic child path
                // UniqueParent:Key
                enumerator = null;
                return parentNode.TryLookup(key, out foundNode);
            }

            // Enumerated child path
            // UniqueParent:Variable
            if (parentNode.Children.Count > 0)
            {
                foundNode = null;
                enumerator = new ELNodeEnumeratorBindAndUnbindVariable(parentNode.Children[0], v);
                return true;
            }

            // parentNode is exclusive, but is childless, so we can't match.
            foundNode = null;
            enumerator = null;
            return false;
        }
Пример #33
0
 public ELNodeEnumeratorBindFixedNodeToVariable(ELNode node, LogicVariable variableToBind)
 {
     this.node = node;
     this.variableToBind = variableToBind;
 }
Пример #34
0
        private static bool TryExclusiveQueryEnumeratedParent(
            out ELNode foundNode,
            out ELNodeEnumerator enumerator,
            ELNodeEnumerator parentEnumerator,
            object key,
            LogicVariable v)
        {
            // Non-deterministic parent path
            // NonUniqueParent:Something
            foundNode = null;

            enumerator = (v == null)
                ? new ELNodeEnumeratorEnumerateParentAndLookupExclusiveKey(parentEnumerator, key)
                : (parentEnumerator.BindsVar(v)? (ELNodeEnumerator)new ELNodeEnumeratorPreboundVariable(parentEnumerator, v, true)
                                                 : new ELNodeEnumeratorEnumerateParentAndBindVariable(parentEnumerator, v));
            return true;
        }
Пример #35
0
 internal void Start()
 {
     updateConcernBids = this.UpdateConcernBids;
     elRoot = this.KnowledgeBase().ELRoot;
     this.perceptionRoot = elRoot / Symbol.Intern("perception");
     this.locationRoot = perceptionRoot / Symbol.Intern("location");
     this.conversationalSpace = perceptionRoot / Symbol.Intern("conversational_space");
     this.socialSpace = perceptionRoot / Symbol.Intern("social_space");
     this.motorRoot = elRoot / Symbol.Intern("motor_state");
     this.physiologicalStates = elRoot / Symbol.Intern("physiological_states");
     this.eventHistory = elRoot / Symbol.Intern("event_history");
     this.lastDestination = elRoot / Symbol.Intern("last_destination");
     ELNode.Store(lastDestination % null);  // Need a placeholder last destination so that /last_destination/X doesn't fail.
     if (string.IsNullOrEmpty(CharacterName))
         CharacterName = name;
     if (!KB.Global.IsTrue("register_character", gameObject, Symbol.Intern(CharacterName), Symbol.Intern((Type))))
         throw new Exception("Can't register character " + name);
 }
Пример #36
0
    private void InitiateAction(object action)
    {
        if (action == null)
        {
            return;
        }

        var actionCopy = Term.CopyInstantiation(action);

        ELNode.Store(motorRoot / SLastAction % actionCopy);

        var structure = action as Structure;

        if (structure != null)
        {
            switch (structure.Functor.Name)
            {
            case "face":
                Face(structure.Argument <GameObject>(0));
                break;

            case "say":
                // Say a fixed string
                Say(structure.Argument <string>(0), gameObject);
                break;

            case "cons":
                // It's a list of actions to initiate.
                InitiateAction(structure.Argument(0));
                InitiateAction(structure.Argument(1));
                break;

            case "pause":
                pauseUntil = Time.time + Convert.ToSingle(structure.Argument(0));
                break;

            case "pickup":
            {
                var patient = structure.Argument <GameObject>(0);
                if (patient == gameObject)
                {
                    throw new InvalidOperationException(name + ": tried to pickup() self!");
                }
                if (patient == gameObject)
                {
                    return;
                }
                if (patient == null)
                {
                    throw new NullReferenceException("Argument to pickup is not a gameobject");
                }
                var physob = patient.GetComponent <PhysicalObject>();
                if (physob == null)
                {
                    throw new NullReferenceException("Argument to pickup is not a physical object.");
                }
                physob.MoveTo(gameObject);
                break;
            }

            case "ingest":
            {
                var patient = structure.Argument <GameObject>(0);
                if (patient == null)
                {
                    throw new NullReferenceException("Argument to ingest is not a gameobject");
                }
                var physob = patient.GetComponent <PhysicalObject>();
                if (physob == null)
                {
                    throw new NullReferenceException("Argument to ingest is not a physical object.");
                }
                physob.Destroy();
                // TODO: FIX LOCATION UPDATE SO WE DON'T NEED TO KLUGE THIS
                locationRoot.DeleteKey(patient);
                var propinfo = patient.GetComponent <PropInfo>();
                if (propinfo != null)
                {
                    if (propinfo.IsFood)
                    {
                        physiologicalStates.DeleteKey(Symbol.Intern("hungry"));
                    }
                    if (propinfo.IsBeverage)
                    {
                        physiologicalStates.DeleteKey(Symbol.Intern("thirsty"));
                    }
                }
                break;
            }

            case "putdown":
            {
                var patient = structure.Argument <GameObject>(0);
                if (patient == gameObject)
                {
                    throw new InvalidOperationException(name + ": tried to putdown() self!");
                }
                if (patient == null)
                {
                    throw new NullReferenceException("Argument to putdown is not a gameobject");
                }
                var physob = patient.GetComponent <PhysicalObject>();
                if (physob == null)
                {
                    throw new NullReferenceException("Argument to putdown is not a physical object.");
                }
                var dest = structure.Argument <GameObject>(1);
                if (dest == null)
                {
                    throw new NullReferenceException("Argument to putdown is not a gameobject");
                }
                physob.MoveTo(dest);
                break;
            }

            case "flash":
            {
                flashColorA    = structure.Argument <Color>(0);
                flashColorB    = structure.Argument <Color>(1);
                flashPeriod    = Convert.ToSingle(structure.Argument(2));
                flashStartTime = Time.time;
                flashEndTime   = flashStartTime + Convert.ToSingle(structure.Argument(3));
                break;
            }

            case "get_in":
                GetIn(structure.Argument <GameObject>(0));
                break;

            case "dismount":
                Dismount();
                break;

            case "end_game":
                Application.Quit();
                break;

            default:
                // Assume it's dialog
                this.IsTrue("log_dialog_act", structure);
                GameObject thisAddressee =
                    ((structure.Arity >= 2) ?
                     structure.Argument(1) as GameObject
                            : gameObject) ?? gameObject;
                var talkingToSelf = thisAddressee == gameObject;
                if (!talkingToSelf || ShowMentalMonologue)
                {
                    var    textVar = new LogicVariable("DialogText");
                    object text    = null;
                    try
                    {
                        text = gameObject.SolveFor(textVar, "generate_text", structure, textVar);
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(string.Format("Exception while generating text for {0}", gameObject.name));
                        Debug.LogException(e);
                    }
                    var textString = text as string;
                    if (textString == null)
                    {
                        throw new Exception(
                                  "generate_text returned " + ISOPrologWriter.WriteToString(text) + " for "
                                  + ISOPrologWriter.WriteToString(structure));
                    }
                    var talkingToPlayer = structure.Arity >= 2 &&
                                          ReferenceEquals(structure.Argument(1), playerSymbol);
                    SetSpeechTimeout(textString);
                    if (talkingToPlayer)
                    // Character is talking to zhimself
                    {
                        if (nlPrompt != null)
                        {
                            nlPrompt.OutputToPlayer(textString);
                        }
                        else
                        {
                            Say(string.Format("({0})", textString), thisAddressee);
                        }
                    }
                    else
                    {
                        Say(textString, thisAddressee);
                    }

                    if (!talkingToPlayer && !talkingToSelf)
                    {
                        // Tell the other characters
                        foreach (var node in socialSpace.Children)
                        {
                            var character = (GameObject)(node.Key);
                            if (character != gameObject)
                            {
                                character.QueueEvent((Structure)Term.CopyInstantiation(structure));
                            }
                        }
                        // TODO: fix it so that when characters appear, the system computes their social
                        // spaces from scratch.  Then we won't need this kluge.
                        if (!socialSpace.ContainsKey(thisAddressee))
                        {
                            thisAddressee.QueueEvent((Structure)Term.CopyInstantiation(structure));
                        }
                    }
                }
                break;
            }
            if (structure.Functor.Name != "pause")
            {
                // Report back to the character that the action has occurred.
                QueueEvent(structure);
            }
        }
        else
        {
            throw new InvalidOperationException("Unknown action: " + ISOPrologWriter.WriteToString(action));
        }
    }