游戏人工智能之状态驱动智能体改进(三)

游戏人工智能之状态驱动智能体改进(三)

之前在忙考试,耽误了几天时间。今天我们继续之前的代码。
我们发现状态机实现的矿工行为总是固定不变的,于是我引入了天气作为不确定的因素,天气分为晴天、多云和下雨。晴天时,挖矿会更让人觉得口渴;下雨天时,矿工会回家,如果矿工非常疲倦,那么他回家就会睡觉,如果不是很累,那么矿工也会从事娱乐活动–网购,当然网购是要花钱的。现在和之前不同,喝水也要花钱购买。如果矿工入不敷出,那么他就会破产。
我们在之前代码的基础上进行修改(这次的代码相对来说要复杂一些,我加上注释方便阅读):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace SDIB
{
    enum Weather
    {
        Sunny,Rainy,Cloudy
    }
    //随机生成天气
    class WeatherEvent
    {
        public Weather getWeather()
        {
            Weather[] weathers = Enum.GetValues(typeof(Weather)) as Weather[];
            Random random = new Random();
            Weather weather = weathers[random.Next(0, weathers.Length)];
            return weather;
        }

    }
    //挖矿
    class DigNugget
    {
        public int money;
        public int gold;
        public int tired;
        public int health;
        public Weather weather;
        public int count;


        public delegate void MinerEventHandler(Object listener,MinerEventArgs e);
        public event MinerEventHandler Miner;

        public class MinerEventArgs : EventArgs
        {
            public readonly int money;
            public readonly int tired;
            public readonly int health;

            public MinerEventArgs(int money, int tired, int health)
            {
                this.money = money;
                this.tired = tired;
                this.health = health;
            }
        }

        protected virtual void OnActive(MinerEventArgs e)
        {
            if (Miner != null)
            {
                Miner(this, e);
            }
        }

        public void Update()
        {
            gold = 0;
            WeatherEvent weatherAction = new WeatherEvent();
            weather = weatherAction.getWeather();
            while (true)
            {

                count++;
                //如果计数大于5天气就会变化
                if (count >= 5)
                {
                    count = 0;            
                    weather = weatherAction.getWeather();
                }
                if (gold < 0)
                {
                    break;
                }

                //晴天挖矿会更加口渴
                if(weather == Weather.Sunny){
                    tired ++;
                    health -= 3;
                    money++;
                    Console.WriteLine("天气:晴天");
                    Console.WriteLine("挖矿中");
                    Thread.Sleep(1000);   

                }
                //多云和之前一样
                else if (weather == Weather.Cloudy)
                {
                    tired++;
                    health--;
                    money++;
                    Console.WriteLine("天气:多云");
                    Console.WriteLine("挖矿中");
                    Thread.Sleep(1000);   

                }

                MinerEventArgs mea = new MinerEventArgs(money, tired, health);
                OnActive(mea);
                //下雨了回家
                if (weather == Weather.Rainy)
                {
                    Console.WriteLine("天气:下雨");  
                    Console.WriteLine("下雨了,回家躲雨");
                    Thread.Sleep(1000);
                    GoHome.Update(this, mea);
                    continue;
                }


                if (tired >= 10)
                {
                    Console.WriteLine("累了,回家睡觉");
                    Thread.Sleep(1000);
                    //Miner += GoHome.Update;
                    GoHome.Update(this, mea);
                    continue;
                }
                if (health <= 0)
                {
                    Console.WriteLine("渴了,去酒吧喝酒");
                    Thread.Sleep(1000);
                    //Miner += GoBar.Update;
                    GoBar.Update(this, mea);
                    continue;
                }
                if (money >= 3)
                {
                    Console.WriteLine("包满了,去银行换钱");
                    Thread.Sleep(1000);
                    //Miner += GoBank.Update;
                    GoBank.Update(this, mea);
                    continue;
                }

            }

        }
    }

    class GoHome
    {
        public static void Update(Object listener, DigNugget.MinerEventArgs e)
        {
            DigNugget mine = (DigNugget)listener;
            bool isSleep = false;
            while (true)
            {
                //计数大于变换天气
                if (mine.count >= 5)
                {
                    mine.count = 0;
                    WeatherEvent weatherAction = new WeatherEvent();
                    mine.weather = weatherAction.getWeather();
                }
                //下雨、疲劳小于5,网购
                if (mine.weather == Weather.Rainy && mine.tired <= 5 && isSleep == false)
                {

                    Console.WriteLine("下雨了,不出去,在家网购");
                    Thread.Sleep(1000);
                    mine.gold--;
                    mine.count += 5;
                    //网购需要花钱,矿工没钱了就会破产
                    if (mine.gold < 0)
                    {
                        Console.WriteLine("矿工破产了");
                        break;
                    }
                    Console.WriteLine("剩余存款:" + mine.gold);
                    continue;
                }
                //否则睡觉
                else if (mine.tired > 0)
                {
                    Console.WriteLine("睡觉中");
                    Thread.Sleep(1000);
                    isSleep = true;
                    mine.tired --;
                    mine.count ++;
                    //睡醒了如果发现不下雨就去挖矿
                    if (mine.tired <= 0 && mine.weather != Weather.Rainy)
                    {
                        Console.WriteLine("睡醒了");
                        isSleep = false;
                        if (mine.weather != Weather.Rainy)
                        {
                            Console.WriteLine("去挖矿");
                            Thread.Sleep(1000);
                            break;
                        }
                    }

                }
                //如果不下雨了就去挖矿
                else if (mine.weather != Weather.Rainy)
                {
                    Console.WriteLine("去挖矿");
                    Thread.Sleep(1000);
                    break;
                }
            }


        }
    }
    //去银行存钱,每存一次钱金钱数加1
    class GoBank
    {
        public static void Update(Object listener, DigNugget.MinerEventArgs e)
        {
            DigNugget mine = (DigNugget)listener;
            mine.money = 0;
            mine.count++;
            mine.gold++;
            Console.WriteLine("存钱中,存款:"+mine.gold);

            Thread.Sleep(1000);
            Console.WriteLine("继续去金矿干活");
            Thread.Sleep(1000);
        }
    }
    //去酒吧
    class GoBar
    {
        public static void Update(Object listener, DigNugget.MinerEventArgs e)
        {
            DigNugget mine = (DigNugget)listener;
            mine.health = 10;
            mine.count++;
            mine.gold--;
            //喝酒也要花钱,如果没钱就会破产
            if (mine.gold < 0)
            {
                Console.WriteLine("矿工破产了");
                return;
            }
            Console.WriteLine("喝水中,剩余存款:" + mine.gold);
            Thread.Sleep(1000);
            Console.WriteLine("不渴了,去金矿");
            Thread.Sleep(1000);
        }
    }

    //main函数
    class Program
    {
        static void Main(string[] args)
        {
            DigNugget miner = new DigNugget();
            miner.money = 0;
            miner.tired = 0;
            miner.health = 10;
            miner.Update();
        }
    }
}

这样我们的矿工就显得智能多了:
这里写图片描述

当然有时候矿工也会很倒霉(有些不合理):
这里写图片描述

其实这个程序还有可以改进的地方,比如可以加入房租,每隔固定时间就要交房租,或者在去往银行的途中有几率遇到小偷,遭遇小偷后包里的矿就没了,只能回去继续挖矿等等。当然条件越多矿工生存越艰难,所以我们也可以对矿物进行枚举,分为铜矿、银矿、金矿,不同的矿物价值不同,如果挖到金矿那矿工也可以在家休息很久了(前提是去银行途中没有遇到小偷。。)。总而言之,我们的状态机实现了我们想要的功能,但是还比较单一,在接下来我们尝试加上一些社群行为。



如果有什么疑问可以留言>_<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值