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

プニグマ punigma VB.NET

Module Punigma

    ''' <summary>
    ''' ローターの機能に対応するクラス
    ''' </summary>
    Class Roter
        Protected mWire As Integer() = New Integer(25) {}   ' 結線
        Protected mPosition As Integer  ' 位置

        ''' <summary>
        ''' 結線を設定する
        ''' </summary>
        ''' <param name="n1">結線する端子(0~25)</param>
        ''' <param name="n2">結線する端子(0~25)</param>
        ''' <remarks></remarks>
        Protected Sub Connect(n1 As Integer, n2 As Integer)
            ' n1 を n2 に、n2 を n1 に結線する
            mWire(n1) = n2
            mWire(n2) = n1
        End Sub

        ''' <summary>
        ''' コンストラクタ
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
            ' ローターの結線を設定します
            ' 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
        End Sub

        ''' <summary>
        ''' 現在のローターの位置を取得する
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Position() As Integer
            Get
                Return mPosition
            End Get
        End Property

        ''' <summary>
        ''' 文字を変換する
        ''' </summary>
        ''' <param name="ch">変換する文字</param>
        ''' <returns>変換された文字</returns>
        ''' <remarks></remarks>
        Public Function Encode(ch As CharAs Char
            Dim n As Integer = (Asc(ch) - Asc("A"c) + mPosition) Mod 26
            Dim encoded As Integer = Asc("A"c) + ((mWire(n) - mPosition + 26) Mod 26)

            mPosition += 1  ' ローターを回転

            Return ChrW(encoded)
        End Function

        ''' <summary>
        ''' ローターを回転する
        ''' </summary>
        ''' <param name="n">回転する量</param>
        ''' <remarks></remarks>
        Public Sub Rotate(n As Integer)
            mPosition = (mPosition + n) Mod 26
        End Sub
    End Class


    ''' <summary>
    ''' 画面の表示
    ''' </summary>
    ''' <param name="roter">ローター</param>
    ''' <param name="input">入力された文字列</param>
    ''' <param name="encoded">変換された文字列</param>
    ''' <remarks></remarks>
    Private Sub ShowPunigma(roter As Roter, input As String, encoded As String)
        Dim str0 As String = "------------------------"
        Dim str1 As String = "Q W E R T Y U I O P   |||"
        Dim str2 As String = " A S D F G H J K L    |*|"
        Dim str3 As String = "  Z X C V B N M       |||"

        str2 = str2.Replace("*"c, ChrW(Asc("A"c) + roter.Position))

        Console.WriteLine(str0)
        Console.WriteLine(str1)
        Console.WriteLine(str2)
        Console.WriteLine(str3)

        Console.WriteLine(vbLf & "{0}    {1}", input, encoded)
    End Sub

    ''' <summary>
    ''' Main
    ''' </summary>
    ''' <remarks></remarks>
    Sub Main()
        Dim roter As New Roter()
        Dim input As String = ""
        Dim encoded As String = ""
        Dim reset As Boolean = False
        ' 文字列表示のリセット
        ' 操作ガイドを表示
        Console.WriteLine("1~9の数字を入力するとローターが回転します。")
        Console.WriteLine("A~Zを入力すると右側に変換した文字を表示します。")
        Console.WriteLine("0を入力するとプログラムを終了します。")

        While input.Length < 30
            ' 画面を表示
            ShowPunigma(roter, input, encoded)

            Dim cki As ConsoleKeyInfo = Console.ReadKey()

            ' 文字を入力
            Dim ch As Char = cki.KeyChar

            ' 小文字なら、大文字に変換
            ch = Char.ToUpper(ch)

            If "A"c <= ch AndAlso ch <= "Z"Then
                ' アルファベットの場合
                If reset Then
                    ' 表示をリセット
                    input = ""
                    encoded = ""
                    reset = False
                End If

                input += ch
                encoded += roter.Encode(ch)
            ElseIf "1"c <= ch AndAlso ch <= "9"Then
                ' 数字の場合。ローターを回す
                roter.Rotate(Asc(ch) - Asc("0"c))

                reset = True
            Else
                Exit While
            End If
        End While
    End Sub

End Module
PAPER BOWL
NEZEN