オセロらしく

株式会社シンメトリック新入社員の青木です。 先週はWeb&デジタルマーケティングEXPO 春に参加したことについての記事を執筆しましたが、今回からは通常通りとして通信対戦型オセロ作成についてを書きます。

今週の目標

前回からだいぶ時間がたっておりますが、順番通りに書きます。前回はWebSocketでの通信を用いて異なるブラウザ間での情報の同期を図るということをしました。

今回はその情報を発信して受け取るところ、つまりはゲーム部分のロジックを練り、オセロオセロしてるような部分をブラウザ上での機能としてjavascriptで作り、あわよくばブラウザ間で対戦ができるまでを目標とします。期間が一週間だけでしたら目標が高そうといったところですが、やはり実時間がかなり立っておりますので、できそうであるとします。

行ったアプローチ

まあ言ってしまえばオセロというゲームをjavascriptで作ったというソースコードは数多くあるのでそのまま使えそうな気がしたのですが、それらはほぼ我々に要求されている通信対戦という部分を含んでいないので、部分的にしか参考にできません。 とはいえ、これらのWeb上でいくらでも散見されるようなオセロのソースコードをまったく使えないとして認定してやらないのは正直もったいないという気持ちがあったので、参考にできるという部分を大きくするようなロジックを練ることにしました。

その散見されるオセロのソースコードはやはり他言語よりもjavascriptのものが多いので、オセロとしてのだいたいの機能をブラウザに押し込み、1ブラウザだけでは無理である部分の、他ブラウザからの入力(置いた石の座標などを仲介する)を最低限の機能としてサーバーにて動くJAVAのソースに持たせることにしました。 こうすることで前回作ったWebSocket用のJAVAソースコードを何も改変・追加せずにjavascriptのみで今週を戦えるのでスムーズでよいと思います。

このやり方のイメージとしては、コンピューター(CPU)相手を前提としているオセロのソースコードから、そのCPUによる座標入力処理の部分を抜き取り、その代わりとして、ただサーバーからの情報を受け取るだけのことを書き下すといったかたちです。CPUとして考えて石を置く部分をまるまる省ける上に、それ以外の大部分を参考元と同じロジックかのように書けそうなので逆に簡単そうです。

ですので、まず最初に 置く→待たされる→サーバーが送ってきた座標を認識する→置く→…… というキャッチボールをつくることにしました。これではキャッチボールでありオセロらしくないので、よりオセロらしくするために本当は 置ける場所を識別する→置く→置かれた座標によりひっくり返す→待たされる→サーバーが送ってきた座標を認識する→送られた座標によりひっくり返す→置ける場所を識別する→…… となるまで自分と相手の入力時の処理で分けて作りこむ必要があるのですが、これらの「設置可能座標識別」と「反転」のロジックは一つ作ればそれぞれ使いまわせそうなため、まずその前段階であるキャッチボールを完成させます。

前回の記事ではボタンを押したら1回につき1足されてそれが各ブラウザ上で同期されているだけのプログラムを作りましたが、今回はまず最初にオセロの枠らしくボタンをそれぞれ用意して、ボタンを押すとその座標の情報がサーバーに送られつつ入力制限がかかり、サーバーによる仲介で座標の情報を送られ次第それを反映しつつ入力制限がなくなりボタンを押せるようになるプログラムを作ります。 その後、ひっくり返すための機能を作ります。

作業結果

前提がひとつ間違っていました。前回作ったWebSocketのプログラムはサーバーが受け取った情報を全てのブラウザへ送ります。ですのでこれを使いまわすとなると、ボタンを押すことでサーバーに送った情報がすぐに返ってくることになります。つまり、 置く→サーバーが送ってきた座標を認識する→待たされる→サーバーが送ってきた座標を認識する→置く→… となっています。

このキャッチボール部分は置いた座標と自分の送った座標がサーバーから返ってきたものが同じものですので、上書きされても問題がなく動いてしまい気付きませんでした。 次の段階として作ったひっくり返す機能自体は様々な資料から知恵を得て作れたのですが、それを動かす段階でこの認識の間違いが効き、多くのエラーを生みました。

これを正すにはサーバーサイドのソースを書き換え、接続中のブラウザ全部ではなく指向性を持たせることにするか、ブラウザサイドでサーバーから受け取ることができるタイミングを制限するかになります。今回はサーバーサイドは触りたくないとして、ブラウザの機能としてタイミングを絞ることに決めました。

0527

(画像においての大きさは4×4ですが、実際には4の倍数であれば最後まで遊べます。)

ということでブラウザ間で遊べるオセロができました。

課題

今回はとりあえずオセロとして動けばよいとしてタイミング制限の手法をとりましたが、サーバーに情報が送られ次第すべてのブラウザに返すというのは明らかに無駄な処理であり、そもそもすべてのブラウザに返すということはひとつのサーバーで1ゲームしかできないということですのでここを作りなおします。ということで次回はセッションIDをサーバーで発行してブラウザに取得させる機能を作るつもりです。

Page Top