Top >コンソール・アプリケーション集

プニグマ punigma C++

#include    <stdio.h>
#include    <conio.h>

/////////////////////////////////////////////////////////////////////
// ローターの機能に対応するクラス
/////////////////////////////////////////////////////////////////////
class Roter
{
protected:
    int mWire[26];  // 結線
    int mPosition;  // 位置

    /////////////////////////////////////////////////////////////////
    // ローターの結線を設定する
    //  n1: 結線する端子(0~25)
    //  n2: 結線する端子(0~25)
    /////////////////////////////////////////////////////////////////
    void Connect(int n1, int n2)
    {
        mWire[n1] = n2;
        mWire[n2] = n1;
    }

public:
    /////////////////////////////////////////////////////////////////
    // コンストラクタ
    /////////////////////////////////////////////////////////////////
    Roter()
    {
        // ローターの結線を設定します
        // 0~25が、必ず1回、使用されるようにします
        Connect(16, 6);
        Connect(15, 20);
        Connect(0, 21);
        Connect(17, 22);
        Connect(7, 2);
        Connect(5, 11);
        Connect(12, 23);
        Connect(10, 1);
        Connect(8, 24);
        Connect(3, 25);
        Connect(18, 9);
        Connect(13, 4);
        Connect(14, 19);

        // ローターの初期位置を設定
        mPosition = 0;
    }

    /////////////////////////////////////////////////////////////////
    // 文字を変換する
    //  ch: 変換する文字
    //  return: 変換された文字
    /////////////////////////////////////////////////////////////////
    int Encode(int ch)
    {
        int     n = (ch - 'A' + mPosition) % 26;
        int     encoded = 'A' + ((mWire[n] - mPosition + 26) % 26);

        mPosition++;

        return encoded;
    }

    /////////////////////////////////////////////////////////////////
    // 現在のローターの位置を取得する
    // return:現在のローターの位置(0~25)
    /////////////////////////////////////////////////////////////////
    int GetPosition()   const
    {
        return mPosition;
    }

    /////////////////////////////////////////////////////////////////
    // ローターを回転する
    // n:回転する量
    /////////////////////////////////////////////////////////////////
    void Rotate(int n)
    {
        mPosition = (mPosition + n) % 26;
    }
};

/////////////////////////////////////////////////////////////////////
// プニグマの画面を表示する
//  proter: Roterクラスへのポインタ
//  input: 入力文字列
//  encoded: 変換後文字列
/////////////////////////////////////////////////////////////////////
void ShowPunigma(const Roter& rroter, char* input, char* encoded)
{
    char    str0[] = "-------------------------";
    char    str1[] = "Q W E R T Y U I O P   |||";
    char    str2[] = " A S D F G H J K L    | |";
    char    str3[] = "  Z X C V B N M       |||";

    str2[23] = 'A' + rroter.GetPosition();

    puts(str0);
    puts(str1);
    puts(str2);
    puts(str3);

    printf("\n%s    %s\n", input, encoded);
}

/////////////////////////////////////////////////////////////////////
// main
/////////////////////////////////////////////////////////////////////
void main(void)
{
    Roter   roter;
    int     ch = 0;
    char    input[100] = "";
    char    encoded[100] = "";
    int     count = 0;
    char*   guide =
        "1~9の数字を入力するとローターが回転します。\n"
        "A~Zを入力すると右側に変換した文字を表示します。\n"
        "0を入力するとプログラムを終了します。";

    // 操作ガイドを表示
    puts(guide);

    while (count < 98)
    {
        // 画面を表示
        ShowPunigma(roter, input, encoded);

        ch = _getche();

        // 小文字なら、大文字に変換
        if ('a' <= ch && ch <= 'z')
            ch = ch - 'a' + 'A';

        if ('A' <= ch && ch <= 'Z')
        {
            // A ~ Z の場合
            // 入力文字列と変換後文字列に設定
            input[count] = ch;
            encoded[count] = roter.Encode(ch);

            count++;

            // 文字列終端の0を代入
            input[count] = 0;
            encoded[count] = 0;
        }
        else if ('1' <= ch && ch <= '9')
        {
            // 1 ~ 9 の場合
            // ローターを回転する
            roter.Rotate(ch - '0');

            count = 0;
        }
        else{
            // 0など、それ以外の場合はプログラムを終了
            break;
        }
    }
}
PAPER BOWL
NEZEN