schemaverseのクライアントボットを作成する

画像 ハブで、SQLゲームについての言及が既にありました。 しかし、私はすべて忙しかったので、つい最近それが何であるかを理解することにしました。 偶然にも、 Habrですでに言及されているスキーマバースを選択しました。



私はそれを理解しているように、あなたはそれのためにボットを書くとき、あなたはゲームのすべての喜びを得ます。 このために、お気に入りの言語の1つであるjavascriptを選択しました。 また、マップを視覚化して、自分の船がどのように飛行して敵の惑星を捕らえるかを確認することにしました。 記事を膨らませないように、多くのコードとSQ​​Lクエリは提供しません。 リポジトリでそれらを常に確認できます



ボットの行動アルゴリズムは非常に簡単です-マイナーを作成し、侵略者を作成し、侵略者が十分になったら-捕まえるために飛びます。 それでも、途中で船を修理するエンジニアが作られており、十分なお金があれば、艦隊のアップグレードに費やしています。



当初から、サードパーティのライブラリの使用を最小限に抑えることにしました。 そのため、最初にデータベースへの接続を確立します。



var config = require('./config.js'); // Postgres connection var pg = require('pg'), conn = "pg://"+config.username+":"+config.password+"@db.schemaverse.com:5432/schemaverse"; var UserModel = require('./models/user'); var CommandProcessor = require('./command_processor'); pg.connect(conn, function(err, client) { if (!err){ var userModel = new UserModel.constructor(client); CommandProcessor(userModel); } else { console.log(err); } });
      
      





接続が確立された後、ユーザーが初期化され、コンソールで統計を確認してビジュアライザーを起動できるように、コマンドハンドラーを追加しました。

ユーザーが初期化されると、ユーザーの惑星に関する情報が収集されます。 鉱夫/侵略者/エンジニアの建設は、それぞれの惑星をそれ自身のために作ります。 そして、すべての船の給油/アップグレード。

これはターンベースの戦略であり、移動時間の依存関係を追跡できませんでした。 したがって、前の移動の長さに応じて、移動が完了したかどうかを確認します。 新しい移動の開始時に、船のステータスがチェックされ、ticイベントにサブスクライブするハンドラーが呼び出されます。 新しい惑星の捕獲に関する情報は、イベントのリストから取得されます。 惑星を占領するには、そこから燃料をうまく抽出するだけで十分です。 これはゲームの唯一のリソースです。 また、移動するたびに、すべての飛行船の進路と速度が修正されます。

新しい惑星をキャプチャすると、その惑星は惑星のリストに追加され、ticイベントにサブスクライブします。



 var tick = function(){ repair_damaged(); create_miners(); create_attackers(); go_to_conqueror(); } //constructor user.on(tick);
      
      





コンソール出力からこのすべてを追跡することは、あまり面白くないです。 ゲームのステータスをいつでも確認できるCommandProcessorモジュールを追加しました。 サポートされているコマンドのリストはいつでも展開できます。 しかし、より詳細に、ビジュアライザーと私が直面しなければならなかった問題についてお話したいと思います。



mapコマンドを入力した後、最初に行うことは、WebサーバーとWebSocketサーバーの作成です。



 var app = require('http').createServer(handler), io = require('socket.io').listen(app, { log: false });
      
      





また、ビジュアライザーはticイベントをサブスクライブし、マップを更新できるというメッセージをクライアントに送信します。

実際、Webサーバーは、静的データ、つまりWebSocketクライアントを転送するためにのみ必要です。

既存のビジュアライザーは、一般的なマップのみを表示します。 私の目標は、艦隊を展示することでもありました。



次のようになります。

画像

接近したとき、私はより多くの惑星をしました。なぜなら、それらは船によって閉じられていたからです。



最大規模では、マップは非常に長い間更新されています。 あなたがそれを動かすか、それを増やすなら、あなたも長い時間待たなければなりません。 くしゃみをするたびにマップを更新するのではなく、ユーザーが新しい希望の座標を入力するまで待ちます。 マップはマウスホイールとシャッフルに応答します。 クライアントは、目的のパターンの増加、オフセット、およびサイズを転送します。 サーバーは、このデータに基づいて、データベースにオブジェクトを要求し、それらをキャンバスに描画して、クライアントに返します。



 get_map_base64( data.x, data.y, data.w, data.h, data.zoom, data.render_planets, data.render_ships, function(img){ socket.emit('draw', img); } );
      
      





理論上、サーバーは船のみまたは惑星のみを描画できますが、私はまだ使用していません。



惑星のリストをローカルに保存し、「征服」イベントに応じて個々の惑星を変更し、ベースからすべてのカードを取得せず、正方形に分割して正方形から1つを取得する場合、マップの更新速度を最適化できました。

しかし、それらをローカルに保存するためにたくさんあります、私はメモリを節約することにしました、そしてあなたが正方形から1つをとるなら、あなたは最初の惑星を見ることができません。 そのため、これまでプロセスを最適化しないことにしました。 さらに、大幅に増加すると、すべてが非常に迅速に更新されます。



プロジェクトリポジトリのリンク-https://github.com/peinguin/schemaverse_bot



All Articles