1 of 44

テト譜v115のデータ構造

(完全版)

knewjade

2 of 44

目次

このスライドでは、テト譜のデータ構造を広く説明しています。�なお、バージョンはv115に準拠しています。

part 1. 基本情報・全体図 / Basic Information

part 2. フィールド情報 / Field

part 3. ミノ・フラグ / Piece・Flags

part 4. コメント / Captions

part 5. 後処理 / Post Processing

【オリジナル】

連続テト譜エディタ:https://fumen.zui.jp/

made by Mihys

3 of 44

Part 1

基本情報・全体図

Basic Information

4 of 44

ブロック / Block, Piece

  • テト譜ではミノ7種+空白・グレーの計9種のブロックがある。
  • それぞれに番号がついており、その対応は以下の通り。

番号

0

1

2

3

4

5

6

7

8

種類

空白

I

L

O

Z

T

J

S

グレー

5 of 44

ミノの向き / Rotation

  • 各ミノの向きは次の通り。

番号

0

1

2

3

方向

South

East

North

West

6 of 44

フィールド / Field

  • フィールドの大きさ: 23×10+せり上がり1行で24×10
    • 従って、最大ブロック数は240

  • 各ブロックは1次元配列 (int[]相当)に格納されている
    • 格納順は画像のオレンジの数字の通り
    • フィールドの走査は基本的にこの添字順で行う

7 of 44

データの全体図 / General View

次のデータは 簡単な3ページのデータ です。�このデータの構成は、以下のようになっています。

「1ページ分の情報」が複数個連結した構造になっています。�ただし各ページは、前のページの状態をもとに作るため、独立ではありません。�例えば、ページの情報の順番を並び替えると、データは壊れてしまいます。

v115@ bhA8SeAAA bhAAA8ReAAA chAAA8QeAAA

prefix

1ページ分の情報

8 of 44

データのフォーマット / 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

      となる

9 of 44

データのフォーマット / 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)

10 of 44

Prefix

データの先頭5文字で、主にバージョンの識別に利用します。�バージョンによって、その後のデータの構造が異なってきます。�

先頭1文字のアルファベットは、表示の切り替えに使われているため、データへの影響はありません。そのため、文字だけ置き換えても問題ありません。

v115@

m115@

l115@

エディタ表示 →

List表示 →

View表示 →

v110@

v105@

v100@

v095@

...

...

...

...

...

...

...

...

公式のサポート範囲 (v115時点)

11 of 44

Part 2

フィールド情報

Field

12 of 44

データの全体図 / General View

次のデータは 簡単な2ページのデータ です。�このデータの構成は、以下のようになっています。

このPartでは、この部分について説明します。

v115@ ghE8Je AgH vhA AAA

フィールド

13 of 44

1ページ目のフィールドの例

右図の1行目にグレーがあるフィールドを例とします。

このフィールドが 1ページ目にある場合

データは ghE8Je になります。

このデータがどのような構成になっているかみていきます。

14 of 44

1ページ目のフィールドの構成 #1

まずは、データをpoll(2)します。� (フィールドの数字は2つずつ使用する)

ghE8Je = (32,33), (4,60), (9,30)

ghE8Je = 2144, 3844, 1929

総ブロック数240で除算して、その商と余りを計算します。

ghE8Je = (8,224), (16,4), (8,9)

15 of 44

1ページ目のフィールドの構成 #2

図をみると0番から順に

「空白が225個→グレーが5個→空白が10個」

で構成されています。

そのため ghE8Je は次のことがわかります。

ghE8Je = (8,224), (16,4), (8,9)

ブロック番号 + 8

連続するブロック個数 - 1

※ 注意:この説明は「1ページ目の場合」です

16 of 44

「ブロック番号」の本当の意味

ghE8Je = (8,224), (16,4), (8,9)

【1ページ目の場合】

空のフィールドとの差分値を計算しています。

その結果、ブロック番号と同じ値になります。

ブロック番号 + 8

連続するブロック個数 - 1

前のページのフィールドとの差分値

17 of 44

フィールドのエンコード / 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値をデータに変換します。

18 of 44

フィールドの繰り返し / Field Repeating

「前のページのフィールド」から全く変化がないとき、つまり、

(diff = 8, count = 239) → データ “vh”

になる場合、フィールドをそのあと何ページ繰り返すか設定します。

なおデータは1文字で、最大で63回まで繰り返します。

例) 1ページ目: フィールドデータが “vhB” → Repeat は 1回 (“B”)

2ページ目: フィールドの設定がスキップされます(データが必要ない)

3ページ目: 通常通りにフィールドを設定します

19 of 44

注意点

  • diffを計算するときの「前のページのフィールド」は、ミノやフラグを反映した後のフィールドになります。�たとえば、ゲームのリプレイのように、フィールドを変えずにミノだけを置き続けた場合、diffは常に8となります。
  • 1ページ目の「前のページのフィールド」は、すべてがEmptyであるフィールドと比較します。
  • Repeat = 0になる場合(次のページですぐに変化する場合)でも、データに “A” を記録します。
  • Repeatが64以上の場合は Max63 を設定し、Repeatが0になったタイミングで、新しい繰り返しを設定します。

20 of 44

Part 3

ミノ・フラグ

Piece・Flags

21 of 44

データの全体図 / General View

次のデータは 簡単な2ページのデータ です。�このデータの構成は、以下のようになっています。

このPartでは、この部分について説明します。

v115@ ghE8Je AgH vhA AAA

ミノ・フラグ

22 of 44

データ構造 / 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)

23 of 44

操作中のミノ / Operating piece

  • 「操作しているミノの種類」が記録されています。
  • 値は スライド 4: ブロック / Block, Piece の通り。
  • ミノが選択されていない場合は “0” になります。
  • 「操作しているミノの向き」が記録されています。
  • 値は スライド 5: ミノの向き / Rotation の通り。
  • ミノが選択されていない場合は “0” になります。

const piece = value % 8

value = floor(value / 8)

const rotation = value % 4

value = floor(value / 4)

24 of 44

操作中のミノ / Operating piece

  • 「操作しているミノの場所」が記録されています。
  • 値は スライド 6: フィールド / Field の通り。
  • ミノの軸の位置は、マウスのカーソルが表示される位置になります。
  • ミノが選択されていない場合は “0” になります。

const location = value % 240

value = floor(value / 240)

25 of 44

せりあがりフラグ / Raise flag

  • 「盛」フラグの表示がオンのとき、valueは “1” になります。

const flag_raise = value % 2

value = floor(value / 2)

26 of 44

鏡フラグ / Mirror flag

  • 「鏡」フラグの表示がオンのとき、valueは “1” になります。

const flag_mirror = value % 2

value = floor(value / 2)

27 of 44

色フラグ / Guideline flag

  • 「色」フラグの表示がオンのとき、valueは “1” になります。
  • テト譜エディタでは、1ページ目の設定値がすべてのページに適用されます。�2ページ目以降のフラグの値は使われておらず、必ず “0” になります。

const flag_color = value % 2

value = floor(value / 2)

28 of 44

コメントフラグ / Caption flag

  • 前のページからコメントが更新されたとき “1” になります。
  • 1ページ目は、空文字列でないとき、更新されたと判定されます。�
  • “1” の場合は、Part4のコメントのデータを読み込みます。�
  • コメントがQuizの場合、実際に置いたミノに合わせて、次のコメントを計算しています。
  • 計算後のコメントと比較して、変化がなければ “0” になります。

const flag_comment = value % 2

value = floor(value / 2)

29 of 44

接着フラグ / Lock flag

  • 「接着」フラグの表示がオンのとき、valueは “0” になります。

const flag_lock = !(value % 2)

30 of 44

Part 4

コメント

Captions

31 of 44

データの全体図 / General View

次のデータは 簡単な1ページのデータです。�このデータのコメントの構成は、以下のようになっています。

このコメントのデータは、コメントフラグが “1” のときだけ記録します。�データ化する際、まずはじめに、コメントを escape() でASCIIに変換します。�その後エスケープされた文字列に対して、文字数を記録して4文字ずつ変換します。�もし、4文字ずつ区切る際に文字が足りない場合は “0” でpaddingします。

v115@vhAAgW FA BU4nD GBAAA

文字数

poll(2)

本文�データ5文字につき、コメント4文字

32 of 44

エンコードの例 / 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

33 of 44

コメント用テーブル / 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

      となる

34 of 44

Part 5

後処理

Post-Processing

35 of 44

内部状態の更新 / Update Internal Status

フィールドとコメント(Quiz)の状態は、次のページとの差分に影響を与えます。

そのため次のページを変換する前に、内部的な状態をデータに合わせて更新します。

36 of 44

フィールドの更新 / Update Field

現在のページの最終的なフィールドの状態を確定させます。

フィールドの計算順番(フラグの処理順)は次の通りです。

if (Lockフラグ == 1) {

if (the piece is valid) ミノを置く();

ライン消去();

if (riseフラグ == 1) フィールドのせりあがり();

if (mirrorフラグ == 1) フィールドの左右反転();

}

37 of 44

Quizの更新 / Update Quiz

コメントが #Q= から始まっている場合は、Quizであると判定されています。

Quizが有効で、かつミノを接着させたときは、ツモの情報を更新します。

現在のミノ() or ホールドミノ[] に、接着したミノがあれば取り出して、

ネクストを含めた全体の状態を調整します。

38 of 44

ここまでの流れで、1ページ分のデータをつくれます。

この処理をページと同じ回数だけ繰り返せば、データは完成です。

もどる → スライド 11: Part 2 フィールド情報 Field

39 of 44

補足

Additions

40 of 44

参考資料 / References

2021年8月現在、ソースコード以外の情報は基本的にありません。たぶん。

連続テト譜エディタ [JavaScript]

この資料の著者の実装も置いておきます。

tetris-fumen [TypeScript]

41 of 44

v110とv115の違い

/ Difference between 110 and 115

フィールドの高さ(プレイエリア)が 21 (v110) → 23 (v115) になっています。

それ以外のデータの構造は同じです。

フィールドの高さによって、上限値が変わる項目がいくつかあるため、出力されるデータの文字列は部分的に変化します。

42 of 44

データの文字数制限 / Max Length

テト譜の仕様上の制約として、データの文字数の上限はありません。

ただし、実際にWeb上で利用する上で、サイト側のアプリケーションとして制約を設けていたり、サーバー・ブラウザの制約を受けてエラーになる場合はあります。

<制約の例>

連続テト譜エディタの制約:最大ページ数2000、出力時の最大文字数32768 ...

ブラウザで扱えるURLの最大長:Qiitaの記事

サーバーで扱えるURLの最大長:Apacheはデフォルトだと8190byte

43 of 44

データ内の“?” / “?” in the data

連続テト譜エディタでは、47文字ごとに “?” を挿入します。

v115@.... ? .... ? .... ? ….

一方で、この”?”はデータ上の意味を持っていないため、省略しても構造上問題ありません。

なぜ ”?” を挿入しているのか、筆者(knewjade)は把握できていません。

47文字

44 of 44

おわり

指摘や不明点、要望 などは https://twitter.com/1millim まで