テト譜v115のデータ構造
(完全版)
knewjade
目次
このスライドでは、テト譜のデータ構造を広く説明しています。�なお、バージョンはv115に準拠しています。
part 1. 基本情報・全体図 / Basic Information
part 2. フィールド情報 / Field
part 3. ミノ・フラグ / Piece・Flags
part 4. コメント / Captions
part 5. 後処理 / Post Processing
Part 1
基本情報・全体図
Basic Information
ブロック / Block, Piece
番号 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
種類 | 空白 | I | L | O | Z | T | J | S | グレー |
ミノの向き / Rotation
番号 | 0 | 1 | 2 | 3 |
方向 | South | East | North | West |
フィールド / Field
データの全体図 / General View
次のデータは 簡単な3ページのデータ です。�このデータの構成は、以下のようになっています。
「1ページ分の情報」が複数個連結した構造になっています。�ただし各ページは、前のページの状態をもとに作るため、独立ではありません。�例えば、ページの情報の順番を並び替えると、データは壊れてしまいます。
v115@ bhA8SeAAA bhAAA8ReAAA chAAA8QeAAA
prefix
1ページ分の情報
データのフォーマット / Data format
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 | A | B | C | D | E | F | G | H | I | J |
1 | K | L | M | N | O | P | Q | R | S | T |
2 | U | V | W | X | Y | Z | a | b | c | d |
3 | e | f | g | h | i | j | k | l | m | n |
4 | o | p | q | r | s | t | u | v | w | x |
5 | y | z | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
6 | 8 | 9 | + | / | | | | | | |
十の位↓
→一の位
vhAAgH は
47,33,0,0,32,7
となる
データのフォーマット / Data format
65以上の数字を表現する場合は、複数個の文字を組み合わせて1つの数字に変換します。この変換のことを、このスライドでは poll(n) と書いています。
AA = 0 = 0 + 0 * 64�BA = 1 = 1 + 0 * 64
…
/A = 63 = 63 + 0 * 64
AB = 64 = 0 + 1 * 64
…
// = 4095 = 63 + 63 * 64
poll(2)
AAA = 0 = 0 + 0 * 64 + 0 * 4096
...
abc = 116442 = 26 + 27 * 64 + 28 * 4096
...
poll(3)
Prefix
データの先頭5文字で、主にバージョンの識別に利用します。�バージョンによって、その後のデータの構造が異なってきます。�
先頭1文字のアルファベットは、表示の切り替えに使われているため、データへの影響はありません。そのため、文字だけ置き換えても問題ありません。
v115@
m115@
l115@
エディタ表示 →
List表示 →
View表示 →
v110@
v105@
v100@
v095@
...
...
...
...
...
...
...
...
公式のサポート範囲 (v115時点)
Part 2
フィールド情報
Field
データの全体図 / General View
次のデータは 簡単な2ページのデータ です。�このデータの構成は、以下のようになっています。
このPartでは、この部分について説明します。
v115@ ghE8Je AgH vhA AAA
フィールド
1ページ目のフィールドの例
1ページ目のフィールドの構成 #1
まずは、データをpoll(2)します。� (フィールドの数字は2つずつ使用する)
ghE8Je = (32,33), (4,60), (9,30)
ghE8Je = 2144, 3844, 1929
総ブロック数240で除算して、その商と余りを計算します。
ghE8Je = (8,224), (16,4), (8,9)
1ページ目のフィールドの構成 #2
図をみると0番から順に
「空白が225個→グレーが5個→空白が10個」
で構成されています。
そのため ghE8Je は次のことがわかります。
ghE8Je = (8,224), (16,4), (8,9)
ブロック番号 + 8
連続するブロック個数 - 1
※ 注意:この説明は「1ページ目の場合」です
「ブロック番号」の本当の意味
ghE8Je = (8,224), (16,4), (8,9)
【1ページ目の場合】
空のフィールドとの差分値を計算しています。
その結果、ブロック番号と同じ値になります。
ブロック番号 + 8
連続するブロック個数 - 1
前のページのフィールドとの差分値
フィールドのエンコード / Field Encoding
1. フィールドの0番から順に、前のページのフィールドと現在のページのフィールドとの「差分」を計算します。
diff = current - prev + 8
※ diffの範囲は 0 <= diff <= 16 となります
2. count = (diffが同じ値で続く個数 - 1) をカウントして求めます。
3. (diff, count) の2つの数字を、データ用の数字 value に変換します。
value = diff * 240 + count
4. value値をデータに変換します。
フィールドの繰り返し / Field Repeating
「前のページのフィールド」から全く変化がないとき、つまり、
(diff = 8, count = 239) → データ “vh”
になる場合、フィールドをそのあと何ページ繰り返すか設定します。
なおデータは1文字で、最大で63回まで繰り返します。
例) 1ページ目: フィールドデータが “vhB” → Repeat は 1回 (“B”)
2ページ目: フィールドの設定がスキップされます(データが必要ない)
3ページ目: 通常通りにフィールドを設定します
注意点
Part 3
ミノ・フラグ
Piece・Flags
データの全体図 / General View
次のデータは 簡単な2ページのデータ です。�このデータの構成は、以下のようになっています。
このPartでは、この部分について説明します。
v115@ ghE8Je AgH vhA AAA
ミノ・フラグ
データ構造 / Data Structure
3文字のデータの中に、複数の情報が入っています。
const piece = value % 8
value = floor(value / 8)
value = poll(3)
const rotation = value % 4
value = floor(value / 4)
const location = value % 240
value = floor(value / 240)
const flag_raise = value % 2
value = floor(value / 2)
const flag_mirror = value % 2
value = floor(value / 2)
const flag_color = value % 2
value = floor(value / 2)
const flag_comment = value % 2
value = floor(value / 2)
const flag_lock = !(value % 2)
操作中のミノ / Operating piece
const piece = value % 8
value = floor(value / 8)
const rotation = value % 4
value = floor(value / 4)
操作中のミノ / Operating piece
const location = value % 240
value = floor(value / 240)
せりあがりフラグ / Raise flag
const flag_raise = value % 2
value = floor(value / 2)
鏡フラグ / Mirror flag
const flag_mirror = value % 2
value = floor(value / 2)
色フラグ / Guideline flag
const flag_color = value % 2
value = floor(value / 2)
コメントフラグ / Caption flag
const flag_comment = value % 2
value = floor(value / 2)
接着フラグ / Lock flag
const flag_lock = !(value % 2)
Part 4
コメント
Captions
データの全体図 / General View
次のデータは 簡単な1ページのデータです。�このデータのコメントの構成は、以下のようになっています。
このコメントのデータは、コメントフラグが “1” のときだけ記録します。�データ化する際、まずはじめに、コメントを escape() でASCIIに変換します。�その後エスケープされた文字列に対して、文字数を記録して4文字ずつ変換します。�もし、4文字ずつ区切る際に文字が足りない場合は “0” でpaddingします。
v115@vhAAgW FA BU4nD GBAAA
文字数
poll(2)
本文�データ5文字につき、コメント4文字
エンコードの例 / Sample for Encoding
コメント”abc” → データ”DABUYCA”
文字数)3文字なので “DA”
本文)�1. “abc” をコメント用のテーブルで数字に変換�スライド 31: コメント用テーブル / Table for captions��2. 1つの数値に変換�なぜか係数は 96 なので注意!(テーブルは95文字)
3. この数字を5文字のデータに変換�スライド 7: データのフォーマット / Data format
abc → (65,66,67,0)
65+66*(96^1)+67*(96^2)+0*(96^3) = 623873
623873 → (1,20,24,2,0) → BUYCA
コメント用テーブル / Table for Captions
※ 文字の並び順はASCII と同じです
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
0 | SP | ! | “ | # | $ | % | & | ‘ | ( | ) |
1 | * | + | , | - | . | / | 0 | 1 | 2 | 3 |
2 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = |
3 | > | ? | @ | A | B | C | D | E | F | G |
4 | H | I | J | K | L | M | N | O | P | Q |
5 | R | S | T | U | V | W | X | Y | Z | [ |
6 | \ | ] | ^ | _ | ` | a | b | c | d | e |
7 | f | g | h | i | j | k | l | m | n | o |
8 | p | q | r | s | t | u | v | w | x | y |
9 | z | { | | | } | ~ | | | | | |
十の位↓
→一の位
Gray は
39,82,65,89
となる
Part 5
後処理
Post-Processing
内部状態の更新 / Update Internal Status
フィールドとコメント(Quiz)の状態は、次のページとの差分に影響を与えます。
そのため次のページを変換する前に、内部的な状態をデータに合わせて更新します。
フィールドの更新 / Update Field
現在のページの最終的なフィールドの状態を確定させます。
フィールドの計算順番(フラグの処理順)は次の通りです。
if (Lockフラグ == 1) {
if (the piece is valid) ミノを置く();
ライン消去();
if (riseフラグ == 1) フィールドのせりあがり();
if (mirrorフラグ == 1) フィールドの左右反転();
}
Quizの更新 / Update Quiz
コメントが #Q= から始まっている場合は、Quizであると判定されています。
Quizが有効で、かつミノを接着させたときは、ツモの情報を更新します。
現在のミノ() or ホールドミノ[] に、接着したミノがあれば取り出して、
ネクストを含めた全体の状態を調整します。
補足
Additions
参考資料 / References
2021年8月現在、ソースコード以外の情報は基本的にありません。たぶん。
連続テト譜エディタ [JavaScript]
この資料の著者の実装も置いておきます。
tetris-fumen [TypeScript]
v110とv115の違い
/ Difference between 110 and 115
フィールドの高さ(プレイエリア)が 21 (v110) → 23 (v115) になっています。
それ以外のデータの構造は同じです。
フィールドの高さによって、上限値が変わる項目がいくつかあるため、出力されるデータの文字列は部分的に変化します。
データの文字数制限 / Max Length
テト譜の仕様上の制約として、データの文字数の上限はありません。
ただし、実際にWeb上で利用する上で、サイト側のアプリケーションとして制約を設けていたり、サーバー・ブラウザの制約を受けてエラーになる場合はあります。
<制約の例>
連続テト譜エディタの制約:最大ページ数2000、出力時の最大文字数32768 ...
ブラウザで扱えるURLの最大長:Qiitaの記事
サーバーで扱えるURLの最大長:Apacheはデフォルトだと8190byte
データ内の“?” / “?” in the data
連続テト譜エディタでは、47文字ごとに “?” を挿入します。
v115@.... ? .... ? .... ? ….
一方で、この”?”はデータ上の意味を持っていないため、省略しても構造上問題ありません。
なぜ ”?” を挿入しているのか、筆者(knewjade)は把握できていません。
47文字
おわり
指摘や不明点、要望 などは https://twitter.com/1millim まで