设为首页收藏本站

塞爱维(CIV)文明联盟

 找回密码
 注册
查看: 5866|回复: 9

[原创] [DLL解析]AI初探之科技选择[史前大坑……]

[复制链接]
发表于 2012-11-9 20:21:25 | 显示全部楼层 |阅读模式
第一楼直接写结论,给不愿细看内容的童鞋提供便利:
[难度常量]
TechNumOptions,AI将从权重位列前TechNumOptions个可选择科技中依据权重随机选取,从易到难分别为10/4/3/2/2/2/2/2

[科技选择的分类]
1.免费科技选择
2.正常科技选择

[科技选择的条件]
1.无正在研究的科技

[免费科技选择逻辑]
1.检查所有可以直接被研究的科技,依据该科技预设权重排序
2.从权重位列前TechNumOptions个可选择科技中依据权重随机选取

[正常科技选择逻辑]
1.队友是否正在研究自己可以直接研究的科技?
  (1)有,全部压入研究队列,退出;
  (2)没有,继续下一步。
2.检查所有可以直接被研究的科技,用以下权重计算方法依据权重排序:
  某科技权重W=该科技预设权重/(研究该科技剩余回合数^(0.15+0.015*研究该科技剩余回合数))
3.从权重位列前TechNumOptions个可选择科技中依据权重随机选取,压入研究队列

[研究队列]
先进入队列的科技先被研究,后进入的后被研究,已被研究会弹出(不管是自己研究出来的还是队友)

[无正在研究的科技的条件]
研究队列空


关于AI的科技选择的代码,分布在CvPlayerAI.cpp和CvTechAI.cpp中,现选择几个关键代码段贴出

[ 本帖最后由 Olemi 于 2012-11-30 03:29 编辑 ]

评分

1

查看全部评分

 楼主| 发表于 2012-11-9 20:21:44 | 显示全部楼层

科技预设权重

(占楼)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:21:57 | 显示全部楼层

科技选择的条件

由于AI_chooseResearch()是唯一的正常的科技选择方法,所以我们来看一下调用它的前后文(两处)
CvPlayer.cpp第17146~17160行
  1. // Force player to pick Research if he doesn't have anything assigned
  2. if(GetPlayerTechs()->GetCurrentResearch() == NO_TECH)
  3. {
  4.         ...
  5.         AI_chooseResearch();
  6.         ...
  7. }
复制代码
CvPlayerAI.cpp第676~680行
  1. if(GetPlayerTechs()->GetCurrentResearch() == NO_TECH)
  2. {
  3.         AI_chooseResearch();
  4.         //AI_forceUpdateStrategies(); //to account for current research.
  5. }
复制代码
其中的GetPlayerTechs()是同一个方法,据此判断选择科技的条件是无正在研究的科技
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:22:10 | 显示全部楼层

正常科技选择的权重计算

代码在CvTechAI.cpp第317~327行:
  1. iTurnsLeft = m_pCurrentTechs->GetResearchTurnsLeft(eTech, true);

  2. double fWeightDivisor;

  3. // 10 turns will add 0.02; 80 turns will add 0.16
  4. double fAdditionalTurnCostFactor = GC.getAI_RESEARCH_WEIGHT_MOD_PER_TURN_LEFT() * iTurnsLeft;        // 0.015
  5. double fTotalCostFactor = GC.getAI_RESEARCH_WEIGHT_BASE_MOD() + fAdditionalTurnCostFactor;        // 0.15

  6. fWeightDivisor = pow((double) iTurnsLeft, fTotalCostFactor);

  7. int iNewWeight = int(double(m_ResearchableTechs.GetWeight(iI)) / fWeightDivisor);
复制代码
由此可得iNewWeight=Weight/(iTurnsLeft^I_RESEARCH_WEIGHT_BASE_MOD+AI_RESEARCH_WEIGHT_MOD_PER_TURN_LEFT* iTurnsLeft),以此作为其权重
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:22:25 | 显示全部楼层

依据权值选择科技代码

代码在CvTechAI.cpp第197~203行
  1. // If total weight is above 0, choose one above a threshold
  2. if(m_ResearchableTechs.GetTotalWeight() > 0)
  3. {
  4.         int iNumChoices =GC.getGame().getHandicapInfo().GetTechNumOptions();
  5.         rtnValue = (TechTypes) m_ResearchableTechs.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing tech from Top Choices");
  6.         LogResearchChoice(rtnValue);
  7. }
复制代码
和CvWeightVector.h第230~249行(即ChooseFromTopChoices()函数的代码)
  1. // Get the total weight
  2. for (i = 0; i < iNumChoices; i++)
  3. {
  4.         elem = m_pItems[i];
  5.         TotalTopChoicesWeight += elem.m_iWeight;
  6. }

  7. // Random roll up to total weight
  8. iChoice = (*rndFcn)(iTotalTopChoicesWeight, szRollName);

  9. // Find out which element was chosen
  10. for (i = 0; i < iNumChoices; i++)
  11. {
  12.         elem = m_pItems[i];
  13.         Choice -= elem.m_iWeight;
  14.         if (iChoice < 0)
  15.         {
  16.                 return elem.m_Element;
  17.         }
  18. }
复制代码
在执行这段代码之前,所有可以研究的科技都会被按权重从大到小的顺序排列。由于科技的选择取决于前一段代码中rtnValue的值,即ChooseFromTopChoices()的返回值,所以ChooseFromTopChoices()函数的执行将会影响最终AI的决策。后一段代码中第一个循环将所允许选择的科技(即权重排前iNumChoices个的科技)的权值相加,iChoice取得一个随机数,由第二个循环决策选择哪个科技。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:22:40 | 显示全部楼层

排序代码

代码在CvTechAI.cpp第194行
  1. m_ResearchableTechs.SortItems();
复制代码
和CvWeightVector.h第137~141行
  1. /// Sort this stuff from highest to lowest
  2. void SortItems ()
  3. {
  4.         std::sort(m_pItems.begin(), m_pItems.end());
  5. }
复制代码
至于为什么可以从大到小排,2k的程序员搞了一个小动作(CvWeightVector.h第43~47行):
  1. bool operator< (const WeightedElement& b2) const
  2. {
  3.         // Reverse of the normal direction because we want highest weight first in our list
  4.         return m_iWeight > b2.m_iWeight;
  5. };
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:23:01 | 显示全部楼层

现有问题

1.预设权重的计算方式(貌似是个大坑……)

[ 本帖最后由 Olemi 于 2012-11-9 21:08 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-11-9 20:26:30 | 显示全部楼层
阶段性完
回复 支持 反对

使用道具 举报

发表于 2012-11-9 23:23:00 | 显示全部楼层
等總結.............................
回复 支持 反对

使用道具 举报

发表于 2012-11-9 23:30:41 | 显示全部楼层
你就是那定盘的星
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|塞爱维(CIV)文明联盟    

GMT+8, 2024-4-29 13:31

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表