【C#入門】第11回 文字列と型変換について【じゃんけんゲームを作ろう その11】

2023年2月7日

こんにちは!ノムノムです。

前回は配列についてやりました。

【C#入門】第10回 配列について【じゃんけんゲームを作ろう その10】
【C#入門】第10回 配列について【じゃんけんゲームを作ろう その10】
こんにちは、ノムノムです。 前回までじゃんけんゲームを作成しデバッグできるところまでやりました。 すでにじゃん…
http://nomux2.net/array/

今回は、前回の答え合わせを含めて文字列についてやっていこうと思います。

前回の課題

前回は、勝敗結果を表示してみるという課題をだして終わりました。
表示できましたでしょうか?

配列変数 array_match_result には勝敗結果(2:勝ち、1:負け、0:あいこ)が格納されています。
これを使ってうまいこと表示してみましょう。

結果表示ですので新しく関数を作るのもいいですが、ConvertVictoryMessage関数の中にでも入れてしまいましょう。 ConvertVictoryMessage関数 は関数のところで追加した関数です。

【C#入門】第8回 関数について【じゃんけんゲームを作ろう その8】
【C#入門】第8回 関数について【じゃんけんゲームを作ろう その8】
こんにちは、ノムノムです。 前回は繰り返し文までやりました。 今回は関数をやりたいと思います。 まずはここまで…
http://nomux2.net/method/
//じゃんけんの結果に対し勝敗メッセージに変換します。
private int ConvertVictoryMessage(int judge, ref string victory)
{
    //判定で結果文字列を取得
    switch(judge)
    {
        case 0:
            victory = "あいこ";
            break;
        case 1:
            victory = "負け";
            break;
        case 2:
            victory = "勝ち";
            break;
        default:
            victory = "";
            return -1;
    }

    int cnt_win = 0;            //勝利回数
    int cnt_lose = 0;           //敗北回数
    int cnt_draw = 0;           //引分回数

    //array_match_resultの要素の数だけ繰り返す
    foreach (int res in array_match_result)
    {
        switch(res)
        {
            case 0:
                cnt_draw++; //引分回数に加算
                break;
            case 1:
                cnt_lose++; //敗北回数に加算
                break;
            case 2:
                cnt_win++;  //勝利回数に加算
                break;
            default:
                break;

        }
    }

    //勝敗結果に追加する
    victory += "\r\n" 
             + array_match_result.Length.ToString() + "戦中 " 
             + cnt_win.ToString() + "勝" 
             + cnt_lose.ToString() + "敗" 
             + cnt_draw.ToString() + "分け\r\n"
             + "勝率" + (cnt_win / array_match_result.Length).ToString() + "%";

    return 0;
}

まず勝ち、負け、あいこの数を数えます。

int cnt_win = 0;            //勝利回数
int cnt_lose = 0;           //敗北回数
int cnt_draw = 0;           //引分回数

//array_match_resultの要素の数だけ繰り返す
foreach (int res in array_match_result)
{
    switch(res)
    {
        case 0:
            cnt_draw++; //引分回数に加算
            break;
        case 1:
            cnt_lose++; //敗北回数に加算
            break;
        case 2:
            cnt_win++;  //勝利回数に加算
            break;
        default:
            break;

    }
}

これで数を取得できました。foreach文は便利です。

次に表示部分です。

//勝敗結果に追加する
victory += "\r\n" 
         + array_match_result.Length.ToString() + "戦中 " 
         + cnt_win.ToString() + "勝" 
         + cnt_lose.ToString() + "敗" 
         + cnt_draw.ToString() + "分け\r\n"
         + "勝率" + (cnt_win / array_match_result.Length).ToString() + "%";

return 0;

ここで見て頂くとわかる通りToString関数を使用しています。これがポイント!今回の文字列のところです。

ちなみにですが、C#の場合「;(セミコロン)」が出てくるまでが1行の命令文として扱われるので上記のような書き方ができます。

文字列について

通常変数の型が違う者同士を + で足すことはできません。
C#の場合、文字列に数値を加算すると数値が自動変換され文字列として扱われます。

しかし、それはよろしくないのです。しっかり明示的に文字列ですと示した方がいいのです。

その理由は、あとで自分または他の人が見たときにおおこれ文字列だなとわからないと不具合の原因になることがあります。

数値と文字列の比較について

それでは質問です。次の変数resには何の値が入っているでしょう?

int res = 0;
int a = 6;
int b = 15;
if (a > b)
{
    res = 1;
} else {
    res = 2;
}

これは簡単ですね。変数resの中には2が入っています。ではこの場合はどうでしょう?

int res = 0;
string a = "6";
string b = "15";
if (a > b)
{
    res = 1;
} else {
    res = 2;
}

正解は 1 です!意外でしたか?6と15だったら15の方が大きいじゃないかと思われがちですが、文字列の場合先頭から一文字ずつ比較するためまず最初に"6″と"1″を比較します。この時点で"6″の方が大きいので変数 aの方が大きくなるのです。

C#では、文字列同士を >で比較することはできませんでした。スイマセン。ですが他の言語(VBなど)ではできるものもあるので覚えておいた方がよいでしょう。

数値を文字列に変換する

数値を文字列に変換するにはToString関数を使用します。

ToString関数は、変数の値を文字列に変換するもので大抵の型であれば利用できます。

array_match_result.Length.ToString()

なのでこの場合、配列変数 array_match_result要素数(Length)を文字列に変換するという意味です。

(cnt_win / array_match_result.Length).ToString()

こんな計算結果をそのまま文字列にしちゃうなんてこともできます。

文字列連結

文字列同士を連結して一つにするには + 演算子を利用します。

cnt_win.ToString() + "勝"

勝利回数を文字列に変換して後ろに文字列”勝”をくっ付けています。

改行文字

文字列を途中で改行した時は改行文字である「\r\n」を入れます。

「\r」はキャリッジリターン、「\n」はラインフィードです。

キャリッジリターン

先頭にカーソルを戻しなさいという意味です。

ラインフィード

次の行へ行きなさいという意味です。

実行して確認してみます。

それではデバッグしてみたいと思います。実行ボタンを押してじゃんけんしてみてください。

ふむ、どうやら勝敗結果の方は問題ないみたいですが、勝率が0%ですね。これはどういうことでしょう?

整数型の割り算

文字列とは関係なくなってしまいますが、せっかくなので説明しておこうと思います。

(cnt_win / array_match_result.Length)

ここが0を返しているようです。

これは、整数型同士の割り算の結果は整数になってしまうため、小数点以下切り捨てになってしまいます。

整数を浮動小数点に変換する

簡単に言えば小数点が使えればいいのです。

整数を浮動小数点に変換するには変数の前に「(double)」または「(float)」などの小数点型を置きます。

((double)cnt_win / (double)array_match_result.Length)

実行してみると

ふふふ、出ましたよ。・・・・勝率おかしくね?・・・・%じゃなくね?
100を掛け忘れました。こういうミスも気をつけようねということであえて差し替えません!。

victory += "\r\n" 
         + array_match_result.Length.ToString() + "戦中 " 
         + cnt_win.ToString() + "勝" 
         + cnt_lose.ToString() + "敗"
         + cnt_draw.ToString() + "分け\r\n"
         + "勝率" + (100.0 * (double)cnt_win / (double)array_match_result.Length).ToString() + "%";

なおしました。さっそく実行です。

でました。またしても気が付いてしまったのですが、別にそこまでの精度はいらない小数点以下いらないというのであれば別に型変換しなくても

victory += "\r\n" 
         + array_match_result.Length.ToString() + "戦中 " 
         + cnt_win.ToString() + "勝" 
         + cnt_lose.ToString() + "敗"
         + cnt_draw.ToString() + "分け\r\n"
         + "勝率" + (100 * cnt_win / array_match_result.Length).ToString() + "%";

掛け算が先に計算されるので100掛けとけばよかったです。テヘ。

まとめ

戦績がでてゲームっぽくなってきましたね。まだまだ見た目はしょぼいですが・・・。

本当は第5回くらいで基礎講座を終われると思って始めましたが、なかなか説明することが多くて自分でもビックリです。

ですが、プログラミングをやっていく上で必要なことです。せっかくここまで来たのですから、最後までやって自分だけのオリジナルアプリを作れるようにがんばりましょう。

ちなみにオリジナルアプリって売れますよ。

次回は、クラスを扱っていこうかと思います。

【C#入門】第12回 クラスについて【じゃんけんゲームを作ろう その12】
【C#入門】第12回 クラスについて【じゃんけんゲームを作ろう その12】
こんにちは!ノムノムです。 前回は文字列と型変換の説明をしました。 今回は、ついにクラスです。はやくクラスの説…
http://nomux2.net/class/