feat: rng & commands impl & tests

This commit is contained in:
hyper
2026-04-01 17:34:21 +08:00
parent ea337acacb
commit df9698b67b
10 changed files with 835 additions and 221 deletions
+58 -4
View File
@@ -5,7 +5,7 @@ import {RNG} from "../utils/rng";
export type Region = Entity & {
// aligning axes of the region
axes: RegionAxis[];
// current children; expect no overlapped positions
children: EntityAccessor<Part>[];
}
@@ -27,7 +27,49 @@ export type RegionAxis = {
*/
export function applyAlign(region: Region){
for (const axis of region.axes) {
// TODO implement this
if (region.children.length === 0) continue;
// 获取当前轴向上的所有位置
const positions = region.children.map(accessor => accessor.value.position);
// 根据当前轴的位置排序 children
region.children.sort((a, b) => {
const posA = a.value.position[0] ?? 0;
const posB = b.value.position[0] ?? 0;
return posA - posB;
});
if (axis.align === 'start' && axis.min !== undefined) {
// 从 min 开始紧凑排列
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
currentPos[0] = axis.min! + index;
accessor.value.position = currentPos;
});
} else if (axis.align === 'end' && axis.max !== undefined) {
// 从 max 开始向前紧凑排列
const count = region.children.length;
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
currentPos[0] = axis.max! - (count - 1 - index);
accessor.value.position = currentPos;
});
} else if (axis.align === 'center') {
// 居中排列
const count = region.children.length;
const min = axis.min ?? 0;
const max = axis.max ?? count - 1;
const range = max - min;
const center = min + range / 2;
region.children.forEach((accessor, index) => {
const currentPos = accessor.value.position.slice();
// 计算相对于中心的偏移
const offset = index - (count - 1) / 2;
currentPos[0] = center + offset;
accessor.value.position = currentPos;
});
}
}
}
@@ -37,5 +79,17 @@ export function applyAlign(region: Region){
* @param rng
*/
export function shuffle(region: Region, rng: RNG){
// TODO implement this
}
if (region.children.length <= 1) return;
// Fisher-Yates 洗牌算法
const children = [...region.children];
for (let i = children.length - 1; i > 0; i--) {
const j = rng.nextInt(i + 1);
// 交换位置
const posI = children[i].value.position.slice();
const posJ = children[j].value.position.slice();
children[i].value.position = posJ;
children[j].value.position = posI;
}
}