STUDIO HAZE · jeniapp
Topaz source
Open by house policy. Topaz is our own language.
Topaz 5.20.2 · 63 files
apps/slow-monster/core/genome.tpz
Topaz · 7403 B · Original file
1
// 크리처의 게놈과 드리프트를 계산합니다. 게놈은 계통시드에서 유도한 다섯 개의 작은 정수이고 드리프트는 성장으로 천천히 쌓이는 카운터입니다.2
// 계통시드는 월드시드와 크리처의 기원으로 만든 문자열입니다. 표현형은 원본 게놈에 드리프트 단계만큼 흔들림을 더한 값이고, 드리프트가 진화임계에 닿으면 진화 준비입니다.3
// 게놈과 흔들림은 mutation 도메인 난수만 쓰므로 조우와 전투 난수가 게놈을 바꿀 수 없고, 같은 시드와 플레이는 같은 게놈을 만듭니다.4
// 상태, 데이터, 전투 모듈을 가져오지 않습니다. 모든 값을 가둬 손상된 저장이 정수 넘침이나 느린 그리기를 일으키지 않게 합니다.5
// Genome and drift: a five-trait genome derived from a lineage seed, slow drift, phenotype nudges and evolution readiness.7
import core.rng { 난수 }8
import core.util { 범위가두기 }10
// 색소, 막, 크기, 대사, 촉수는 연못 미생물의 형질이고 값은 [0, 강도상한) 입니다.11
export record 게놈 {12
색소: int,13
막: int,14
크기: int,15
대사: int,16
촉수: int,17
}19
// 토파즈 과제 '구조 타입 주석 속 다른 모듈 레코드' 때문에 모듈째 가져오며 TPZ3017 때문에 레코드를 따로 가져올 수 없어 이 함수로 만듭니다.20
// 5.21 에서 그 과제가 고쳐지면 제거 여부를 다시 봅니다.21
export function 게놈만들기(색소: int, 막: int, 크기: int, 대사: int, 촉수: int) -> 게놈 {22
게놈 { 색소: 색소, 막: 막, 크기: 크기, 대사: 대사, 촉수: 촉수 }23
}25
export let 트레이트수 = 526
export let 강도상한 = 828
// 10 이면 유한한 야생을 다 비울 때 3~4 세대까지 진화해 자동 진행이 보스를 이길 수 있습니다.29
export let 진화임계 = 1030
export let 드리프트상한 = 100000032
// 흔들림 계산이 단계에 비례하므로 단계를 상수로 가둡니다. 진화임계 / 8 = 3 까지만 미리 보여 줍니다.33
export let 단계상한 = 335
enum 기원 {36
시조,37
야생(string),38
모름,39
}41
export function 시작계통시드(월드시드: string) -> string {42
"{월드시드}#starter"43
}45
// 같은 시드에서 같은 스텝, 칸, 종으로 잡으면 같은 계통시드입니다.46
export function 야생계통시드(월드시드: string, 스텝: int, x: int, y: int, 종아이디: int) -> string {47
"{월드시드}#wild@{스텝}:{x}:{y}:{종아이디}"48
}50
// 진화는 계통시드 뒤에 ">분기" 를 붙이므로 맨 앞의 기원 표시는 어느 노드에도 남습니다.51
function 기원읽기(계통시드: string) -> 기원 {52
let 해시조각들 = 계통시드.split("#")53
if 해시조각들.length < 2 { return 기원.모름 }54
let 핵심 = 해시조각들[1].split(">")[0]55
if 핵심 == "starter" { return 기원.시조 }56
let 야생조각들 = 핵심.split("@")57
if 야생조각들.length < 2 { return 기원.모름 }58
기원.야생(야생조각들[1].split(":")[0])59
}61
export function 출처(계통시드: string) -> string {62
match 기원읽기(계통시드) {63
case 시조 => "시조"64
case 야생(스텝) => "야생 #{스텝}"65
case 모름 => "야생"66
}67
}69
// 숲 공유 코드에 쓰는 짧은 기원 키입니다.70
export function 출처키(계통시드: string) -> string {71
match 기원읽기(계통시드) {72
case 시조 => "S"73
case 야생(스텝) => "W{스텝}"74
case 모름 => "W"75
}76
}78
// 시드 문자열이 크리처마다 게놈 스트림을 가르므로 엔티티 인자는 0 입니다.79
export function 계통엔티티(계통시드: string) -> int {80
난수("mutation", 0, 0, 계통시드)81
}83
// 선형합동 난수의 아래 비트는 규칙적이라 작은 폭으로 줄이면 치우치므로 위 비트를 씁니다.84
function 트레이트유도(엔티티: int, 트레이트번호: int, 계통시드: string) -> int {85
(난수("mutation", 엔티티, 트레이트번호, 계통시드) / 21474836) % 강도상한86
}88
export function 게놈유도(계통시드: string) -> 게놈 {89
let 엔티티 = 계통엔티티(계통시드)90
게놈 {91
색소: 트레이트유도(엔티티, 0, 계통시드),92
막: 트레이트유도(엔티티, 1, 계통시드),93
크기: 트레이트유도(엔티티, 2, 계통시드),94
대사: 트레이트유도(엔티티, 3, 계통시드),95
촉수: 트레이트유도(엔티티, 4, 계통시드),96
}97
}99
// 기본은 레벨업 하나에 3, 레벨업 없는 승리에 2 입니다. 데모는 어떤 승리든 두 번이면 임계를 넘도록 14 와 12 를 씁니다.100
export function 드리프트증가(오른레벨: int, 승리: bool, 데모: bool) -> int {101
let 레벨당 = if 데모 { 14 } else { 3 }102
let 승리몫 = if 데모 { 12 } else { 2 }103
if 오른레벨 > 0 { 오른레벨 * 레벨당 } else if 승리 { 승리몫 } else { 0 }104
}106
export function 드리프트가두기(드리프트: int) -> int {107
범위가두기(드리프트, 0, 드리프트상한)108
}110
// 여덟마다 한 단계라 흔들림이 드물고 느리게 보입니다.111
function 드리프트단계(드리프트: int) -> int {112
(드리프트가두기(드리프트) / 8).atMost(단계상한)113
}115
// 단계마다 -1, 0, +1 중 하나를 더합니다. 카운터를 트레이트수만큼 띄워 게놈유도의 카운터 0~4 와 겹치지 않게 합니다.116
function 너지(엔티티: int, 트레이트번호: int, 단계: int, 계통시드: string) -> int {117
let 방향들 = map(1..<(단계 + 1), k => (난수("mutation", 엔티티, 트레이트번호 + k * 트레이트수, 계통시드) / 21474836) % 3 - 1)118
방향들.reduce(0, (합, 방향) => 합 + 방향)119
}121
// 페이지가 표현형으로 블롭의 색조와 모양을 조금 흔들어 다가올 진화를 미리 보여 줍니다.122
export function 표현형(원본: 게놈, 계통시드: string, 드리프트: int) -> 게놈 {123
let 단계 = 드리프트단계(드리프트)124
if 단계 <= 0 { return 원본 }125
let 엔티티 = 계통엔티티(계통시드)126
게놈 {127
색소: 원본.색소 + 너지(엔티티, 0, 단계, 계통시드),128
막: 원본.막 + 너지(엔티티, 1, 단계, 계통시드),129
크기: 원본.크기 + 너지(엔티티, 2, 단계, 계통시드),130
대사: 원본.대사 + 너지(엔티티, 3, 단계, 계통시드),131
촉수: 원본.촉수 + 너지(엔티티, 4, 단계, 계통시드),132
}133
}135
export function 진화준비(드리프트: int) -> bool {136
드리프트가두기(드리프트) >= 진화임계137
}139
export function 드리프트퍼센트(드리프트: int) -> int {140
범위가두기(드리프트가두기(드리프트) * 100 / 진화임계, 0, 100)141
}143
export function 게놈요약(대상: 게놈) -> string {144
"{대상.색소},{대상.막},{대상.크기},{대상.대사},{대상.촉수}"145
}147
function 트레이트칸(칸들: Array<string>, i: int) -> int {148
범위가두기(if 칸들.length > i { toInt(칸들[i]) ?? 0 } else { 0 }, 0, 강도상한 - 1)149
}151
// 게놈요약의 역입니다. 도감이 가지 않은 형제 후보를 다시 유도할 때 씁니다.152
export function 게놈요약파싱(요약: string) -> 게놈 {153
let 칸들 = 요약.split(",")154
게놈 {155
색소: 트레이트칸(칸들, 0),156
막: 트레이트칸(칸들, 1),157
크기: 트레이트칸(칸들, 2),158
대사: 트레이트칸(칸들, 3),159
촉수: 트레이트칸(칸들, 4),160
}161
}SHA256 e48f9c8d127a43e18ee716cd28b83ae33417c4becca0d9826d3779f2954ef8d9