pochitto’s blog

詩、雑感などを記しています。

はじめてゲームプログラミングで「上海ソリティア」を制作したときのメモ

上海ソリティアのゲーム画面

はじめに

先般、はじめてゲームプログラミング(以下「はじプロ」)向けに「上海ソリティア」というゲームを公開しました。

有名なゲーム、「上海」の移植版です。

おそらくはじプロでは前例のない、大量のオブジェクトを区別するタイプのゲームとなりました。

この「上海ソリティア」を制作するに至った経緯、制作の過程、工夫した点や苦労した点などを書き残したいと思います。

 

制作の経緯

ふと「そういえば、はじプロで上海って作られてないな」と考えたのがそもそものきっかけでした。

上海のような大量のオブジェクトを区別しなければならないパズルゲームは、はじプロが苦手とするジャンルです。

せっかくだから制作に挑戦してみよう、という所からスタートしました。

 

「上海」とは

その前に、「上海」とは何かについてWikipediaの説明を引用しておきます。

上海』(シャンハイ)は、1986年7月アメリカ合衆国アクティビジョンから発売されたMacintoshパズルゲーム。 

最初は、季節牌4枚(春、夏、秋、冬)、花牌4枚(梅、蘭、菊、竹)を含む合計144枚の麻雀牌が積み上げられた状態が表示される。

その牌の山の中から、同じ牌を2枚選ぶと、その牌を取り除くことができる(季節牌と花牌は、季節牌同士、花牌同士であれば良い)。ただし、左右両方に隣接する牌がある場合や、上に牌が乗っている場合はその牌を選ぶことはできない。

144枚全てを取り除くことができればゲームクリア、牌が残っているにも関わらず、取り除くことのできる牌がなくなったら(手詰まりで)ゲームオーバーとなる。

まあ一種のパズルゲームですね。

1990年代初頭にかなり人気がありました。

当時私も手持ちのPC-8801MHでN88-BASICによる移植を試みましたが、当時の技術力では太刀打ちできず、諦めた記憶があります。

 

技術的な制約

時が経って2022年、はじプロにすっかりハマってしまった私はこの上海をはじプロに移植する事を決意しました。

さっそくサンプル的なものを作ってみると、まあまあ良い感じです。

ですがちゃんとした上海を作るとなると、技術的な課題が山ほどありました。

それをどうやって一つ一つ克服していったかについて書いていきます。

 

512ノードンの壁

はじプロには「512ノードンの壁」があります。

ノードン(プログラムの構成要素)はゲーム内に512個しか置けない、というものです。

この制約に引っかからず、かつモノの区別がつくようにしなければなりません。

これは非常に難しい問題です。

 

どうやって36種類144個のオブジェクトを区別するか

また、はじプロは、モノの区別をつけるのが非常に苦手です。

基本的には、ある基本形(直方体や円柱など)に「おしゃれなモノノードン」というものを連結して、さわっているノードンを使ってそれぞれのモノの区別を付けます。

ただ、おしゃれなモノノードンはゲーム内に32個しか配置できないため、それ以上のモノを区別するには別の方法を考える必要がありました。

 

当初考えていた案は、まずおしゃれなモノノードンで区別し、足りないものは複数の基本形(直方体、円柱、球)を一定法則で牌となるモノに連結し、それぞれを区別するというものでした。

たとえば次のようなものです。

🀉=○
🀛=○○
🀒=○○○
🀂=○○○○

🀊=□
🀜=□□
🀓=□□□
🀃=□□□□

この方式でいけば、16+16+40+40+40+56+56=264通りで、牌本体とロジック部分のノードンを考慮すると最大で7種類の牌を表現できるのではと考えました。

ただ、それだと「なんちゃって上海」になってしまい、往年の、あの「上海」を再現できたとは言い難いものになります。

あの『上海』をはじプロで再現!」と銘打ちたかったので、この案は残念ながら却下することにしました。

 

ある気づき:モノの大きさは0.01m刻みで変えられる

それから数日悩んだある日、ふと思いつきました。

モノの大きさって0.01m刻みで変えられるな…ならばその大きさの違いを計測すればモノを区別でき、連結するモノは1つだけで済むのでは?

モノノードンとさわってるノードンを0.01m刻みで設置し、試行錯誤しつつ試してみると、何とうまくいくではありませんか!

今回の上海の場合は牌を重ねていくので、

0.36(36種類)+0.1(モノノードンの最小サイズ)+0.1(さわってるノードンの最小サイズ)=0.56mの厚みがあれば良いことになります。

牌そのものやその他のノードン類と干渉しないよう球の形を選んだので、自分の中で

ボールぶらさげ方式

と勝手に命名しています。

TACTYさん(@LaboTacty)のご厚意で牌のテクスチャを作っていただけることになり、基本部分はほぼできました。

 

ゲームの難易度調整、そして完成

最後に待ち構えていた難問が、難易度調整です。

ゲームの上海と聞くと、皆さんは↓のようなものを想像されるかと思います。

「DRAGON(龍配列)」と呼ばれる配列です。

もちろんこの配列をそのまま使うのは難しいのですが、おおむねこれに似た配列を採用してテストプレイしていました。

牌自体はランダムに散らばるようにして、毎回楽しめるよう工夫を凝らしました。

が、

全然クリアできない…

10回やって1回クリアできるかできないかの、超絶高難易度のゲームになってしまいました。

こういったパズルゲームは、がんばってクリアした時の達成感がキモだと思っているので、9割方詰むというのは到底容認できません。

あとから調べて分かったのですが、この配列の場合、クリアしやすいように牌の並びをプログラムで調整する必要があるのです。そうしないと容易に詰んでしまいます。

ですがはじプロで上海を作るにあたり、そのような工夫を盛り込む余裕は全くありませんでした。

そして数日悩んだある日、一つの仮説を思いつきました。

・横に並ぶ牌の数が多い列がたくさんあればあるほど、難易度が高くなる

その仮説を検証すべく、DRAGON配列を縦半分にぶった切ってテストプレイをしてみました。

すると驚いたことに、難易度が劇的に下がったのです!

詰む事はほぼなくなりました。

本当に驚きです。たったこれだけの事でこれほど難易度が変わるとは…

ただあまりにも簡単すぎるので、微妙に配置を変えて難易度調整をして、最後の仕上げをして、無事完成しました。

※オリジナルの上海を制作された皆様、また現在においても上海をリリースされている皆様、許諾も得ずに移植してしまいすみません…必要でしたら許諾を取りに伺います。

 

感想

当初想定していた以上に移植度の高いものが出来、自分でも驚いています。

そして改めて、上海は奥の深いゲームだなあと思いました。

派手なゲームが多いはじプロの中にあって地味なゲームかもしれませんが、自分の中では記念碑的な作品になりました。

今回の開発手法を応用すればトランプゲームなども作れると思うので、ぜひ挑戦してみたいと思います。

 

 

謝辞

テクスチャ作成の要望に快く応えてくださったTACTYさん(@LaboTacty)に最大の賛辞を送りたいと思います。

また、暇な親父の趣味に付き合ってテストプレイをしてくれた次男にも感謝したいです。

 

また機会があればゲーム制作と共に、そのメモを書いてみたいと思います。

最後までお読みいただき、ありがとうございました。