【42 Tokyo 】so_longのExitの考え方【番外編】
こんにちは、ウタです。
先日so_longの記事を投稿したのですが、この課題のExitの扱い方が人によって異なり、そこが42らしいと思ったので記事にしました。
課題の概要
(課題をご存知の方は本セクションは読み飛ばしてください)
本課題では「パックマン」のような2Dゲームを作ります。
プレイヤーは全てのCollectibles
を取得し、Exit
に到達するのが目標です。
ゲーム画面はこんな感じ↑
マップを描画する要素として下記の五つがあります。
-
Wall
(壁) -
Empty Space
(空白) -
Collectibles
(コイン) -
Player
(プレイヤー) -
Exit
(出口)
マップファイルの読み込み、パース、バリデーション、MinilibXによるグラフィックの描写、レンダリングなどがこの課題の行うタスクとなります。
本題
本課題の要件として、「プレイヤーは全てのCollectibles
を集めゴールをすることが目的」というものがあります。つまり、バリデーションの段階でプレイヤーがそもそもゴール出来ないマップやCollectibles
が収集不可能なマップははじかないといけないわけです。
プレイヤーがゴール出来ないマップ。これはアウト。
Collectiblesが回収不可のマップ。これもアウト。
この辺りはわかりやすいのですが、Exit
の奥にCollectibles
が存在する場合、マップを弾くべきかそうするべきではないかが人によって意見が分かれました。
Exitの奥にCollectiblesがあるパターンのマップ。これはValid or Invalid?
invalid map
として扱う
パターン1 僕はこのやり方でやりました。
簡単にいうとExit
をそもそも壁として扱うことでExit
の奥にあるCollectibles
は全て収集不可、つまり正しいマップではないと判断するパターンです。
ゴールまでのパスをチェックする時にflood fill
を使うのですが、その関数をちょっと変更するだけで実装できるのでサクッとこの辺終わらせたい方にはおすすめです。
また、ゲームとしての整合性も僕は取れていると思っていて、スーパーマリオブラザーズだとゴール後はプレイヤーの操作ができず、仮にコインがあったとしても取ることが出来ない仕様になっていた記憶です。(タイトルによって異なりますが、、、)
なので、後ろ指刺されるほどの仕様ではないかと思っています。
valid map
として扱う
パターン2 こちらのパターンで実装している方もちらほらいらっしゃいました。
考え方としてはExit
を壁として扱うのではなく、空白ブロックとして扱い、全てのCollectibles
を回収した上でExit
を踏むとゴール出来るというものです。
こちらの方が分岐が増えて難しくなる印象があります。
人伝に聞いただけなのですが、パターン2の仕様にして、Exit
がデフォルトで門が閉じている画像を採用し、Collectibles
全てを回収後にExit
を門が開いている画像に差し替えるという凝った作り方をしていた人もいるようです。ここまで考えられると筋が通っていて、プレイヤーとしてもワクワクしますよね。
重要な点
本題において大事なのは自分で定義しているか否かだと僕は思っています。
課題のpdfにはパターン1で実装しろともパターン2で実装しろとも記述されていないです。
なので、この宙ぶらりんになっている細かい仕様を自分で詰めて理屈を通して実装することが大事です。
また、そういった部分が42らしいと思っています。ほとんどの課題でこのような決まりきっていない仕様の部分があり、そこを詰めるために周りの人に聞いたり自分で調べたりといったことを求められます。
このプロセスを通して、ただコードを書けるだけのエンジニアではなく、曖昧な要件に対しても自分なりの解釈を持ち、それを論理的に説明できる人材へと成長していけるのだと思います。so_longのような一見シンプルな課題でも、こうした思考力を鍛える要素が散りばめられているところに、42の教育哲学を感じますね。
Discussion