Altseedでマインスイーパーを作ってみた

はいどーもこんにちは、ただの無職です。
Altseedの勉強がてらマインスイーパーを作ってみたので、本日はそれの紹介をしてみたいと思いますよ。
いいからさっさとゲームをDLさせろという方は以下のURLからお願いします。
https://github.com/Tsumio/TsumioMinesweeper/raw/master/bin.zip
左クックが決定(ブロックを開く)で、右クリックで旗を立てられます。
あとは普通のマインスイーパーと同じですかね。

以前にも作ったマインスイーパー

実は以前もマインスイーパーを作ったことがあるのですが、これは色々と機能が足りていませんでした。
また、プログラミングに慣れていない頃だったので、コードがごちゃごちゃとしていて保守がしにくいものとなっていました。
今回はその辺りを考慮して、なるべく保守しやすいマインスイーパーを作ってみようと考えた感じです。
また、前回のマインスイーパーの作成に一週間から二週間くらいかかっていたので、今回は三日以内での完成を目標にしました。
Altseedを使うのが初めてだったので「いけるかなー?」と不安だったのですが、何とか期限内に完成できました。
いやあよかったよかった。

あ、ちなみにですが、「マインスイーパー 作り方」とかでググって出てくるマインスイーパーは「オブジェクト指向なんて犬にでも食わせとけ」みたいな感じの作りのものが多かったです。
何でもかんでもオブジェクト指向で作ればいいというわけではないでしょうが、今回はオブジェクト指向の勉強も兼ねていたので、ちょいちょい意識していますよ。

主な機能

ごくごく普通のマインスイーパーなので、あんまり説明はいらないかなと思っています。
強いて主な機能を挙げてみるなら、こんな感じでしょうか。

・難易度選択
・旗を立てる機能
・周囲に地雷がなければ自動オープン

以前に作ったマインスイーパーは「周囲に地雷がなければ自動オープン」が不完全なものだったので、ここは正確に動作するようこだわりました。
ただ「隣接するブロック」を保持する方法が複雑なので、ここはイベントを使って作ってもよかったのかなあ……と思いました(そもそも各ブロックが隣接するブロックを保持するのが適切かどうかも怪しい)。

他には各ブロックの状態、すなわち「閉じた状態(デフォルト)」「開いた状態」「旗を立てた状態」の3つを管理しやすくするのも意識しました(ステートパターンを利用)。
こうすることによって、以前のマインスイーパーのような条件分岐&フラグ地獄にならずに済みました。
例えば「周囲の地雷の数で文字色変更」をしたい場合、周囲の地雷の数をブロックに表示させたいのは「開いた状態」だけですから、このクラスだけを見ればいいことになります。
いやあ、便利ですね!

足りなかった機能

最後の最後で急遽「そういや」と思った機能なのですが、Windows標準のマインスイーパーって、初手が地雷であることってないんですよね。
これはたぶん内部で「初手が地雷なら、地雷の箇所を再抽選」してるんだと思います。
僕もこの機能を付けようかなーと思ったのですが、機能追加にふさわしい拡張ポイントが見つかりませんでした。
もちろんこのくらいの機能なら無理やり導入することは可能です。
ですが、今回はコードの複雑さをなるべく減らすことを目標に作っていたので見送ることにしました。
もう少し設計に時間を割いたら綺麗な感じでコードを混ぜ込むことができたかもしれないのですが、いかんせん三日以内に作るという目標が焦りを生みましたかね……。

よかった点

今回の制作を通じて達成できた点をまとめておきます。

・オブジェクト指向な感じのマインスイーパーが作成できた
・前回作ったものよりも、マインスイーパーそのものの性能は上
・前回作ったものよりも、全体的に拡張や変更が容易
・コードの一部はUnityとかにも使いまわせそう

結構いい感じですね。

反省点

今回の制作で「ここはちょっとどうにかしないといけない……」と思った点もまとめておきます。

・MakeRectShapeなど重複しているコードがある(要リファクタリング)
・ゲームオーバーの処理とゲームクリアの処理を考えていなかったので、かなり無理矢理挟むことになった(設計をもっとしっかり)
・そもそも「初手が地雷なら、地雷の箇所を再抽選」は実装すら見送ってしまった(これも設計をしっかり)
・Altseedの2DObjectはタッチ処理が考慮されていないので、タッチの当たり判定を持つ継承オブジェクトを最初に作成すればよかった(単にAltseedに慣れていないためな気もしますが、これをしていなかったため処理が散らばっている箇所がある。リファクタリングも可能だけど、時間的に今回は見送り)
・機能を追加していくうちにクラスが複雑になった(責務がいくつかあったり、変更理由がいくつかあったり……)
・実際のゲーム制作を考えるなら、もう少し汎用的なクラスを作ったほうがいいかも(例えばWindow表示用のクラス。今回はメニュー部分をゴリ押しコードで書いているが、よく使いそうなので汎用的なWindowクラスは用意した方がいい気がする)

あとはゲーム性をほぼ放棄したことくらいでしょうか(あるのは難易度選択くらい)。
例えばスコア機能やランキング機能はもちろん、時間制限もありません。
この点だけで見れば、以前作ったマインスイーパーの方がいくぶんかゲーム性があると思いますw
ただ三日以内の完成を目指していたので、凝った機能は元からつけるつもりはありませんでした。なのでこれは想定通りです。
あ、単体テストも全くと言っていいほどしてませんw
Altseedの機能を色々試すことも目的の一つだったので、まあこれもいいかなって思ってます。

終わりに

GitHubでソースも公開しています。
https://github.com/Tsumio/TsumioMinesweeper
ただコードの中のコメントでも色々と書いている通り、僕自身が納得できていない部分も多々あります。
参考にするのはほどほどにで!

ほなそんな感じでまた。

おまけ画像


開発一日目はこんな感じでしたが、完成版はちょっとだけ見た目が綺麗になってると思いますw

フォローする