HTML5でトーナメント表


トーナメント図作成WEBアプリ

HTML5のCanvas上に一部自動でトーナメント表を表示させる事を目指したときの
自分用メモ(つぶやきの集合)を公開。
メモの時系列は上が昔で下が新しくなってます。
メモ書きそのままなので正しい日本語ではありません。
メモの表のずれもあります。
独自の意味で使っている用語もあると思われます。
間違っていたものも最初はそう考えていたと言うことで残してあります。
アプリは最初の予定、途中経過、最終結果を生成可能。
シードは一回戦のみ対応。
Canvasなので画像として生成できます。
下の3つの画像がそのサンプルです。


生成サンプル


A.予定
トーナメント表サンプル予定
 
B.途中経過
トーナメント表サンプル途中経過
 
C.結果
トーナメント表サンプル結果
 

 

そもそもトーナメントとは?

    一対一の対決で進行し、負けたら終了というルールを図式したもの。
    階層構造。
    必ずしも公平ではないが。
   絶対必要なデータ。
   出場者、出場チーム一覧。
   シード問題。
   シードはとりあえず置いておいて。
   途中経過。
   途中経過もあるなら、勝ち負けデータの保存がいる。
   勝利者ライン
   得点表示領域
     チーム名を並べる。
   チーム名の中心から線が伸びる。
   名前を並べて中心から出る線。
   一次シード。二次シード。
   シード無し。
   勝ち負け無し。
   横ピラミッド構造。
   座標。
   パネルの選択。
   複数の方法論。
   最も単純なトーナメント。
   2チーム。
   線は5本。 予定時        上チーム勝利     下チーム勝利
   上チーム名から先に出る横線。    黒            赤          黒
   下チーム名から先に出る横線。    黒            黒          赤 
   横線から下に出る縦線。       黒            赤          黒
   横線から上に出る縦線。       黒            黒          赤
   その縦線から横に出る線。      黒            赤          赤

   A、B、C、D4チームからなるトーナメントの言語化。
   第一試合 AとBの試合 勝者 次枠
   第二試合 CとDの試合 勝者 次枠
   第三試合 勝者ID1 と 勝者ID2の試合 勝者


   第一試合 1 2
   第二試合 3 4
   第三試合 5 6

   試合結果で代入
   全枠に枠番を付ける。
   
   シードずらし
   シードによって最初のチーム名の並びをずらすか?
   それとも、線の方をずらすか?

   シードのダミー法
   架空のチームを作成して不戦勝として描く。

   グリッド法

   法則性
    座標と長さの法則性。
    文字列の並びにおいて、配列を何ピクセル事に並べるかという指定。
    その指定から、回戦を進めるごとに、位置とか、線の長さを計算できる。
    2回戦以降をループできる。
    最初は、各回戦事に記述する。
    数字を判断して数式化する。
    ループで回すという方法。
    2のn乗化。
    無駄な線が残る。
    下の文字を書くときに次回戦への線を書く。
    ループによる。
    現状ではただ線を書くという挑戦。
    次はまずシード判定。
    シードという文字列があったならば、前のチームは半分下に置く。
    シードチームについては書かない。
    一回戦におけるシード判定は比較的容易ではあった。
    各線の配列化。
     各配列に対して赤黒指定。
     試合数。
     上から試合IDを作成する。
     そのためには、回戦ごとにカウントを行う。

    HTML5のFORM、input type=rangeを使用して、文字サイズと、各項目間の幅の調整。
    その調整や、大量出場チームに備えて、キャンバスの拡大。
    それが入っているDIV枠の拡大コードを追加した。

    出場者が2の何乗とかでは無い場合の自動シード機能が必要であるかも。
    一画面に納めるための左右からののぼりづめ

    結果ライン
    勝ち進んだところを赤く記録していく、トーナメントアプリでは必須の機能である。
    選択肢。
    クリックして色を変える。毎回入力が必要。
    データ形式からの。
    データ入力欄の生成。
    未定 敗北 勝利 シード(勝利)
    これはあれだろう。各試合別に、上勝利下勝利で選択して。
    上データライン配列、下データライン配列。
    一回戦上データ配列、下データ配列。
    ※2回戦以降の横棒は結果時には全て赤。
    ※シードは結果時には赤
    上塗り方式。
    一回戦の横棒と
     シード配列
     各試合事 
     上配列 下配列 X座標 Y座標 太さ 長さ
    各試合事のセレクトオプションと、それを受けるコード。
    全試合の、上か下か未定か。
    優勝チームも自分で入力。
    途中経過も可能ではあるが。
    何回戦まで勝利しているかの選択オプションを設置。

    まずは、シードを赤く塗る。
    上下ではなく、元をたどってチーム名まで行かないとソフトとしての意味が無い。
    結果表。
    試合番号の斜め右上、右下座標に得点表示欄が作成されても良い。
    最初に何回戦まであるかを確認できれば、もっと単純に線が引ける。

    2日目朝現在できる機能
     テキストエリアに入力されたリストからトーナメント表自動生成。
     試合番号の表示。
     各試合事の結果入力欄
     幅、文字の拡大、縮小。

    直近の課題。
     勝利者ライン
     色を塗る。
     色を塗るために、各線の配列化。

    勝ち進んだとして、あるチームが出場する試合番号一覧。

    表示部については、まあ、完成。
    とにかくトーナメント表そのものを作れと言われたときに速攻で作るためのツールにはなった。
    
    無駄なループ等があるので、その改善。
    チーム名をもっと長く書けるようにする。
    また、横によせたり上部にあげたり。
 
    挟み込みレイアウトへの対応。

    直近の課題としては、試合結果を記録する。
    試合結果データを作成する必要がある。
       とにかく、実試合のIDとシード時のみなし試合のIDを両方持つ試合後ごと一行のリスト形式。
    2の何乗
    一回戦
    回戦、みなし試合番号、実試合番号、上チーム、下チーム、勝利チーム、、、
    二回戦以降
    回戦、みなし試合番号、実試合番号、上チーム、下チーム、勝利チーム、上チーム参照みなし試合番号、下チーム参照みなし試合番号、
    シードがあれば、その場で勝利チームへと記録。

    印刷対応

    トーナメント表の代表格
    64チームで左右から迫る形。
    右側
     左側と同一ロジックではあるが、横座標が、
     右側だったら基準値プラスと回戦が上がるごとになっていたものが、
     画面左の方のピクセル値から回戦が上がるごとにマイナス担っていく。
     そこを変えるだけで十分。
     決勝戦の線と三位決定戦
     三位決定戦は、独立した図。

     抽選部分
      距離から、何回戦で当たるか判定する。
      枠番からの距離。
      属性によって振り分けた上で抽選。
 
     座標として考える。
     得点エリア
      右側から上がっていく場合
      交点の右上右下が表示領域
      得点上配列
      得点下配列
      試合の構造体とかで、構造体.上チーム得点 といった形も考えられる。

     基準に基づく規則性を持った座標指定。
      →効率性と整った感じを実現

     途中経過も含めて線を引くなら、
      全ラインデータの配列内への格納が必要。

     toDataURLによる画像化→当然可能だった。
     印刷時の改ページ指定。クロームで印刷→pdf化。も可能だった。

     トーナメントの座標
      最初のチームと最後のチームの線。
      その中心が優勝者の線。
       その線と最初のチームの線の中心が準決勝の線
       その線と最後のチームの線の中心も準決勝の線

     試合毎のリストが完成した。
      さらにやるなら、得点、会場、日時とかもいるかも?
     一回戦から上へとの並び。
     二回戦以降については、チーム枠2つについて、どの試合番号の勝者が入るのかのデータあり。
     二回戦以降でループして、指定回戦の勝者を取得するコード。
     結局データリストを操作してのコードに書き換える必要が出てきた。
     データリストに基づいてのどちらが勝利か入力欄の完成。一回戦のみ。
     一回戦の入力データに基づき、上回戦のデータ切り替え。
     一応できたが、シード対応になっておらず、不具合が。
     最初の段階で、実試合、対応表が必要。
     対応表による変換処理。
     実試合を要素とした全試合配列。
     そもそも実試合だけの配列というのがおかしかった。
     また、=一つにすべき所を==にしてしまうミスが多く発生した。
     試合結果の記録という別アプリと考えた方が良い。
     対応表で大丈夫なのか?
     そもそもシード時の項目形式さえまだできていなかった。
     実試合番号はどこで使うのか?
     実試合とみなし試合の対応表を作成することによって完成した。

とりあえずのまとめ
      トーナメント予定表の自動生成。
      HTMLのテキストエリアに一行ごと入力されたチーム名のリストに基づき。
      トーナメント予定表を生成。
      画面左側に入力した順番通りにチーム名が並ぶ。
      そこから線が出ていく普通のトーナメント表が生成される。
      HTML5のレンジを用いて、文字サイズと、縦の文字と線の間の間隔を変更。
      レンジの変化に連動してのリアルタイム変化。
      toDataURLで画像化。
      印刷改行の間に挟むことにより、ページを指定すれば、クロームでそこだけPDF化。
      チーム名が表示されたセレクトボックスで勝者を選択。
      赤太線が引かれていく。
      一回戦の勝者を選択すると2回戦の試合の選択欄に自動でチーム名が表示される。
      さらに上の回戦も同様の方式で表示される。
      試合をリスト形式で表現したものも生成される。
      何回戦か?試合番号、対戦チーム名と勝者名。
      現在はテキストボックスに。
      そのリストから、トーナメント結果表の生成については、まだ作成していない。
     
     線のグループ分けが不完全
      これについては、既存のものの改良にするか。
      それとも、リスト形式のものから、線を引くものを新たに作成するか?
      リストからの生成が求められる。
      リストcsv形式作成ソフトの機能としてのトーナメント。
     その他、デザインで言えば、出場者欄の枠組みを四角描くか。改行対応するか。
     ラインID、回戦、対応試合、(上か下かシード)、横か縦かシードか、横座標、縦座標、横幅、縦幅、
     
     
     1回戦    2回戦     3回戦     4回戦    5回戦
初期位置  0     0+(基準値/2)   基準値*1.5  基準値*3.5  基準値*7.5
差    基準値 かける2 かける4 かける8   かける16
             50

           1 50       150
           2 250       550
           3 450       950
           4 650
           5 
           6
           7
           8          
 
          mt = (Math.pow(2、ks-1)-1);
          2 1
          3 3
          4 7          

         各試合毎なので2倍必要か?。
           100

           0*(100*2)+50 50
   1*(100*2)+50 250
2*(100*2)+50 450
         なぜ正しい数値にならないのか?
         

          初期位置
           0  1  3  7
           1  2  4  8 から 1を引いたもの。0.5かけたもの足す。

     実際に画面を書きながら試してなんとか意図した場所に表示された。
     この基準が出来ていれば、それに特定の数字を足すとかで良いはず。
     その計算もいるが。
     わかりきっているものでも、数式化するとなると。
     なんどか試して達成した。
     理屈と言うよりいろいろ入れてみて確認した。
     
     別ロジックでのトーナメントの作成。思ったより難航。
     規則性はわかるが、それを数式に表すのが。
     可変のチーム数が。

     レシピ 
     1.画面左側に出場者チーム等を並べます。
     2.メンバー数から試合の予定表をリスト化します。
     3.試合ごとのライン座標を計算して、試合を添字とする配列に代入します。
     4.3の座標に基づきCanvas上に試合予定トーナメントの生成コード
     5.試合結果入力欄とそれを受ける関数の作成。
     6.結果入力に基づいて赤太線を引いたものを表示します。

    副機能
     1.幅の指定。
     2.文字サイズの指定
     3.画像ファイルとして生成
     4.印刷の利便性をはかるタグ指定。(トーナメント部を1ページ)
     5.途中経過の保存

     1試合目とか、最後の線とか、シードとか。
     そういうイレギュラーの部分。
     それがさらに複合する部分が、複雑化する傾向に。
     さらに、リストからという方法だといっそう複雑に。

主要関数
   関数1 最初に実験的に描写していった関数。正確に表示できる。
      関数2 結果入力欄を表示するためのコード。4チームで最後がシードの時の不具合有り。
      関数3 結果の選択を配列に代入するためのコード
      関数4 低い数値回戦の結果から次回戦の出場チーム名を取得してリストに入れるコード。
      関数5 旧結果登録
      関数6 確実に赤いところは最初から赤く書いておくためのコード
      関数7 対戦結果に基づいて勝利したチームのラインを引くためのコード。
      関数8 画像化
      関数9 チーム一覧から試合リストを生成するためのコード。
      関数10 試合リストから、ラインの座標を生成するためのコード。
               現在テスト中のため実際に表示させるのと配列代入を一緒に混ぜてやっている。

      シードが合った場合の不具合の原因は複数。
      勝者決定なのに、それを読みに行くコードを経由していない。
      セレクトオプションに挟む改行タグ挿入の判定式。
      出場者名と、試合番号の表示。
       既存コード等の利用。
      勝者ネームだけではなく上下どちらが勝ったかの数字データ欄もいる。
      それを改善しますと、数字で選択している部分も変更しなければなりません。
      試合名の表示は完成。
      これは、もともと交点座標からの距離を指定すれば良いだけなので難しくはなかった。
      基準値からの。
      次はチームの表示。
      チームの座標はどうするか。
      幅は連動するが、基準の横は別にしておく。
      長い文字列を入れたり入れなかったり。

      それ以降のロードマップと見通し。
      配列から表示させる。
      配列から勝者名を引き出して、赤と黒を変えて表示させる。
      最終試合が終了しているとの判定により、最後の線を表示して、優勝チームを表示する。
      表示 みなし試合番号でループ。
         勝ち負け判定 実試合番号。
      勝者番号 上チーム得点 下チーム得点
      結果入力欄の改善 得点入力法にする。
      また、SVGで線をクリックすることによる方法も考える。
 
      textareaから取得→レコードの生成→シードから勝ち上がり部分のレコードの変更→
      座標の計算→予定の表示→結果入力欄の生成
      結果入力→結果の表示→結果入力欄の変更

      旧来の表示コードを排除できる段階へと。
      常にレコードを操作して、そのレコードからの表示という。
      統合されたものにする。途中経過の保存も可能にする。

      みなし試合。実試合のどちらでループさせているか。
      配列空白であれば非表示とかのふりわけ。
      配列中身無しがエラーの発生源。

      レコードから予定を生成するまでの数式の方のテストは完了した。
      配列に入れて複合して、戻して表示させる必要がある。
      その際、試合結果に基づき色の変化を与えて表示させる。

      レコードからのテストと言うことでいろいろ詰め込んでいる座標計算部分について、座標を配列に入れるのみにするか。
      とも思ったが、スライドバーでの変動時に数値を再計算するので、全部あってもいいのか。
      なければ計算不可能。

      そろそろ、初期のテキストエリアからの直接書き部分を必要なところを残して削除。

      勝利したのは上か下かの数値は、若干わかりづらいが一番最後に追加すると言うことで良いだろう。

      データというか番号のまとめ
      みなし試合番号 座標の計算をする場合に使う。
      実試合番号 試合結果の入力 試合番号の表示 
      試合番号の表示は、他と絡まないから特に対応表での変換は必要無し。
      対応表によって処理を行う。

      中間生成物 最終生産物
       試合予定結果表 csv形式 2次元配列形式
       座標配列 一次元配列 複数の配列
       結果入力欄 HTMLフォーム文字列
       トーナメント図 canvas上 jpg 

      ループは何
      回戦(何回戦まであるかを判定してのループ)
      出場者名でループ

      特殊なところ
      最初のテキストエリアにおいて単に順番だけでは無く奇数番と偶数番に意味づけ。
      試合単位で一行の形式で、左にトーナメント図における単一の試合で上に来るチーム、右に単一の試合で下に来るチーム。
      シードは内部ではみなし試合として処理。
      一回戦のみシード対応
      上の勝利ライン座標配列と下の勝利ライン座標配列を別配列にして、リストによる勝利者記入欄からの判定で色と太さを分ける。

      当初の実験的なロジックでの描写コードの削除は完了し、必要な物だけ残した。
      みなし試合番号を使用するところ、実試合番号を使用するところ。
      関数の呼び出し関係の整理を行った。
      初期化。
      テキストエリアから読み出して最初のレコード構造を生成する物。
      シードデータから読み出して第二回戦の出場チームを得る関数。
       これは、後に使う下位の回戦データから勝利者を読み出して上位の回戦のカードを決定する関数でもある。
      結果入力欄生成関数
      データに基づいて座標配列を作成する関数。
      座標配列に基づいてキャンバスに配置を行う関数。

      結果ラインの赤太線の描画。
      座標計算ロジックと表現ロジックは分けていたが、結局、表現時に赤黒判定。
      最初の横線。それ以降の横線。初回は負けチームは横線が引かれないが、それ以降は横線は引かれる。
      予定トーナメント。結果トーナメント。同一関数内、条件式で振り分け。途中経過も対応。
      途中経過のレコードからの読み込みはまだ非対応。
      途中経過保存するほど大規模なものか?
      それほど頻繁な更新がいるか?レコードを生成しているのでその逆を行うコード。
      配列挿入コードを作成すれば良い。
      優勝者名の表示。優勝ラインの判定。優勝者テキスト枠。横幅を若干広げる必要が。
      背景色指定。文字色指定。HTML5の習得を目指しているのだから、input type=colorの使いどころ。
      フォームからおくられてくるデータの形式の確認が必要である。
      得点表示欄。交点から右上と右下座標を指定すれば良い。
      結果入力欄の改善。試合を選び、得点を入力するという形になるか。
      

日記(なからにしら座)