ハノイの塔について

[戻る]
ハノイ 2003/02/21(金) 10:37:31
下に示すハノイの塔のプログラムを完成したのですが、円盤が4つの場合と6つの場合での区別
の仕方がわかりません。教えてください。お願いします。


#include <stdlib.h>
    #include <stdio.h>
    #define MAX_PLATE 100
    #define max(x,y) (((x) >= (y)) ? (x) : (y))

    void hanoi (
        int aaiPlace [][3], int iFrom, int iTo, int iOther, int iCount);
    void move (int aaiPlace [][3], int iFrom, int iTo);
    void display (int aaiPlace [][3]);

    int main (int argc, char* argv [])
    {
        int i, iCount;
        int aaiPlace [MAX_PLATE + 1][3]; // 棒 A, B, C

        if (argc < 2)
        {
            printf ("Usage: hanoi <number>\n");
            return -1;
        }
        iCount = atoi (argv [1]);
        if (iCount <= 0)
        {
            printf ("Error: <number> は 1 以上にしてください。\n");
            return -2;
        }
        if (iCount > MAX_PLATE)
        {
            printf (
                "Error: <number> は %d 以下にしてください。\n",
                MAX_PLATE);
            return -3;
        }

        for (i = 0; i < MAX_PLATE; i ++)
        {
            // まずは全ての棒を空にする
            aaiPlace [i][0] = 0;
            aaiPlace [i][1] = 0;
            aaiPlace [i][2] = 0;
        }
        for (i = 0; i < iCount; i ++)
        {
            // 棒 A に全ての円盤を乗せる
            aaiPlace [i][0] = iCount - i;
        }

        // 初期状態を表示
        display (aaiPlace);

        // 棒 A から棒 C に、棒 B を用いて iCount の円盤を動かす
        hanoi (aaiPlace, 0, 2, 1, iCount);

        return 0;
    }

    void hanoi (
        int aaiPlace [][3], int iFrom, int iTo, int iOther, int iCount)
    {
        if (iCount > 1)
        {
            hanoi (aaiPlace, iFrom, iOther, iTo, iCount - 1);
        }

        move  (aaiPlace, iFrom, iTo);
        // 現在の状態を表示
        display (aaiPlace);

        if (iCount > 1)
        {
            hanoi (aaiPlace, iOther, iTo, iFrom, iCount - 1);
        }
    }

    void move (int aaiPlace [][3], int iFrom, int iTo)
    {
        int iFromPos, iToPos, i;

        for (i = 0; aaiPlace [i][iFrom] > 0; i ++)
        {
        }
        iFromPos = i - 1;
        if (iFromPos < 0)
        {
            // iFrom に 1 枚も円盤がない
            return;
        }
        for (i = 0; aaiPlace [i][iTo] > 0; i ++)
        {
        }
        iToPos = i;

        // 円盤を移動
        aaiPlace [iToPos  ][iTo]   = aaiPlace [iFromPos][iFrom];
        aaiPlace [iFromPos][iFrom] = 0;
    }

    void display (int aaiPlace [][3])
    {
        // 最大の円盤の大きさを求める
        int iWidth = max (aaiPlace [0][0], max (aaiPlace [0][1],
            aaiPlace [0][2]));
        // 必要な棒の高さを求める
        int iHeight = iWidth;

        int i, j, k;
        for (i = iHeight - 1; i >= 0; i --)
        {
            for (j = 0; j < 3; j ++)
            {
                // 各棒の左側を描く
                for (k = 0; k < iWidth; k ++)
                {
                    if (k < iWidth - aaiPlace [i][j])
                    {
                        printf (" ");
                    }
                    else
                    {
                        printf ("*");
                    }
                }

                // 棒を描く
                printf ("|");

                // 各棒の右側を描く
                for (k = 0; k < iWidth; k ++)
                {
                    if (k < aaiPlace [i][j])
                    {
                        printf ("*");
                    }
                    else
                    {
                        printf (" ");
                    }
                }
            }
            // 一行描き終わったので改行
            printf ("\n");
        }

        for (i = 0; i < (iWidth * 2 + 1) * 3; i ++)
        {
            // テーブルを描く
            printf ("=");
        }
        // 最後に 2 行改行
        printf ("\n\n");
    }

sugar 2003/02/21(金) 13:15:07
> 円盤が4つの場合と6つの場合での区別の仕方がわかりません。
>
なぜ区別する必要性があるのですか?
4か6かでハノイの解き方が変わるようでは、ダメなんじゃないでしょうか。

古いスレッドには追加発言できません。