スッキリわかるC言語入門

スッキリCの「どっかで見たようなパズルRPG」

エイ! ファイヤー! アイスストーム!

どうも、子供の頃は学校から帰ると、バーチャファイターで実弟(某大会では日本チャンプ)に家庭内暴力を受けていた、著者の中山です1

弟は「ぷよぷよ」も死ぬほどうまくて、カエル積みしかできない自分としては、みじんにも勝てる気がしませんでした。
それ以来パズルゲームにはあまり良い思い出がないのですが、「スッキリわかるC言語入門」の実践演習問題としてパズルRPGの開発を入れさせていただいています。

クソゲーのくせにちょっと難しい演習なので、攻略法と舞台裏を今回はご紹介します。

宝石を消してモンスターと戦うパズルRPG

スッキリわかるC言語入門の第12章は、1章まるごとをかけて、「宝石を消してモンスターが攻撃するパズルRPG」を製作する課題になっています。
Puzzle & Monsters、略して「パズモン」といいます2

画面上部に「相手モンスター」「自分モンスター」、そして下部には「宝石」が並んでいるという、どっかで見たことがある画面を、「ターミナル画面の文字だけ」でノスタルジックに表現。

わかる人にはわかる、PC8801 mkIIごろの、なんつーか「あの頃の俺たち、何もなかったけど、胸の中は夢でいっぱいだったよな」的な時代の香りさえ感じるクソゲーを作る課題に仕上がっています。

とみーさんが作ってくれたプレイ動画もはっておきますね。

パズモン開発の演習課題とは

実際には、トップダウンアプローチで次の9つのミニ課題をときながら、完成をさせていきます。

[1] ゲーム全体の流れの開発
[2] 敵モンスター関連の処理の実装
[3] 味方パーティ関連の処理の実装
[4] バトルの基本的な流れの実装
[5] バトルフィールドの実装
[6] ユーザー入力コマンドの実装
[7] 宝石消滅判定の実装
[8] 攻撃処理の実装
[9] コンボ処理の実装

模範解答だと500行程度なんですが、初学者の方にはなかなかボリュームがあります。
特に、クソゲーのくせに「属性システム」(火・水・風・土によるダメージ補正)があったり、ぷよぷよみたいな連鎖の発生とダメージの増幅など、わりと真面目に仕様が定められていたりするので、作っていくのはそこそこ大変なんです。

ちょっと言い過ぎかも知れませんが、これを作れたら、「初心者は卒業」といってもいいんじゃないかなと思います3

逆にC言語を業務に使っている方とか、教えている方は、腕試しとして「ノーヒントでのタイムアタック」をしてみていただくのにピッタリな課題だと思います。

初見で2時間以内で完全動作までできれば、C言語に概ね慣れている(ポインタとかアドレス含め、血肉になっている)方という印象でしょうか。

(バリバリ現場でやっている方は1時間かからないかもしれません。YouTubeへのライブコーディング動画、お待ちしております/笑)

パズモン開発の攻略法

そんなパズモンですが、実は初学者の方には相当難しく感じる課題として設計されています。特に最初の山場は課題[2]です。

ここではC言語の世界ではなかばイディオムになっている「可変長配列を実現するために、要素の先頭アドレスと要素数を構造体で扱う」ということを深く実体験していただくための課題です。

このイディオム、経験者や既にわかっている人からすると「あたりまえじゃん」という話なんですが、初学者の人にとっては最も飲み込みづらい用法の1つです。そして経験者の方が「●●という理由だから、こういうイディオムを使うんだよ」といっても、学び手は頭ではわかっても脊髄でまではわかりづらいという特性があり、いわゆる「教えにくい事項」なんですよね。

この課題[2]は、多少のヒントがある状況でいろいろ模索して(例えば固定長の配列を宣言しちゃったりして「これじゃだめだー」と思っていただいたり)、そのイディオムに自ら辿り着いていただくことで、納得していただく構造になっています。

ですから、ちょっと表現が難しいのですが、この課題[2]の攻略法は、

(1) 時間を定めて、まずは自分でいろいろやってみること
(2) 自分が思いつく手をいろいろ試してダメだったら(煮詰まったら)、遠慮せずにヒントコードや正解を見ること

が攻略法になります。

実は同様の傾向は、課題[6]と課題[8]にも見られます。「しっかり考えてから、堂々と答えを見る」ということが勝利のカギです。

C言語の「先生」であれば、思わずにんまりするポイント

実はこの課題、取り組む学び手はわりと大変なのですが(しかもできあがったものはクソゲー)、「先生」に受けがいいんです。

某知り合いの指導者の方は、ざざざっと5分ほど眺めただけなのに、

へぇ〜。アドレスや配列をしっかり使わせ定着させつつ、
王道のswapとか末尾再帰も盛り込んでるわけね。
単に中山くんがパズドラ好きなだけかと思ってたー、はははー。

とか設計意図をズバリ見破るもんだから、「この人キモっ、こわっ!」と思った、ひぐらしなく夏の夕暮れでございました。

なお、熟練者の方はご想像のとおり末尾再帰を使うのは「連鎖(コンボ)」の実装です。
宝石を3つ並べて消えてたあと、右から宝石が振ってきたり、空白部分に沸いてきたコンボがおきます。

もちろん、私の弟みたいな人間がプレイして再帰によるスタック溢れが怖いという人のために、ループによる別解も模範解答例につけてあります。

C言語学習で学び手も指導者も悩むポイント

執筆時、いろんなエンジニアや先生の話を聞いてわりとC言語の先生に共通していた声がありました。

まずは、

「 C言語スキルには、入門時に1つ大きな「壁」があるよね 」

という声。うまく表現できないのですが、主にポインタやアドレスや文字列を「頭で考えず、脊髄で、自由に使える」か否かという壁です。
入門時はとても大変なのだけれども、一度「悟り」をひらくと、ぱぁぁーーーっといろんなことが頭の中で繋がって、一気に自由に操れるようになる、あの感覚。
「そうそう! それあるよね!」っていう経験者、すごく多いです4

そして、もう一つの声は、

「その壁を越えさせるためには、単純な小問ではだめだが、適切な複合問題がない(作るの大変)」

っていう声でした。

いわゆる一問一答とか、章末問題のような小さなレベルのものではダメなので、大きめの実践課題を探されていたりするんですが、C言語黎明期とかに作られた伝統あふれる

ハノイの塔

とかだったりすると、学生さんとか目が死んじゃうみたいで...。

大昔の私は、「ハノイの塔」とか「ジャックポット」とか「HIGH and LOW」とか作る課題って、なんかすごくワクワクしたんですけど、「毎日スマホでグラフィカルなゲームをやっている人」にはちょっとツラいみたいです。

そんなこんなで、「スッキリわかるC言語入門」では(スマホゲームでおなじみの)パズルRPGが題材となっています。
もし、学び手が楽しく取り組みつつ「壁」を超えられることを狙う課題をお探しの先生・指導者の方がいらしたら、ぜひお試しいただけましたら幸いです。

ちなみに、中山は未だにパズドラをプレイしたことがありません...。

  1. 普段チャンプとスパーリングをしているわけなので、たまに友達とゲームするとやたら勝てたり「つえー」と言われる不思議な体験をしました
  2. ・・・あくまで、パズモンです!
  3. Javaとかと違って、Cの世界はコンパイラと最適化を競って勝ったり、マシンコードを直接読んじゃうような仙人もいるので、「まだまだひよっこ」とか言われるかもしませんが、まぁそこは気にしなくて良いでしょう
  4. 特に独学とかで地獄をみたような人は

-スッキリわかるC言語入門
-,