我正在尝试制作一个解决日本益智游戏"河流智商测试"的程序,我知道,我可以查找解决方案,但这不会很有趣,现在就教育了吗?:)
这是游戏的目标:
使用筏,用户可以将人们运送过河,用户必须将所有人从左侧传送到右侧.每次使用木筏时,它都停留在另一侧,直到那边的人再次将它引导到另一侧以吸引更多的人.
左侧有以下人员开始:
这是类的层次结构:
必须遵守以下规则:
我需要完成的是:
这是我目前的代码:
class Program
{
Side _leftSide = new Side(Side.RL_Side.RL_LeftSide);
Side _rightSide = new Side(Side.RL_Side.RL_RightSide);
Raft _myRaft = new Raft();
static void Main(string[] args)
{
// TODO: put systematic trial-and-error solving logic here
// TODO: make sure that successful solution is printed to console
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
public class PassengerList : List<Passenger>
{
public bool CheckRulesObeyed()
{
bool isPoliceman = isPresent<Policeman>();
bool isPrisoner = isPresent<Prisoner>();
bool isFather = isPresent<Father>();
bool isSon = isPresent<Son>();
bool isMother = isPresent<Mother>();
bool isDaughter = isPresent<Daughter>();
// ----------------------------------------------
bool isPrisoner_NonPoliceman = (isPrisoner && (isFather || isMother || isDaughter || isSon));
bool isPrisonerRuleViolated = (!(isPoliceman && isPrisoner) && isPrisoner_NonPoliceman);
bool isDaughterRuleViolated = ((isFather && isDaughter) && !isMother);
bool isSonRuleViolated = ((isMother && isSon) && !isFather);
bool AreAllRulesObeyed = !(isPrisonerRuleViolated && isDaughterRuleViolated && isSonRuleViolated);
return AreAllRulesObeyed;
}
private bool isPresent<T>() where T: Passenger
{
foreach (Passenger p in this)
{
if (p is T)
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
public class Side
{
public enum RL_Side
{
RL_RightSide,
RL_LeftSide
}
public RL_Side _whichSide;
public PassengerList _myPeople;
public Side(RL_Side side)
{
_whichSide = side;
_myPeople = new PassengerList();
// left side starts with all the people
if (_whichSide == RL_Side.RL_LeftSide)
{
_myPeople.Add(new Prisoner());
_myPeople.Add(new Policeman());
_myPeople.Add(new Father());
_myPeople.Add(new Son());
_myPeople.Add(new Son());
_myPeople.Add(new Mother());
_myPeople.Add(new Daughter());
_myPeople.Add(new Daughter());
}
}
public bool didEveryoneMakeItToRightSide()
{
if (_whichSide == RL_Side.RL_RightSide)
{
// TODO: implement logic that checks and returns if everyone is on the right side.
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
public class Raft
{
public Side _mySide;
public PassengerList _myPassengers;
public void ChangeSides(Side Destination)
{
_mySide = Destination;
}
public bool LoadRaft(Pilot myPilot, Passenger myPassenger)
{
bool areRulesObeyed = true;
_myPassengers.Add(myPilot);
_myPassengers.Add(myPassenger);
areRulesObeyed = _myPassengers.CheckRulesObeyed();
if (areRulesObeyed == false)
{
UnloadRaft();
}
return areRulesObeyed;
}
public void UnloadRaft()
{
foreach (Passenger p in _myPassengers)
{
_mySide._myPeople.Add(p);
_myPassengers.Remove(p);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我认为你从来没有学过PROLOG。这些问题在PROLOG中都是经典的,更重要的是PROLOG只处理问题的本质。当我在标题中看到逻辑和谜题时,很明显你需要一种逻辑语言。我知道你要求 C#,但这不是一个 OO 问题,正如你所说,这是一个逻辑问题。
请参阅Prolog 深度编程第 229 页第 8.3 节。传教士和食人族 请注意,解决方案比问题中的所有代码都要小。别误会我的意思,很多年前我也经历过同样的情况,双关语。
我认识的一些最好的程序员处理这样的问题不是为了解决方案,而是因为要自己解决这些问题,他们知道他们会学到一些重要的东西,以后可以使用。花几个月的时间来了解 PROLOG 如何解决这个问题,你会比别人给你建议要好得多。如果你不理解递归以及人工智能如何解决问题,那么当你得到解决方案时你就会明白了。
编辑
那么,C# 是否无法解决此类问题呢?
PROLOG 有一个内置的推理引擎和反向链接,它的作用是在给定规则的情况下找到解决方案。您可以从头开始创建一个,这比解决最初的问题更难,但是有一个用 C# 实现的 PROLOG 开源实现,即John Pool 的C#Prolog。虽然您可以查看源代码来了解 PROLOG 的工作原理,但代码经过了大量优化,因此除非您先了解 PROLOG,否则不容易理解。
如果您了解 F# 或函数式语言,如何用纯函数式语言实现 prolog 解释器?可能有帮助。
基本上,问题归结为创建一组规则,然后尝试规则的组合,直到得到满足所有规则的结果。
从这些关键字和短语开始,在此处搜索互联网和问题。
统一
语法统一
回链 推理
引擎
prolog 的工作原理