游戏AI算法:GOAP的简单实现

直接贴代码吧,c#模拟的,新建一个控制台项目,然后全部拷贝进去运行即可。

planner部分应该是从目标到当前状态的倒叙a*搜索比较合适,因为我模拟的比较简单,这部分就直接略过了,也就是说在这个项目中所有原子化的action都能直接实现当前状态到目标。

写的比较快,有些地方命名不严格,有些地方随便写的名字。

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApp1 {

    public class AIAction {
        public string name;
       public  Dictionary<string, object> condition=new Dictionary<string, object>();
       public  Dictionary<string, object> effect=new Dictionary<string, object>();
        public delegate void Work();
        public Work work;
        public AIAction(Work w) {
            work = w;
        }
        public void DoWork() {
            work();
        }
    }
    public class AIGoal {
        public string name;
        public Dictionary<string, object> condition=new Dictionary<string, object>();
      
    }
    public class Planner {

        public void SetPlan(List<AIAction> _actions,AIGoal _goal) {
            for(int i = 0; i < _actions.Count; i++) {
                foreach(KeyValuePair<string,object> pair in _actions[i].effect) {
                    bool isFinish = false;
                    foreach(KeyValuePair<string,object> p in _goal.condition) {
                        if (pair.Key == p.Key && (int)pair.Value == (int)p.Value) {
                            isFinish = true;
                            _actions[i].DoWork();
                        }
                    }

                }
            }
        }
    }
     
    public class AI {
        public List<AIAction> aIActions = new List<AIAction>();
        public AIGoal currentGoal = new AIGoal();
        public Planner planner = new Planner();
       
    
        public void PullTrigger(string _condition) {
            if (_condition == "hungry") {
                currentGoal = new AIGoal();
                currentGoal.name = "not hungry";
                currentGoal.condition["hungry=?"] = 100;

            }else if (_condition == "tired") {
                currentGoal = new AIGoal();
                currentGoal.name = "not tired";
                currentGoal.condition["energy=?"] = 100;

            }
            planner.SetPlan(aIActions, currentGoal);
        }
    }
    public class Cow {
        private int hungry = 100;
        private int energy = 100;
        private AI ai =new AI();
        public Cow() {
            AIAction action = new AIAction(Sleep);
            action.name = "sleep";
            action.condition["energy<?"] = 20;
            action.effect["energy=?"] = 100;
            ai.aIActions.Add(action);

            AIAction aIAction = new AIAction(Eat);
            aIAction.name = "eat";
            aIAction.condition["hungry<?"] = 20;
            aIAction.effect["hungry=?"] = 100;
            ai.aIActions.Add(aIAction);
        }
        public  void Eat() {
            hungry = 100;
            Console.WriteLine("i m eating");
        }
        public  void Sleep() {
            energy = 100;
            Console.WriteLine("i m asleep");
        }

        public void decreaseHungry() {
            hungry -= 10;
            if(hungry<10)
            ai.PullTrigger("hungry");
        }
        public void decreaseTired() {
            energy -= 5;
            if(energy<10)
            ai.PullTrigger("tired");
        }

        public void TempSetHungry() {
            hungry = 10;
            ai.PullTrigger("hungry");
        }
        public void TempSetTired() {
            energy = 10;
            ai.PullTrigger("tired");
        }
    }
  
    public class Program {
        public Cow cow=new Cow();

        static void Main(string[] args) {
            Program p = new Program();
            const int SLEEPTIME = 300;
            Console.WriteLine("q= quit");
            Console.WriteLine("w= hungry");
            Console.WriteLine("e= tired");
            while(true){
                p.cow.decreaseHungry();
                p.cow.decreaseTired();
                p.IO();
                Console.WriteLine("----------------------");
                Thread.Sleep(SLEEPTIME);
            }
        }

         async void IO() {
            await Task.Run(() => {
                ConsoleKeyInfo key = Console.ReadKey();
                if (key.KeyChar == 'q') {
                    Environment.Exit(0);
                }else if (key.KeyChar == 'w') {
                    cow.TempSetHungry();
                }else if (key.KeyChar == 'e') {
                    cow.TempSetTired();
                }
            });
    
        }
       
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值