Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2004-04-01

[開発ログ]リーグ生成

リーグ生成処理が一部しっくりこない。

#-----------------------------------------------------------------------------
#    大会ステータス
#    新規は手動で作成。このレコードの存在=大会の存在である。
#-----------------------------------------------------------------------------
CREATE TABLE compe_state (
  ID             INT  primary key auto_increment,

  stageCounter   INT  not null default 1,
  dayMax         INT,                 # 経過日数がこの値に達すると大会が終了し、新しいリーグが組まれる
                                      # 試合数ではなく休日を含めたあくまで日数
  dayCounter     INT,                 # 経過日数
                                      # NULLだとリーグ新規作成

  gameMax        INT  not null,       # 奇数:1リーグの試合数。ここから1リーグの参加人数(gameMax+1)が決まる
  turn           INT  not null,       # 同じ相手と戦う回数。ステージの試合数は(gameMax*turn)
  gameCounter    INT  not null,       # すでに終了した試合数
  schedule       CHAR(255) not null,  # 1,1,1,1,1,0,0,1,1,1,1,0 スケジュールリスト
  gradeMax       INT  not null,
  leagueNums     CHAR(255) not null,  # 1,3,9,0…  グレード別のリーグ数。必ず最後が0
  downNums       CHAR(255) not null,  # 3,3,3,3,…  グレード別の降格人数
                                      # 最後(最高ランク)の数字は基本的に0。1以上ならその人数が抜ける→NPCで補充

  updatedTime    TIMESTAMP,           # 更新日時
  creationTime   TIMESTAMP,           # 作成日時
);


#-----------------------------------------------------------------------------
#    リーグデータ
#-----------------------------------------------------------------------------
CREATE TABLE league_data (
  ID             INT primary key auto_increment,

  CompeID        INT not null,         # 大会ID
  StageID        INT not null,         # ステージ
  Grade          INT not null,         # グレード
  GroupID        INT not null,         # グループ

  WinAward       INT not null,         # 勝利時の賞金
  DrawAward      INT not null,         # 引き分け時の賞金

  state          ENUM("Playing","After") not null default "Playing",

  UserList       CHAR(255) not null,   # teamid1,teamid2,teamid3,… エントリー順
                                       # デバッグ用。正式にはleague_data_usersで管理される

  updatedTime    TIMESTAMP,            # 更新日時
  creationTime   TIMESTAMP,            # 作成日時

  UNIQUE (CompeID,StageID,GroupID,Grade)
);


#-----------------------------------------------------------------------------
#    リーグデータユーザーズ
#    そのリーグにエントリしているユーザーのリスト
#-----------------------------------------------------------------------------
CREATE TABLE league_data_user (
  UserID         INT not null,
  LeagueID       INT not null,
  EntryIdx       INT not null,

  UNIQUE (userID,LeagueID),
  UNIQUE (LeagueID,EntryIdx),
);


#-----------------------------------------------------------------------------
#    順位テーブル
#    順位とリーグ中の成績を記録。試合終了時に更新。
#    インサートはリーグ更新時だけなので、過去の大会の順位ログが残っていく。
#    
#    リーグ作成時にこのリストも作成される。
#-----------------------------------------------------------------------------
CREATE TABLE compe_ranking (
  userID          INT not null,
  CompeID         INT not null,           # LeagueIDからも引けるが持っておく
  StageID         INT not null,           # LeagueIDからも引けるが持っておく
  LeagueID        INT,
  Grade           INT,

  ranking         INT,                    # リーグ内順位
  gRanking        INT,                    # ランク内順位
  cRanking        INT,                    # 大会総合順位

  win             INT not null default 0,
  draw            INT not null default 0,
  lose            INT not null default 0,

  score           INT not null default 0,

  UNIQUE (userID,LeagueID)
);


#-----------------------------------------------------------------------------
#    対戦データ
#    試合の対戦記録。リーグ更新時にまとめて作成される。
#    試合が行われたときに更新される。
#    スケジュールの役割も果たす。
#
#    容量計算
#      4*4+3+80+80=179+index ≒ 200
#      5000(games) × 200(Byte) × 1000(days) = 1,000,000,000 = 1G
#    よって 1万人1000日稼動でHDD消費1ギガ
#-----------------------------------------------------------------------------
CREATE TABLE vs_data (
  ID              INT primary key auto_increment,
  LeagueID        INT not null,
  DayCount        INT not null,       # 何日目に行われる何試か
  GameCount       INT not null,       # 何試合目か

  homeID          TINYINT not null,   # 試合会場のID
  homeUserID      INT not null,
  awayUserID      INT not null,
  homeScore       TINYINT,            # NULLなら試合が行われていないとみなす
  awayScore       TINYINT,            # NULLなら試合が行われていないとみなす

  UNIQUE (LeagueID,GameCount,homeUserID)
);

leaguefactory.rb

#=============================================================================
#  リーグ工場
#
#    新規にリーグを作成
#    vs_data(対戦スケジュール)もここで作成
#    既存のリーグに途中参加のユーザを追加
#
#=============================================================================

class LeagueFactory
  #---------------------------------------------------------------------------
  #    ひとつのリーグを新規作成
  #    vs_data(対戦スケジュール)もここで作成
  #---------------------------------------------------------------------------
  def LeagueFactory.make(sql,compeID,stageID,member,grade)
  end

  #---------------------------------------------------------------------------
  #    大会参加者全員分のリーグを作成
  #
  #    順位順にソートし、上から順にグループに振り分ける
  #    リーグのエントリに不足があればNPCを作成してエントリさせる
  #---------------------------------------------------------------------------
  def LeagueFactory.make_all(sql,compeID,stageID)
  end
end

ranking.rb

#=============================================================================
#  compe_rankingテーブルに対する操作を行う
#
#
#=============================================================================

class Ranking
  #---------------------------------------------------------------------------
  #    compe_ranking作成
  #---------------------------------------------------------------------------
  def Ranking.make_new(sql,compeID,stageID)
  end

  #---------------------------------------------------------------------------
  #    compe_ranking.cRankingを成績にソートした順位で更新する
  #---------------------------------------------------------------------------
  def Ranking.update_cranking(sql,compeID,stageID)
  end

  #---------------------------------------------------------------------------
  #    leagueIDを設定
  #---------------------------------------------------------------------------
  def Ranking.update_leagueID(sql,compeID,stageID)
  end
end

_test_all.rb

init_test(sql)
CardDealer::deal_to_all(sql)

stageID = -1
compeID = make_compe_state(sql)
Ranking::make_new(sql,compeID,stageID)
Ranking::update_cranking(sql,compeID,stageID)

LeagueFactory::make_all(sql,compeID,stageID)
Ranking::make_new(sql,compeID,stageID)
Ranking::update_cranking(sql,compeID,stageID)
Ranking::update_leagueID(sql,compeID,stageID)

明日もう一度考えてみよう。