很快啊,在经历了短短的……(看一眼日期)短短的五天之后,我们的第三篇开发日志就出来了。当然啦,坏消息是这学期的大项目竟然来得这么早,另外就是这周一直高强度存疑地搞这个项目实在是有些腻了,毕竟咱还有许多堆积的其他事情要做,因此之后的更新速度可能会放慢一些。
闲话少叙,本次的主题也已经在标题上展示出来了——日程,主要的作用就是设定智能体一些比较规律的行为,例如工作睡觉等等。虽然智能体完全可以只参照自己当前的状态选择应该做什么,但一些合理的指引是必要的,除了能增强真实性外,也能给每个角色以独有的特点。
当然,可以看到一直到现在我们都只是在捣鼓一些“配件”,到时候这个小镇到底能不能运行起来,以及其中的智能体到底够不够智能,还是有待观察的。之后一期日志会实现活动,再下一期应该就要开始正式的模拟了,不然感觉现在做的这些都有些虚→_→
既然要实现日程那肯定和时间密不可分的,于是我们先写了一个时间模块。首先就是Time
类:
Rustpub struct Time {
pub day: u16,
pub hour: u8,
pub minute: u8,
}
Time
类其实同时包含了两重意义,一个能够代表时刻——当前处于一天的几点几分,一个则表示时间——做一件事需要几小时几分钟,在这里没有区分开来。其实还是我有些懒了
然后是关于当前是星期几的枚举Weekday
:
Rustpub enum Weekday {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
}
由于当前也不考虑能让程序模拟个几百天,因此也就不会记录当前是几月几号。但星期几是有必要进行管理的,毕竟对日程也有重要的影响。
最后是整个项目的时间管理器TimeManager
:
Rustpub struct TimeManager {
pub time: Time,
pub weekday: Weekday,
update_interval: Time,
}
其中time
表示当前是小镇的第几天几时几分,weekday
表示当前是星期几,至于update_interval
……表示的则是每一轮循环的时长,目前计划是5分钟一次更新。
完成了以上的基础元件,接下来就可以实现第二步——事务Transaction
。没错,这其实也是从数据库中偷学来的词,在这里作为日程的基本单元:
Rustpub struct Transaction {
pub name: String,
pub when: Time,
pub place: String,
pub activity: String,
pub duration: Time,
pub repeat: u8, // 0~7 bit: 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, 4: Thursday, 5: Friday, 6: Saturday, 7: Once
}
其实看字段名就很好理解,分别代表的是事务是什么、何时、何地、做了什么、做了多久、以及怎样重复。这里的repeat
字段其实是一个非常精妙的设计自吹自擂,第0到第6比特分别代表从星期日到星期六是否重复,而第7比特表示的则是该事务是否只做一次。比如睡觉是一个每天都会做的事情,那么它的repeat
值就将是127,即第0到第6位是1,第7位是0。
最后的最后便是日程类Schedule
,有了以上两个模块的铺垫,日程类的结构便只需要两个列表:
Rustpub struct Schedule {
transactions: Vec<Transaction>,
todo_list: Vec<Transaction>,
}
每个角色对应一个Schedule
,其中transactions
包含的自然是该角色的全部事务,而todo_list
则表示该角色当天要做的事务,且该列表在每天都将更新,并按时间顺序排列。
当然比较麻烦的是日程文件的读取,日程文件看起来像是下面这样的:
json// resources/characters/Alice/schedule.json
{
"schedules": [
{
"name": "Morning Work",
"when": [8, 0],
"place": "business-district",
"activity": "sale",
"duration": [2, 0],
"repeat": 126
},
{
"name": "Afternoon Work",
"when": [14, 0],
"place": "business-district",
"activity": "sale",
"duration": [3, 0],
"repeat": 126
},
{
"name": "Drink at Tavern",
"when": [18, 0],
"place": "tavern",
"activity": "drink",
"duration": [1, 0],
"repeat": 72
},
{
"name": "Sleep",
"when": [22, 0],
"place": "houses",
"activity": "sleep",
"duration": [8, 0],
"repeat": 127
},
{
"name": "Reading at Library",
"when": [15, 0],
"place": "library",
"activity": "read",
"duration": [2, 0],
"repeat": 1
},
{
"name": "Date with Bob",
"when": [19, 0],
"place": "town-square",
"activity": "date",
"duration": [3, 0],
"repeat": 1
}
]
}
不过至少看上去是清晰明了的,并且在文件层面也很好编辑修改,至于怎样读取保存的事,就任由实现者烦恼吧╮(╯▽╰)╭
最后再在Character
类中增加schedule
的字段,关于日程的部分也差不多就到这里了。另外虽然这里没怎么提及,不过在进行的过程中还是对过去的部分进行了相当多的重构的,例如文件结构方面的调整等等。以及,现在越写越让人怀疑到时候智能体们到底能否如预料般“智能”地运行。没办法,毕竟咱也是第一次做这样的项目。
只能说车到山前必有路,船到桥头自然直。大家做项目的时候千万不要像我这样随心所欲。这次嘛,毕竟只是我一个人的自娱自乐,此时也只好相信我的能力了(。・ω・。)