見出し画像

プログラミングはなぜ「難しい」のか あるいはコンピュータは思考していないという話

※プログラミングの知識がまったくない方はまずこちら:知識ゼロから始める具体的なプログラミング入門

はじめに

プログラミング言語のマニュアルを読んで「変数に値を代入」「for文でループできる」といったことを学び、サンプルプログラムを動かしてみたりいじってみたりはできる。しかしそこで「ではシューティングゲームを作ってみましょう」など具体的な目的を与えられるとピタリと手が止まってしまう。そんな方は多いと思います。
この記事ではなぜそんな現象が起こるのか解説していきます。

コンピュータ≠脳

そもそも「プログラム」とは何でしょうか。「プログラム」という単語は「運動会のプログラム」と使われたりもするように、順序、手順を意味します。これはコンピュータの「プログラム」でも同じです。コンピュータは人間によって書かれた「変数Xに10を代入しろ」「変数Xと変数Yの大きさを比較しYの方が大きければこの命令を実行しろ」といった「手順」を淡々と実行しているだけです。だからプログラムを書きたければ単にコンピュータが実行すべき手順を淡々と書けばいいだけです。問題はその「手順」を人間は無意識にやっていることです。
どういうことか? 例えばあなたが友達と一緒に食事をしていて醤油が必要になったとき醤油差しが少し遠くにあったとします。このとき「醤油取って」と言えば近くの人が醤油を取ってきてくれるでしょう。このとき間違っても「醤油取って。単に持つだけじゃなくこっちに運んでって意味だよ。運ぶ途中で傾けてこぼしちゃダメだよ。人や皿や食べ物に当たらないようにしないとダメだよ」などと言う必要はありません。しかしそれを全部書き出さなければいけないのがプログラミングなんです

よく脳をコンピュータに例えたり逆にコンピュータを脳に例えたりしますがこの2つは情報の処理方法が全く異なります。例えばコンピュータは人間なら長時間かかる計算を一瞬でやってのけます。一方で「顔を認識する」「声で頼み事をする」といった人間なら子供でもできることがコンピュータは長い間できませんでした。コンピュータというのは(電子部品までさかのぼると)「A端子とB端子両方に電流が流れたときだけ電流を出力する」「A端子とB端子どちらか一方に電流が流れたときだけ電流を出力する」といった電子回路の集合体で、この電流のオンオフと二進法(0と1だけで数値を表現)を対応させることで数値計算(だけ)は高速にできるようにしただけで、それ以外はからっきしなのです。

コンピュータを相手にするのはちょうど発達障害の子供を相手にするようなものです。電話で「お母さんいる?」と聞くと「いる」と答える。しばしの沈黙の後「お母さんと変わってくれる?」と聞くとようやく変わってくれる。コンピュータはこの発達障害の子供のようなもので「相手の質問の意図は何か?」「相手は何を求めているか?」を一切考えてくれません。
人間なら「醤油取って」の例からもわかるように全く無意識の内に相手の意図や注意しなければいけないことを考えてくれます。例えば会社で「コピー10枚取って」と指示したら当然コピー10枚取るだけでなくそれ(と原本)を持って帰って来て何なら会議のメンバーに配るところまでやってくれるでしょう。電話で「○○さんいらっしゃいますか?」と聞かれたら当然その人に用があるのだということを推測し、電話を変わったり後でこちらからかけ直すように伝えてくれるでしょう。
人間は常にこのような思考(推測)を全く無意識の内に実行しており当然相手もそのように思考してくれているだろうと考えて会話や命令(お願い)をしています。だからそれらを全くしてくれないコンピュータを相手にすると何をすればいいかわからず呆然としてしまうのです。
ちなみにビル・ゲイツやスティーブ・ジョブズなど著名なエンジニアが発達障害という話があります。発達障害は「空気や行間が読めない」「ジョークや皮肉を理解できず言葉をそのままの意味で受け取る」という特徴がありますが、行間を読まず言われたことだけをそのまま実行するのはコンピュータと同じです。発達障害の人がプログラマに向いてるのは普通の人よりも考え方がコンピュータに近いからかもしれません。
なお「コンピュータ(AI)は人間と同じようには考えない」というわかりやすい例が以下のページに載っています。

音声認識機能がチェスをできず、将棋AIが車を運転できないように、今のAIにはその製作者が意図しなかった動作はできません。人とは「考える方法」が違うので、あらかじめ準備できていない状況には対処できないのです。

画像
現在のAI 「東京大学まで連れて行って!」と車に話しかければ自動運転で目的地まで行けるようになるでしょう(上)。しかし、乗客が突然苦しみ出して失神しても、車が目的地を変更して病院に急行することは(事前にそう設計されていなければ)ありません(下)。現在のAIは、人とは「考える方法」が異なるため、あらかじめ準備されていない状況には対処できません。
© 2017 東京大学

人間なら「体調が悪いなら病院に連れて行かなければ」と考えなくてもわかりますが、コンピュータは「○○に連れて行って」と言われた時「○○」に行くようにプログラミングすることはできても、「人間がある言葉を言ったらそれは体調が悪いという意味である」「その場合は病院に連れて行かなければ」という常識がありません。そのためいくら乗客が苦しみの言葉を入力しても「病院に連れて行こう」と「判断」することはそもそも不可能なのです。
なお以下の投稿で『深層のラプタ』を元に「AIと人間の違い」を説明しています。

すべてを明文化する

プログラムは「思ったように」は動かない。「書いたとおりに」動く。という言葉がありますが、上記のようにコンピュータはこちらの意図を汲んではくれないので「こういう動作をして欲しい」と無意識に考えていることをすべて書き出さなければいけません。最初に例としてあげた(縦スクロール)シューティングゲームなら以下のようになります。

  • まず画像を描画できる必要がある

  • 自機と敵機を配置する

  • 「←」「→」「↑」 「↓」キーを押した時自機をそちらの方向に移動させる

    • ただし画面外に出てしまう場合は移動しない

  • 「z」キーを押すと弾を生成する。位置は自機の真ん中の前方。また、弾を「弾リスト」に加える。

  • 「弾リスト」のすべての弾に対して以下の処理を実行

    • 弾は時間経過に従い上に移動していき、敵機と重なると敵機を破壊し、また自身は消滅し、弾リストから除かれる。画面外に出た弾も除かれる

    • 弾が当たった敵機は爆発の画像に切り替えた後、消滅する。

  • 弾は連続して発射できるようにするとビームのようになってしまうので一定間隔で発射するようにする

  • 自機と敵機が重なったときは自機の画像を爆発の画像に切り替えゲームオーバーとする

具体的なプログラムは以下のような形になります(カンタンのため敵機は一機としています)。

ウインドウサイズは横100200とする
5x5サイズのPictureBoxC#の場合。言語によって異なる)を生成。自機の画像を貼り付ける
5x5サイズのPictureBoxを生成。敵機の画像を貼り付ける
自機を(x=47, y=194)座標に配置
敵機を(X=47, y=0)座標に配置

「弾リスト」を作成
count = 0
「前回発射時count」に整数の最小値をセット

無限ループ:
    count = count + 1

   「←」キーが押されている時
        自機のx座標が1以上なら、自機のx座標を-1
   「→」キーが押されている時
        自機のx座標が94以下なら、自機のx座標を+1
   「↑」キーが押されている時
        自機のy座標が6以上なら、自機のy座標を-1
   「↓」キーが押されている時
        自機のy座標が194以下なら、自機のy座標を+1
    
    敵機のy座標を+1
    自機と敵機を重なり判定:
        重なっていたなら自機の画像を爆発に置き換えて、「GAME OVER」と表示。ループを抜ける。

    「z」キーが押されている時:
        countマイナス「前回発射時count」が4以上なら://弾を一定間隔で発射するため
            1x1サイズの弾PictureBoxを生成。黄色で塗りつぶす。
            位置は(自機のx座標+2, 自機のy座標-1)。そして「弾リスト」に追加。
            「前回発射時count」にcountを代入
     
    「弾リスト」をループ:
        弾のy座標を-1
        弾のy座標がマイナスなら弾を破壊、弾リストから除外する。
        弾と敵機を重なり判定:
            重なっていたら:
                弾を破壊。敵機は爆発画像に置き換えた後、0.1秒後消滅させる。
                弾を弾リストから除外する。
                「GAME CLEAR」と表示し無限ループを抜ける。

    0.05秒、待機

※重なり判定
    少し複雑なので https://qiita.com/hp0me/items/57f901e9b0babe1a320e を参照してください

このように「何をすればいいか」を明文化できたなら後はそれをプログラミング言語に置き換えるだけです。

以上を読んで「やっぱりプログラミングは難しい」と思う方もいるかも知れませんが、「コンピュータはこちらの意図を察してくれない」ということを意識し、試行錯誤を繰り返せば(多分)誰でもプログラミングできるようになると思います。

補足:プログラミングを食わず嫌いしてる方へ

まず最初に言っておくとプログラミングをする上で理系である必要はありません。確かに高速化や独自の人工知能を作ったりする場合はコンピュータ科学や数学の知識が必要となりますが、普通のプログラム(例えばToDoアプリ)を書くだけなら特別な知識はいりません。また、「英語がわからないとダメなんでしょ?」と思ってる方もいるかも知れませんが、ifやforなど少数の単語の機能さえ覚えれば英語の知識もいりません。有名な言語には日本語の解説もついてますし、何なら日本語プログラミング言語というのもあります。

※詳しいプログラミングの記事をZennに上げてます。

いいなと思ったら応援しよう!

Lamron サポートいただけると記事を書く時間や質問に回答できる時間が増えます。

コメント

コメントするには、 ログイン または 会員登録 をお願いします。
買うたび 抽選 ※条件・上限あり \note クリエイター感謝祭ポイントバックキャンペーン/最大全額もどってくる! 12.1 月〜1.14 水 まで
プログラミングはなぜ「難しい」のか あるいはコンピュータは思考していないという話|Lamron
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1