日本のパズルゲーム「River IQ Test」を解くプログラムを作ろうとしています。答えを調べることはできますが、それは楽しくも教育的でもありませんか? :)
ゲームの目的は次のとおりです。
ユーザーが川を渡って人を運ぶことができる筏を使用して、ユーザーはすべての人を左側から右側に移動する必要があります。いかだが使用されるたびに、その側の誰かが再び反対側に操縦してより多くの人を集めるまで、反対側にとどまります.
左側に次のような人がいます。
- 1 囚人
- 1 警察官
- 1 お父さん
- 2人の息子
- 1 マザー
- 2人の娘
クラスの階層構造は次のとおりです。
乗客
- パイロット
- 親
- 母親
- お父さん
 
- 警官
 
- 親
- 囚人
- 子
- 娘
- 息子
 
次の規則に従う必要があります。
- 一度にいかだに乗るのは2人だけです。
- 筏を操縦できるのは警官と父と母だけ
- 囚人は、警官の立ち会いなしに、他の人の前でいかだや川の両側に置くことはできません。
- 父親は、母親の存在なしに、娘と一緒にいかだに乗ったり、川の両側にいることはできません。
- 母親は、父親の存在なしに、息子と一緒にいかだに乗ったり、川の両側にいることはできません。
私がまだ達成する必要があるのは:
- パズルを解くまで試行錯誤するロジック
- 最終的に成功したソリューションを出力するロジック
- 全員が反対側に到達したかどうかを確認するロジック。
これが私の現在のコードです:
プログラム クラス (解決ロジックはここに配置する必要があります)
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();
    }
}
PassengerList クラス
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;
    }
}
サイド クラス (川の側など)
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;
    }
}
いかだ教室
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);
        }
    }
}