设为首页收藏本站

塞爱维(CIV)文明联盟

 找回密码
 注册
查看: 66209|回复: 122

[原创] 商路全面解析(基于BTS3.17)

[复制链接]
发表于 2008-8-1 10:39:46 | 显示全部楼层 |阅读模式
在原来的KK网上曾有篇关于商路研究的帖子,可惜那篇文章年代比较久远(还是1.61时代的),由于BTS商路计算发生了较大变化,该文已经不适用于BTS版本的商路计算了,因此,我整理收集测试了一下BTS3.17版本的商路算法,集合成这篇新文:商路全面解析(基于BTS3.17)

我将主要讨论3个方面的问题:商路是如何计算的、商路是如何分配的、商路的数量是如何计算的。


*********我们首先来研究单条商路是如何计算的

在BTS中,我们只要把鼠标移动到商路上,就可以看见每条商路的具体数据来源是怎样的,它主要被分成了两个部分:1.基础值和2.各种修正。
1.基础值

决定基础值的有两个因素:(1)和你贸易的对方城市的人口数/10
                                    (2)你到对方城市的距离*6%-16%(巨大—擂台)(很显然,地图越大,因子越小)

基础值在上述两个值中取小,但最小值不会小于1.

你到对方的城市的距离是这样计算的:以你的城市为原点,贸易对象城市的坐标为(x,y),设距离为T,则当x>y时,T=x+y/2,当x<y时,T=x/2+y


2.各种修正(它们全是以百分比的形式出现,各项之间是叠加的关系)

(1)当自己城市大于10级时,每一级+5%
(2)你的城市联通首都 +25%
(3)你与那个国家没有处于战争状态 每回合+3%,直至150%(注意最初联通时就有150%的奖励,但一旦你与其交战则失去此奖励,回到和平状态时再以3%每回合的速度增加)
(4)如果你有港口 +50%
(5)如果你拥有阿特密斯神庙 +100%
(6)跨大陆贸易 +100%
(7)拥有海关且是外国贸易 +100%(注:这里317之前的百科全书里说错了,313百科里说必须是跨大陆商路海关才有加成,实际上跨国贸易就可以了



*********其次,我们来研究商路是如何分配的

商路是电脑自动安排的,这个安排遵循这样一个准则:
(1)全国所有城市中,与任一国外城市的商路最多有1条;与国内城市的商路可以有无数条。
(2)商路是单向的,A到B有商路不代表B到A也有商路。

电脑每次分配商路时,分两步:
1. 先遍历本国所有城市,将各个城市其贸易修正系数从大到小排序,逐一分配商路;
2. 轮到某一城市时,遍历所有国家的所有城市,再从可以建立商路的城市中挑出商路收益最大的前n个城市。

城市贸易修正系数就是商路收益修正系数里(1)(2)(4)(5)之和,即
(1) 当自己城市大于10级时,每一级+5%
(2) 你的城市联通首都 +25%
(4) 如果你有港口 +50%
(5) 如果你拥有阿特密斯神庙 +100%

n = 城市允许的最大商路数

举个简单的例子,你有城市A、B、C,对方有城市1、2、3,其中你的城市里A最大,对方的1最大。如果ABC离1的距离差不多的话,在连接商路时,一般是你的A在和对方的1贸易,那么B、C再也不能与对方的1贸易。有时候,由于A是首都,非常大,因此它同时和1、2、3贸易,也就是说占据了全部国际商路,这时候,你的城市B、C就只能和国内城市贸易了;通常说来,由于A最大,所以B、C都会存在和A贸易的路线,但A不一定和B、C有商路。

既然商路是由电脑安排的,那是否就意味着玩家什么也不用做,就等电脑自己安排就够了呢?答案显然不是这样。玩家不能具体安排商路,但却可以在宏观上调控商路:

(1)与外国开放商路的前提当然是签订通行许可,不过注意若对方采用的重商主义则无法贸易,你用重商的话也是一样,但你可以与你的附庸国和殖民地贸易,见第(4)条和***注

(2)你所拥有的地图对商路的建立有重要的影响:
我国X城可以把某国Y城作为贸易对象的充分必要条件是:X与Y之间可以形成连接,且我国拥有该连接所经的全部中立地区的地图。因此,如果对方国B城可以成为我国A城的贸易对象,那么对方所有和B城在对方国文化边界内有连接的城市均可成为我国A城的贸易对象。
同时,又因为商路是单向的,如果你知道了某国所在的位置,而他不知道你的位置的话,开放边界后,你的城市可以与他的城市贸易,他的城市却不能与你的城市贸易。(这点感谢thorsoar的测试与更正)另:参见****注******注

(3)只有研究了航行术,商路才能通过国界外的河流和浅海连接。只有研究了天文学,商路才能通过大洋连接。所以要掌握好你的科研路线。

(4)与殖民地和附庸国的贸易享受所有国际商路的优势,但重商主义是不禁止它们的。


***注:人们通常理解的重商主义是国家重视商业、鼓励商业贸易,为什么文明4里面却是关闭国际商路呢?

其实这只是人们顾名思义的结果,而历史上:

重商主义既是一种经济学说,又是一套政策体系,是16--18世纪盛行于西欧的一种较普遍现象。事实上与现代不同,大多数论述重商主义理论的是商业人士或哲学家。他们从自身的经济活动出发,对商业资本的运作作了理论上的考察。一般说来,他们同意,只有金银货币才是物质的真正财富,也只有增加一国金银货币的活动才是生产性的活动,鉴于货币差额论与贸易差额论的区别,人们习惯于把重商主义划分为前后两个时期。无论如何,有一点肯定无疑,重商主义是对农耕世界“重农抑末”传统思想的否定,是代表商业资产阶级利益的经济学说。

随着商业活动范围及规模的迅速扩大,海外贸易显示出前所未有的魅力,特许商业公司应运而起,在政府支持下募集社会资金,成为16—18世纪欧洲海外贸易的典型组织形式。商界与政府联合力图促进贸易顺差的实现,以使他国金银尽可能多地流入本国。于是在实践中,重商主义就体现为运用国家政权的力量奖掖工商,发展航运,鼓励出口,限制进口,对外则用狐疑嫉妒的目光打量着自己的邻居,不择手段地大力推进商业活动,加紧殖民掠夺。

因此,重商主义实际上只是一种经济手段,通过剥削殖民地,控制进出口,来使得财富留在国内。在文明4原版中,没有殖民地的存在,所以效果是关闭国际商路,到了BTS中,殖民地出现了,由于重商主义着力于控制与殖民地的贸易,限定殖民地的贸易对象只能是本国,因此,殖民地和本国的贸易是不被禁止的。

****注对于商路建立理论的进一步研究包括:
1.假设A国与B国之间的连接(我测试了道路和河流,没试海滨)经过了C国,只要A国没有与C国开战(甚至不需要联系到C国),且有连接所经过的中立地区的地图,则A国可以把B国作为贸易对象
2.河流只需要单侧的地图

******注:国际商路可以建立的判定条件:
假设现有不属于同一组队(Team)的两个国家A和B,如果AB两国开放了边境,且两者皆未采用重商主义。
那么A国城市X可以建立至B国城市Y的商路的充分且必要条件是:

1. A国的其它城市没有至城市Y的商路;
2. X和Y是运输连通的,即XY可以由公路铁路城市要塞河流海岸大洋相连接。当然河流海岸需航海科技支持,大洋需天文。
3. 至少存在一条在连接X和Y的通路,且这条通路经过的格子属于下述两种情况,
  (a)处于未与A国开战的某国文化境内或其下某个城市的21格内, 这里的某国可以是A国,也可以是还未与A国接触过的国家,只要不是野蛮人就行。
  (b)不位于任何国家境内或某城市(非蛮族)21格内, 则此格必须被A国探索过,且从中立地域边境到文化边境(或某城市21格的外圈)这2格路均须被A国探索过。

(注: 上述通路只要不被敌方海军封锁破坏,即使敌人部队站在上面也不影响商路的建立。)




*********最后,我们来研究一个城市里商路的数量是如何计算的

每个城市初始可以拥有的商路是1;
研究货币后+1;
建造大灯塔,所有海滨城市+2;
建造城堡+1;
采用自由市场政体+1(但其前提科技经济学使城堡失效);
研究公司制+1(但使大灯塔失效);
建造机场+1;
联合国投票通过全球统一货币+1;
迦太基的UB巨港+1;


每个城市最大的商路上限是8条,但在正常游戏里一般不会达到上限的。
这个上限的设置在GlobalDefines.xml里的MAX_TRADE_ROUTE语句里


特别致谢:thorsoar与Khyron的测试与总结;fanruijun的《关于城市的贸易研究》;wwwcyc的《为何重商主义关闭国际商路?》;Krikkitone的《trade route》


关于商路相关内容的进一步研究:

Khyron的《大商贸易收入计算公式(BTS317)》http://www.civclub.net/bbs/viewthread.php?tid=31719&extra=page%3D1

[ 本帖最后由 孟仲玄 于 2008-10-20 22:01 编辑 ]
发表于 2008-8-1 10:43:13 | 显示全部楼层

回复 #1 孟仲玄 的帖子

城堡呢?不是也加一条么
 楼主| 发表于 2008-8-1 10:45:04 | 显示全部楼层
对,忘了,赶快补充上去
发表于 2008-8-1 10:46:18 | 显示全部楼层

回复 #3 孟仲玄 的帖子

那我来帮忙补精
发表于 2008-8-1 10:47:18 | 显示全部楼层
哇.....这个也有精......
发表于 2008-8-1 11:02:23 | 显示全部楼层
原帖由 孟仲玄 于 2008-8-1 10:39 发表
(3)你与那个国家没有处于战争状态 每回合+3%,直至150%(注意最初联通时就有150%的奖励,但一旦你与其交战则失去此奖励,回到和平状态时再以3%每回合的速度增加)

实际上不是初始联通时就有150%的奖励
是因为你联通的时候已经有50个回合和平累计了。
也就是说,这个商路的修正值和有没有实际商路连接没有任何关系。

比如你开战后和平,不开边界,50个回合后开边,依然是150%
或者你刚开局就WB出文字和航海,试试看有没有150%的加成。
 楼主| 发表于 2008-8-1 11:05:10 | 显示全部楼层
原帖由 西艾薇.Z.罗莉 于 2008-8-1 11:02 发表

实际上不是初始联通时就有150%的奖励
是因为你联通的时候已经有50个回合和平累计了。
也就是说,这个商路的修正值和有没有实际商路连接没有任何关系。

比如你开战后和平,不开边界,50个回合后开边,依 ...

恩...应该是这样,我去修改。(不过游戏中前50回合就开边境且连路貌似除了WB外不太可能
发表于 2008-8-1 11:12:57 | 显示全部楼层
以前做过的测试结论

国内商路--可以无视,多个2条也没实际用处
国际商路--很赚,商路大概就是瞄准这个,所以首都靠海会比较暴力
发表于 2008-8-1 11:22:27 | 显示全部楼层
原帖由 gowang 于 2008-8-1 11:12 发表
以前做过的测试结论

国内商路--可以无视,多个2条也没实际用处
国际商路--很赚,商路大概就是瞄准这个,所以首都靠海会比较暴力


如果首都附近有很多岛,就更赚了
发表于 2008-8-1 11:27:37 | 显示全部楼层
城市人口数对国际商路的影响最大

盘古6ai的地图,通常人口最高的2.3座城就把有赚头的国际商路都瓜分光了

如果没有办法集中国际商路到首都,通常这局商路可以无视一半了

除非玩海图
发表于 2008-8-1 11:56:57 | 显示全部楼层
在论坛看比在博客看舒服
发表于 2008-8-1 12:00:12 | 显示全部楼层

回复 #10 gowang 的帖子

这是为了突出航海术的重要,可还是谁都不愿意开始就研究。
发表于 2008-8-1 12:29:34 | 显示全部楼层
好文,总算明白了。.
发表于 2008-8-1 12:47:34 | 显示全部楼层
昨天我也在看这个,附代码

  1. int CvCity::getTradeRouteModifier() const
  2. {
  3.         return m_iTradeRouteModifier;
  4. }


  5. int CvCity::totalTradeModifier(CvCity* pOtherCity) const
  6. {
  7.         int iModifier = 100;

  8.         iModifier += getTradeRouteModifier();

  9.         iModifier += getPopulationTradeModifier();

  10.         if (isConnectedToCapital())
  11.         {
  12.                 iModifier += GC.getDefineINT("CAPITAL_TRADE_MODIFIER");
  13.         }

  14.         if (NULL != pOtherCity)
  15.         {
  16.                 if (area() != pOtherCity->area())
  17.                 {
  18.                         iModifier += GC.getDefineINT("OVERSEAS_TRADE_MODIFIER");
  19.                 }

  20.                 if (getTeam() != pOtherCity->getTeam())
  21.                 {
  22.                         iModifier += getForeignTradeRouteModifier();

  23.                         iModifier += getPeaceTradeModifier(pOtherCity->getTeam());
  24.                 }
  25.         }

  26.         return iModifier;
  27. }

  28. int CvCity::getPopulationTradeModifier() const
  29. {
  30.         return std::max(0, (getPopulation() + GC.getDefineINT("OUR_POPULATION_TRADE_MODIFIER_OFFSET")) * GC.getDefineINT("OUR_POPULATION_TRADE_MODIFIER"));
  31. }


  32. int CvCity::getPeaceTradeModifier(TeamTypes eTeam) const
  33. {
  34.         FAssert(NO_TEAM != eTeam);
  35.         FAssert(eTeam != getTeam());

  36.         if (atWar(eTeam, getTeam()))
  37.         {
  38.                 return 0;
  39.         }

  40.         int iPeaceTurns = std::min(GC.getDefineINT("FOREIGN_TRADE_FULL_CREDIT_PEACE_TURNS"), GET_TEAM(getTeam()).AI_getAtPeaceCounter(eTeam));

  41.         if (GC.getGameINLINE().getElapsedGameTurns() <= iPeaceTurns)
  42.         {
  43.                 return GC.getDefineINT("FOREIGN_TRADE_MODIFIER");
  44.         }

  45.         return ((GC.getDefineINT("FOREIGN_TRADE_MODIFIER") * iPeaceTurns) / std::max(1, GC.getDefineINT("FOREIGN_TRADE_FULL_CREDIT_PEACE_TURNS")));
  46. }

  47. int CvCity::getBaseTradeProfit(CvCity* pCity) const
  48. {
  49.         int iProfit = std::min(pCity->getPopulation() * GC.getDefineINT("THEIR_POPULATION_TRADE_PERCENT"), plotDistance(getX_INLINE(), getY_INLINE(), pCity->getX_INLINE(), pCity->getY_INLINE()) * GC.getWorldInfo(GC.getMapINLINE().getWorldSize()).getTradeProfitPercent());

  50.         iProfit *= GC.getDefineINT("TRADE_PROFIT_PERCENT");
  51.         iProfit /= 100;

  52.         iProfit = std::max(100, iProfit);

  53.         return iProfit;
  54. }

  55. int CvCity::calculateTradeProfit(CvCity* pCity) const
  56. {
  57.         int iProfit = getBaseTradeProfit(pCity);

  58.         iProfit *= totalTradeModifier(pCity);
  59.         iProfit /= 10000;

  60.         return iProfit;
  61. }
复制代码
发表于 2008-8-1 12:48:29 | 显示全部楼层
关于城市距离的算法,我有一个问题:假如是环形的盘古地图,A国在大陆最东边海岸,B国在大陆最西侧海岸,2国隔大洋相望,那么在有了航海但是没有光学的情况下(大洋上面也是阴影,也没有国家环球航行),距离怎么算?
发表于 2008-8-1 12:58:18 | 显示全部楼层
另外,原版战神BTS里商路收益的计算公式都有明显区别。这个比较少见。
发表于 2008-8-1 13:18:43 | 显示全部楼层
有关距离计算的几个函数
根据函数来看,#15的问题的回答就是:两个城市的距离是大洋的距离,而非大陆的距离,不管你的科技情况和探索情况如何

  1. inline int plotDistance(int iX1, int iY1, int iX2, int iY2)                                                                                                        // Exposed to Python
  2. {
  3.         int iDX;
  4.         int iDY;

  5.         iDX = xDistance(iX1, iX2);
  6.         iDY = yDistance(iY1, iY2);

  7.         return (std::max(iDX, iDY) + (std::min(iDX, iDY) / 2));
  8. }

  9. inline int xDistance(int iFromX, int iToX)
  10. {
  11.         return coordDistance(iFromX, iToX, GC.getMapINLINE().getGridWidthINLINE(), GC.getMapINLINE().isWrapXINLINE());
  12. }

  13. inline int yDistance(int iFromY, int iToY)
  14. {
  15.         return coordDistance(iFromY, iToY, GC.getMapINLINE().getGridHeightINLINE(), GC.getMapINLINE().isWrapYINLINE());
  16. }

  17. inline int coordDistance(int iFrom, int iTo, int iRange, bool bWrap)
  18. {
  19.         if (bWrap && (abs(iFrom - iTo) > (iRange / 2)))
  20.         {
  21.                 return (iRange - abs(iFrom - iTo));
  22.         }

  23.         return abs(iFrom - iTo);
  24. }
复制代码
发表于 2008-8-1 13:23:20 | 显示全部楼层
孟兄,这里需要修正一下
你到对方的城市的距离是这样计算的:以你的城市为原点,贸易对象城市的坐标为(x,y),则城市(x, y)离你的距离T = x + [y / 2]

正确的应该是这么说,当x>y时,T=x+y/2,当x<y时,T=x/2+y
发表于 2008-8-1 13:24:58 | 显示全部楼层
经过初步测试,商路的建立是不需要探路的。
发表于 2008-8-1 13:27:15 | 显示全部楼层

回复 #17 zz_fly 的帖子

那实际上就是很亏了,可怜的小帆船跑了地球一圈,结果只算了最近的距离,而且也没跨大陆贸易的加成
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-19 16:36

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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