10

ゲームにインターネットのハイスコアを実装したいと考えています。そして、プレイヤーにフィードバックを提供します (トップ 100 などだけではありません)。通常の SQL では、次のようになります。

SELECT COUNT(*) FROM Scores WHERE points > :newUsersPoints

とGQLには似たようなものがあります

db.GqlQuery("SELECT * FROM Score WHERE points > :1", newUsersPoints).count()

しかし、count() は 1000 に制限されているため、私の場合はあまり役に立ちません。これを実装する方法についてのアイデアはありますか?

私は2つを持っています

初め:

  1. シャーディング カウンターのアイデアを使用する ( http://code.google.com/intl/pl/appengine/articles/sharding_counters.html ) ある範囲 (from_points、to_points) 内にいくつのスコアがあるかを格納する新しい「テーブル」を作成します。

  2. range.to_points < newUsersPoints である上記の表のすべてのカウンターを合計します

  3. 新しいスコアが db.GqlQuery("SELECT * FROM Score WHERE points > :1 AND points >= :2 AND points < :3", newUsersPoints, range.from_points, range. to_points).count() + sumfrom2

  4. 新しいスコアが含まれる範囲を見つけ、そのカウンターをインクリメントします

  5. 3. カウンターが 1000 (または 999) より大きい範囲を分割して、限界に達しないようにします。

  6. 新しいスコアをスコア テーブルに追加する

これは非常に複雑で、エラーが発生しやすいものです。スコアを追加する前に、範囲とタイムアウトをインクリメントする場合があります。(非トランザクション)

2番目のアイデア:

時々 (毎日 1 回?) すべてのスコアをポイントで並べ替え、新しい位置を与えます (スクリプトはタイムアウトする可能性があるため、チャンクで実行する必要があります)。

新しいスコアがどの場所にあるかを調べるには、次のことを行います

db.GqlQuery("SELECT * FROM Score WHERE points > :1 LIMIT 1", newUsersPoints).get().precalculated_position + 1

他のアイデアはありますか?

4

2 に答える 2

5

私はいくつかの GAE アプリに Ranker を実装しました。それらは、数千人から数十万人がプレイする Facebook アプリケーションです。これはうまく機能しますが、私の目的では大きな欠点が 1 つあります。それは、参加者のスコアが収まる最終的な範囲を事前に宣言する必要があることです。したがって、これは 2 つの理由で良くありません。

  1. 人々のスコアが上限なしで上昇し続けることができる終わりのないコンテストがある場合、あなたは大騒ぎです。

  2. コンテストの開始時に、全員がゼロ近くに集まっている場合、ranker.py で使用されるツリー構造は効率的ではありません。木は非常に深くなり、その幅をほとんど使用しません。

つまり、ranker.py は、スコアが既知の値の範囲で均等にランダムに分布している競技者がいる場合に最適です。他の用途では、最適とは言えません。

より一般的に役立つランキング エンジンをすぐに開発したいと考えています。そのときは必ずこのスレッドを更新します!

于 2009-06-10T06:00:31.950 に答える
4

google-appengine グループのこのスレッドは、おそらく興味深いものになるでしょう。また、これ専用のライブラリーranklistがあるようです。

基本的に、彼らはシャード カウンターに似たようなことをしたようです。

于 2009-03-04T08:57:00.757 に答える