Prolog:编写rpg stat打印程序时的算术问题

时间:2015-05-14 11:31:31

标签: prolog

我一直在努力编写(作为练习 - 学习一些关于prolog的)一个小代码片段,打印Pen and Paper RPG特定种族的所有可能的统计组合。

相关代码片段:

%abilities
ability(X) :-
    member(X, [str, dex, con, int, wis, cha]).

race(tiefling, planetouched, [[dex, 2], [int, 2], [cha, -2]], [infernalResistance,darkvision,skillAffinity(bluff),skillAffinity(hide)],rogue, 1, medium).
race(human, human, [], [quickToMaster, skilled], any, 0, medium).

racialAttributeBonus(Race, Stat, Bonus) :-
    race(Race, _, BonusList, _, _, _, _),
    member([Stat, Bonus], BonusList).

racialAttributeBonus(Race, Stat, 0) :-
    race(Race, _, BonusList, _, _, _, _),
    \+ member([Stat, _], BonusList).

%start ability points is 32

%first 6 points - 1 point per increase
%7, 8 - +2 per increase
%9, 10 - +3 per increase

statDiffCost(Diff, Cost) :-
    Range = [Diff, Cost],
    member(Range, [
            [0, 0],
            [1, 1],
            [2, 2],
            [3, 3],
            [4, 4],
            [5, 5],
            [6, 6],
            [7, 8],
            [8, 10],
            [9, 13],
            [10, 16]
        ]).

raceAttribCost(Race, AttrName, AttrValue, Cost) :-
    number(AttrValue),
    racialAttributeBonus(Race, AttrName, Bonus),
    AttrDiff is AttrValue - Bonus - 8,
    statDiffCost(AttrDiff, Cost).

raceAttribCost(Race, AttrName, AttrValue, Cost) :-
    number(Cost),
    racialAttributeBonus(Race, AttrName, Bonus),
    statDiffCost(AttrDiff, Cost),
    AttrValue is AttrDiff + Bonus + 8.

raceAttributes(Race, Str, Dex, Con, Int, Wis, Cha) :-
    StrCost + DexCost + ConCost + IntCost + WisCost + ChaCost is 32,
    raceAttribCost(Race, str, Str, StrCost),
    raceAttribCost(Race, dex, Dex, DexCost),
    raceAttribCost(Race, con, Con, ConCost),
    raceAttribCost(Race, int, Int, IntCost),
    raceAttribCost(Race, wis, Wis, WisCost),
    raceAttribCost(Race, cha, Cha, ChaCost).

但是,我遇到了一些与处理数字/算术相关的问题。

首先,我希望

 raceAttributes(human, Str, Dex, Con, Int, Wis, Cha).

会打印参数组合。相反,我得到false

其次,我无法以优雅的方式处理raceAttribCoststatDiffCost中的数字参数。

基本上,我必须创建raceAttribCost的两个版本,因为根据我指定的参数,其中一个将需要"实例化"比较右侧的变量。

所以,我想知道如何

  1. 致电raceAttributes实际工作。
  2. 删除raceAttribCost的其中一个版本并保留其中一个
  3. (可选)用更紧凑的内容替换statDiffCost
  4. 这三个都是同一个问题的一部分,它混合了象征性的"计算"和数字算术。

    么?

    P.S。我在Windows 7上使用SWI-PL 64bit。

2 个答案:

答案 0 :(得分:3)

使用CLP(FD)约束非常容易解决。

关于你的第一个问题(为什么会失败):is/2不适用于左侧的复合词。您需要=:=/2来比较算术表达式的评估。但是,由于未经实例化的变量,仅仅将is/2替换为=:=/2在您的情况下无效。

要解决此问题,只需使用程序中的CLP(FD)约束is/2替换所有出现的#=/2,并在程序开头添加:- use_module(library(clpfd)).。这产生了一个更通用的程序。

然后,只需删除当时不必要的number/1目标,并删除多余的条款。

示例查询及其与新版本的结果:

?- raceAttributes(human, Str, Dex, Con, Int, Wis, Cha).
Str = Dex, Dex = Con, Con = Int, Int = 8,
Wis = Cha, Cha = 18 ;
Str = Dex, Dex = Con, Con = 8,
Int = 11,
Wis = 17,
Cha = 18 ;
Str = Dex, Dex = Con, Con = 8,
Int = 11,
Wis = 18,
Cha = 17 ;
etc.

完全按预期在各个方向工作。

答案 1 :(得分:3)

你可以这样继续:

  1. 用于关系整数算术:

      :- use_module(library(clpfd)).
    
  2. is的所有用途替换为#=

  3. 删除所有number/1目标。

  4. 重新运行原始查询并向后报告:)