🐕

【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?

パターン1 invalid mapとして扱う

僕はこのやり方でやりました。
簡単にいうとExitをそもそも壁として扱うことでExitの奥にあるCollectiblesは全て収集不可、つまり正しいマップではないと判断するパターンです。

ゴールまでのパスをチェックする時にflood fillを使うのですが、その関数をちょっと変更するだけで実装できるのでサクッとこの辺終わらせたい方にはおすすめです。

また、ゲームとしての整合性も僕は取れていると思っていて、スーパーマリオブラザーズだとゴール後はプレイヤーの操作ができず、仮にコインがあったとしても取ることが出来ない仕様になっていた記憶です。(タイトルによって異なりますが、、、)
なので、後ろ指刺されるほどの仕様ではないかと思っています。

パターン2 valid mapとして扱う

こちらのパターンで実装している方もちらほらいらっしゃいました。
考え方としてはExitを壁として扱うのではなく、空白ブロックとして扱い、全てのCollectiblesを回収した上でExitを踏むとゴール出来るというものです。
こちらの方が分岐が増えて難しくなる印象があります。

人伝に聞いただけなのですが、パターン2の仕様にして、Exitがデフォルトで門が閉じている画像を採用し、Collectibles全てを回収後にExitを門が開いている画像に差し替えるという凝った作り方をしていた人もいるようです。ここまで考えられると筋が通っていて、プレイヤーとしてもワクワクしますよね。

重要な点

本題において大事なのは自分で定義しているか否かだと僕は思っています。
課題のpdfにはパターン1で実装しろともパターン2で実装しろとも記述されていないです。
なので、この宙ぶらりんになっている細かい仕様を自分で詰めて理屈を通して実装することが大事です。

また、そういった部分が42らしいと思っています。ほとんどの課題でこのような決まりきっていない仕様の部分があり、そこを詰めるために周りの人に聞いたり自分で調べたりといったことを求められます。

このプロセスを通して、ただコードを書けるだけのエンジニアではなく、曖昧な要件に対しても自分なりの解釈を持ち、それを論理的に説明できる人材へと成長していけるのだと思います。so_longのような一見シンプルな課題でも、こうした思考力を鍛える要素が散りばめられているところに、42の教育哲学を感じますね。

Discussion