【ゲーム開発のためのC#入門講座・基礎拡張編】論理否定演算子を使ってみよう【#8】

2.0_C#基礎拡張編

論理否定演算子って?

以前、論理演算子について学習しましたね。

おさらいも含めて再度確認してみましょう。

演算子命令使用例結果
&&AかつBかどうか判定(両方trueか)1 == 1 && 1 == 2false
||AまたはBかどうか判定(どちらかtrueか)1 == 1 || 1 == 2true
!判定結果を反転!(1 == 1)false

このうち、「&&」演算子と「||」演算子は「and」と「or」の意味なのでわかりやすいですね。一方、「!」演算子はいまいち使い方がぴんとこないと思います。

この「!」こそが論理否定演算子です。

ようはtrueをfalseに、falseをtrueに反転させる演算子なのですが、それって何の意味があるのってなりますよね。

ただ、これは結構便利な演算子なので、ここで具体的な使い方を交えながら理解を進めていきましょう。

例えばプレイヤーに名前入力を求めるなら

例えばオンラインランキングを実装したいとしましょう。その場合、誰の記録かわかりやすくするためにプレイヤーに名前入力を求めますよね。

皆が皆、想定通りに名前を入力してくれるなら何も問題はないです。

ただ、実際には下記のようなケースが考えられます。

  • 間違って未入力のまま登録ボタンを押してしまった
  • 悪戯でスペース入力だけして登録ボタンを押してみた

名前が未入力(またはスペース入力のせいで未入力のように見える)のまま登録されては困りますよね。なのでこういう場合、登録可能かどうか事前にチェックします。

C#にはMicrosoftが作ってくれた、指定の文字列が未入力(スペースだけ入力含む)かどうかチェックする関数があります。今回のケースにドストライクな関数ですね。ありがとう、Microsoft。

// 戻り値はbool型です
string.IsNullOrWhiteSpace("判定したい文字列");

という訳で早速それを使って実装したいと思います。

public class Hello{
    public static void Main(){
        string inputName = "   ";
        if (string.IsNullOrWhiteSpace(inputName))
        {
            System.Console.WriteLine("その名前は登録できないよ!");
        }
        else
        {
            System.Console.WriteLine("名前を登録するよ!");
        }
    }
}
出力エリア

その名前は登録できないよ!

きちんと実装することができましたね。

この実装でも問題ないといえば問題ないのですが、どっちかっていうと「登録可能な名前だったら名前を登録する」がメインの処理なんですよね。変な入力だったら登録させないというのは念のための処理なので。

なのでifとelseの位置関係を入れ替えて、条件を「もしも名前が未入力(スペース入力含む)だったら」から「もしも名前が未入力(スペース入力含む)じゃなかったら」に変更したいです。

それじゃあ比較演算子で、条件を少し変えてみましょう。

比較演算子を使った実装例

比較演算子で「もしも名前が未入力(スペース入力含む)じゃなかったら」という判定に書き換えると、下記のようになります。

public class Hello{
    public static void Main(){
        string inputName = "   ";
        if (string.IsNullOrWhiteSpace(inputName) == false)
        {
            System.Console.WriteLine("名前を登録するよ!");
        }
        else
        {
            System.Console.WriteLine("その名前は登録できないよ!");
        }
    }
}
出力エリア

その名前は登録できないよ!

きちんと実装できました。

この実装でも問題ないといえば問題ないのですが(またか)、せっかく関数名が英文のように読めるように作られていたのに、「== false」がついたことでちょっと読み辛くなってしまいましたね。

// ↓これはそのまま英文として読むことができるが、
if (string.IsNullOrWhiteSpace(inputName))
    
// ↓これは英文としてだけでは読めない
if (string.IsNullOrWhiteSpace(inputName) == false)

「~~かどうか」を判定するメソッドでは「IsXXX」、「~~が可能かどうか」を判定するメソッドでは「CanXXX」という風に、プログラミングの世界ではなるべく英文として読みやすいように関数名も考えて作られていることが多いんですね。なので、上記の実装方法だとせっかくの工夫がちょっと台無しになってしまいます。

何とか英文のまま「もしも名前が未入力(スペース入力含む)じゃなかったら」を判定できないものかな、という時に出番となるのが論理否定演算子です。

論理否定演算子を使った実装例

論理否定演算子は判定結果を反転させます。

これはすなわち、「~~だったら(true)」を「~~じゃなかったら(false)」に、「~~じゃなかったら(false)」を「~~だったら(true)」に変換する演算子ということです。

これを使えば比較演算子を使わなくても実装することができます。

試してみましょう。

public class Hello{
    public static void Main(){
        string inputName = "   ";
        if (!string.IsNullOrWhiteSpace(inputName))
        {
            System.Console.WriteLine("名前を登録するよ!");
        }
        else
        {
            System.Console.WriteLine("その名前は登録できないよ!");
        }
    }
}
出力エリア

その名前は登録できないよ!

きちんと実装することができました!

理屈はわかったけど……part1

理屈はわかったけど、果たして「!」をつけたものが英文として読めるかっていうと正直微妙ですよね。

ただ、これはC#の論理否定演算子が「!」という記号として表されていることが原因だったりします。例えばVB.NETの場合、この論理否定演算子は「!」ではなく「Not」という表記になります。

' VB.NET版
if Not string.IsNullOrWhiteSpace(inputName) Then
    
End If

これなら英文として読めるように、という意図も理解できますよね。

基礎学習編の第1回でも少し触れましたが、C#はなるべく簡略的に表せるようにという設計思想で作られています。その分、VB.NETより記号チックなんですね。なので論理否定演算子も「!」で表すことになっています。

ただ意味合いは全く同じです。

つまりこの記号「!」は「Not」という意味なんです。

「Not」だから、「~~だったら(true)」を「~~じゃなかったら(false)」に、「~~じゃなかったら(false)」を「~~だったら(true)」に変換してくれる、という訳ですね。

// 意味合い的には「not string.IsNullOrWhiteSpace(inputName)」ということ
if (!string.IsNullOrWhiteSpace(inputName))
{
    
}

理屈はわかったけど……part2

理屈はわかったけど、どうしても使わなくちゃだめ? という疑問も出るかと思います。

結論からいうと「別に使わなくてもいい」です。

先程の例で散々「この実装でも問題ないといえば問題ない」と説明してきたように、条件を判定する順番だったり英文として読めることを気にしなければ、使わなくても実装はできます。

特にC#の場合、論理否定演算子は「!」という記号ひとつなので、慣れないと結構見落としやすいんですよね。

// こうやって並ぶと結構神経使わないと気づきにくいですよね
if (!string.IsNullOrWhiteSpace(inputName))
if (string.IsNullOrWhiteSpace(inputName))
if (!string.IsNullOrWhiteSpace(inputName))
if (string.IsNullOrWhiteSpace(inputName))
if (string.IsNullOrWhiteSpace(inputName))

ただ、先程お伝えした通りきちんと使うことのメリットはあります。比較演算子を使うよりも簡略的に表せるというのもあり、世に多く出回っているコードでも使っていることは結構多いです。

なので例え使わなかったとしても、他の人が書いたコードの意味は理解できるようにということで、今回紹介させていただきました。

Unityでの活躍ポイント

Unityにもたくさんの状態を表す変数が存在します。

例えばゲームオブジェクト(キャラクターやイラストなど)がアクティブ(有効かどうか)を表すものとして、下記のような変数があります。

gameObject.activeSelf;

非アクティブにするとゲーム画面への反映等が行われなくなります。反対にアクティブにするとゲーム画面への反映等が行われるようになります。UIの表示/非表示の切り替えなんかはこのアクティブかどうかの切り替えで実現することが多いです。

このゲームオブジェクトに対して「対象が非アクティブだったら」を判定したいという時には、論理否定演算子を使って実装したりします。

if (!gameObject.activeSelf)
{
    gameObject.SetActive(true);
}

ただ前述の通り絶対使わなきゃいけないものでもないので、ご利用はお好みで!

実践演習

それでは実際に論理否定演算子を使ってみましょう。

仕様

下記の条件判定に論理否定演算子を付与してください。

テンプレート
public class Hello{
    public static void Main(){
        bool needsFree = true;
        if (needsFree)
        {
            DisplayNotFreeTools();
        }
        else
        {
            DisplayFreeTools();
        }
        System.Console.WriteLine("色んなゲーム開発ツールがあるね!");
    }
    
    public static void DisplayNotFreeTools()
    {
        System.Console.WriteLine("SRPG Studio");
        System.Console.WriteLine("スマイルゲームビルダー");
        System.Console.WriteLine("RPGツクール");
    }

    public static void DisplayFreeTools()
    {
        System.Console.WriteLine("Unity");
        System.Console.WriteLine("Unreal Engine");
        System.Console.WriteLine("Cocos2d-x");
    }
}

答え合わせ

public class Hello{
    public static void Main(){
        bool needsFree= true;
        if (!needsFree)
        {
            DisplayNotFreeTools();
        }
        else
        {
            DisplayFreeTools();
        }
        System.Console.WriteLine("色んなゲーム開発ツールがあるね!");
    }
    
    public static void DisplayNotFreeTools()
    {
        System.Console.WriteLine("SRPG Studio");
        System.Console.WriteLine("スマイルゲームビルダー");
        System.Console.WriteLine("RPGツクール");
    }

    public static void DisplayFreeTools()
    {
        System.Console.WriteLine("Unity");
        System.Console.WriteLine("Unreal Engine");
        System.Console.WriteLine("Cocos2d-x");
    }
}
出力エリア

Unity
Unreal Engine
Cocos2d-x
色んなゲーム開発ツールがあるね!

まとめ

  • 論理否定演算子は判定結果を反転させる演算子
  • すなわち「~~だったら(true)」を「~~じゃなかったら(false)」に、「~~じゃなかったら(false)」を「~~だったら(true)」に変換する演算子
  • その正体は「Not」だけど、C#は簡略的な記述を好むので「!」で表す

それでは、今回もお疲れ様でした!

また次の記事でお会いしましょう!

Posted by yuumekou