MARSで人生を棒に振る気はない私ですが(笑)、曲がりなりにもプロのシステムエンジニアとして御飯を食べている身としては、この桝田省治の挑戦、受けずばなるまいと考えたので、答案を作成してみました。
MARSの要求水準に達しているかどうかは不明ですが、御査読下さい。
ちなみにシナリオ部門とグラフィック部門はパスします。そっち方面の才能に恵まれていないという自覚があるのが、私が10年前に某光栄の内定を蹴ってゲーム業界への就職を止めた理由でもあるので(笑)。
高さ20センチ、底面の直径15センチ程度の円筒上の空のゴミ箱を思い浮かべてください。次にマッチ棒を8本、そのゴミ箱に投げ込んだとします。
ゴミ箱の底に散らばったマッチ棒の並び具合をゲーム内での使用に耐えるレベルの数式、あるいは数表で表せ。
要求仕様を書くうえでは、顧客が出す曖昧な要望を厳密な形で定義することが必要である。また問題領域の大きさと難易度を勘案し、切り捨てる部分とそうでない部分を分けることが重要であると言える。
上記課題では、まずは次の点について確認を求める必要があろう。
通常はこういった点について顧客とインタビューを重ねて「それをやると面倒です。本当に必要な機能ですか?」とかいった折衝を行ったうえでこれらを確定するのであるが、答案という本件の性質上、今回は次の通りこちらで勝手に設定する。
以上の条件から基礎となる式を設定する。
マッチ棒の線分を表す式の基本となる記号は、次の図のものを用いる。
明らかに極座標を用いるのが簡単であろう。
定数:
円の半径をRとする。
マッチ棒の長さを2Lとする(Lでも良いが式が煩雑になるのでこうする)。
なお設定条件から(L<R)が成立しているものとする。
変数:
円の中心Oと、マッチ棒の二等分点Xの距離をrとする。
OXと、適当な基準線との交角をθとする。
OXと、マッチ棒との交角をφとする。
こうすればマッチ棒の方程式はr,θ,φの3つのパラメータで表現し得ることが分かる。
次は各パラメータの境界条件を求めねばならない。
θ:
0≦θ<2π(ラジアン)の任意の値を取る。乱数で毎回設定するものとする。
φ:
0≦φ<π(ラジアン)の任意の値を取る。乱数で毎回設定するものとする。
r:
乱数で毎回設定するものとし、0より大きい値を取るのだが、問題はこの乱数の最大値をいくつにするかということに尽きる。これが設問の本質であると言って良いだろう(式自体は単なるベクトル方程式で書くだけのことである)。
従って大事なので、以下きちんと述べよう。
まず(0 ≦ r < R)と書いてしまったらこれは明らかに落第(笑)。
これではマッチ棒が円からとび出してしまう。最低、プロとしてこれだけは避けねばならない所である。
次は(0 ≦ r < R-L)である。これは「とび出す」バグは回避できるという点で、実用上「とりあえず動く」プログラムを書くことができる。その意味では最低の合格ラインと言えるだろう。ただしいかにも手抜きであり、シミュレートには遠い。
少し考えれば分かるように、これは「円の外周に決して当たらない」ための条件でしかなく、実際にはこれよりも大きいrを容易に取り得るからだ。
明らかにrの最大値はφの関数にならねばならないことが分かる。
あるφに対するrの最大値は、マッチが円周に内接した時であると言えることから、
余弦定理により
が成立するので、これをrについての二次方程式
として解けば、
となる。
いまL<Rが成立するので、(R/L)^2 - sin^2φは常に正となるので、平方根は実数で開ける(正の値を取る)ことが分かる。
条件r>0より負の解が除外されるので、結局
となる。
rを乱数で求める際には、まずφの値を乱数で確定したうえで、そのφの値を用いてrを0と上記の式の間に収まるように計算を行えば良い。
面倒臭くなったのでこれを含めて真面目に内接の計算をするのは省略(笑)。
まあゲームの画面ということであれば、上記のrの最大値から「マッチの太さの半分」を
差し引いた値にすれば、まずは実用に耐えると思える。
マッチのサイズにもよるが通常それらはLやRよりも非常に小さく、またこの簡略化による弊害である「放り投げた際にちょうど円に内接することが起こらない」というのを気にする人も、あまり出るとも思えませんので。
#もちろんCADとかならそれを考慮した計算を正確にやる必要もありますが。
面倒臭くなったので略(笑)。
定数L,Rおよびパラメータθ,φ,rの値はすべて上記より確定できるので、
この5つの引数を取る線分のベクトル方程式の関数を書いて渡すだけである。
極座標系とXY座標系(ゲームなら最終的にはこちらか)を取るかにより式は異なるが、いずれにせよ仕様は確定しており、これは誰が書いても結果は似たようなものなので、プログラマに任せてしまえば良いと言える。
上記数式の関数ができていれば、あとはそれを8回走らせて結果を出力するだけである。
数字で出しても良いし、円と一緒にプロットするのも良いだろう。
以上。
SEO | [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送 | ||