STUDIO HAZE · jeniapp
Topaz source
Open by house policy. Topaz is our own language.
Topaz 5.20.2 · 63 files
apps/slow-monster/core/lineagedex.tpz
Topaz · 4897 B · Original file
1
// 계통도감의 나무 배치를 계산합니다. 열은 세대이고 뿌리가 왼쪽, 자손이 오른쪽으로 가지를 칩니다.2
// 입력은 발견 순서의 계통 노드 목록이고 출력은 노드마다 열, 행, 픽셀 좌표, 부모의 배치 번호와 나무 전체 크기입니다.3
// 난수 없이 목록 순서만 쓰므로 같은 목록은 늘 같은 배치입니다.4
// 노드 수와 세대를 상수로 가둬 조작된 목록도 멈추지 않거나 넘치지 않고, 가시 영역 160x144 를 넘는 나무는 페이지가 스크롤합니다.5
// Lineage dex layout: a bounded, deterministic depth-first tree layout of discovered lineage nodes.7
import core.evolution8
import core.util { 범위가두기 }10
// 형제를 훑는 배치는 노드 수의 제곱에 가까워 조작된 큰 목록을 256 에서 자릅니다. 그 너머 노드는 그리지 않습니다.11
export let 노드상한 = 25612
export let 세대상한 = 9913
export let 열간격 = 3414
export let 행간격 = 2215
export let 여백x = 1416
export let 여백y = 2418
// 인덱스는 노드 목록의 발견 순서이고 커서가 가리키는 값입니다. 부모인덱스는 배치 목록 안의 부모 자리이며 뿌리와 고아는 -1 입니다.19
export type 배치노드 = {20
인덱스: int,21
고유번호: int,22
부모인덱스: int,23
열: int,24
행: int,25
x: int,26
y: int,27
형태이름: string,28
게놈요약: string,29
세대: int,30
시드지문: string,31
}33
export type 계통레이아웃 = {34
노드들: Array<배치노드>,35
너비: int,36
높이: int,37
행수: int,38
}40
// 부모고유번호 0 은 뿌리이고, 목록에 없는 부모를 가리키는 노드는 고아라 뿌리처럼 다룹니다.41
function 부모인덱스찾기(노드들: Array<evolution.계통노드>, 부모고유번호: int) -> int {42
if 부모고유번호 == 0 { return -1 }43
for i in 0..<노드들.length {44
if 노드들[i].고유번호 == 부모고유번호 { return i }45
}46
-147
}49
function 자식인가(자식: evolution.계통노드, 부모: evolution.계통노드) -> bool {50
자식.부모고유번호 != 0 && 자식.부모고유번호 == 부모.고유번호51
}53
function 뿌리인가(노드들: Array<evolution.계통노드>, 노드: evolution.계통노드) -> bool {54
부모인덱스찾기(노드들, 노드.부모고유번호) < 055
}57
function 자식인덱스들(노드들: Array<evolution.계통노드>, 부모인덱스: int) -> Array<int> {58
let 부모 = 노드들[부모인덱스]59
[for i in 0..<노드들.length if i != 부모인덱스 && 자식인가(노드들[i], 부모) => i]60
}62
function 배치인덱스찾기(배치들: Array<배치노드>, 노드인덱스: int) -> int {63
for i in 0..<배치들.length {64
if 배치들[i].인덱스 == 노드인덱스 { return i }65
}66
-167
}69
// 뿌리부터 발견 순서대로 깊이 우선 전위 순회하며 방문 순서대로 행을 줍니다. 자식이 부모 바로 아래에 모입니다.70
// 스택에는 역순으로 넣어 꺼내는 순서가 발견 순서가 되게 합니다. 방문 표시가 순환과 중복을 막고 방문 수는 노드상한에서 멈춥니다.71
export function 레이아웃계산(노드들: Array<evolution.계통노드>) -> 계통레이아웃 {72
let mut 방문 = [for i in 0..<노드들.length => false]73
let mut 배치들: Array<배치노드> = []74
let mut 최대열 = 075
let mut 스택 = [for i in (노드들.length - 1)..0 by -1 if 뿌리인가(노드들, 노드들[i]) => i]76
while 스택.length > 0 && 배치들.length < 노드상한 {77
let 인덱스 = 스택[스택.length - 1]78
스택 = 스택.slice(0, 스택.length - 1)79
if !방문[인덱스] {80
방문[인덱스] = true81
let 노드 = 노드들[인덱스]82
let 열 = 범위가두기(노드.세대, 0, 세대상한)83
let 행 = 배치들.length84
최대열 = 최대열.atLeast(열)85
let 부모인덱스 = 부모인덱스찾기(노드들, 노드.부모고유번호)86
배치들.push({87
인덱스: 인덱스,88
고유번호: 노드.고유번호,89
부모인덱스: if 부모인덱스 < 0 { -1 } else { 배치인덱스찾기(배치들, 부모인덱스) },90
열: 열,91
행: 행,92
x: 여백x + 열 * 열간격,93
y: 여백y + 행 * 행간격,94
형태이름: 노드.형태이름,95
게놈요약: 노드.게놈요약,96
세대: 노드.세대,97
시드지문: 노드.시드지문,98
})99
let 자식들 = 자식인덱스들(노드들, 인덱스)100
for i in (자식들.length - 1)..0 by -1 { 스택.push(자식들[i]) }101
}102
}103
// 노드 카드 30x18 이 들어갈 여유를 더하고 가시 영역보다 작아지지 않게 합니다.104
{105
노드들: 배치들,106
너비: (여백x + 최대열 * 열간격 + 32).atLeast(160),107
높이: (여백y + 배치들.length * 행간격 + 18).atLeast(144),108
행수: 배치들.length,109
}110
}SHA256 ed0ec9eaa05715f0847ef9b96e75c0d39c4167b54f0674dc42adca67b1613429