주루마블 기본 알고리즘 생성중.
- 시작위치 생성 - 각 위치별 추가 이벤트시 사용될 이벤트 알고리즘 - Rapier, Three.js를 통한 주사위.
This commit is contained in:
93
app/game/chessman.ts
Normal file
93
app/game/chessman.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
/** 주사위판 위를 이동하는 말. */
|
||||
export class Chessman {
|
||||
private index: number;
|
||||
private readonly boardLength: number;
|
||||
/** 1: 시계방향, -1: 반시계방향 */
|
||||
private direction: 1 | -1 = 1;
|
||||
/** 무인도: 남은 대기 턴, 탈출 가능 눈 */
|
||||
private island: { turnsLeft: number; escapeOn: number } | null = null;
|
||||
|
||||
constructor(boardLength: number, startIndex = 0) {
|
||||
if (boardLength <= 0) {
|
||||
throw new Error('Chessman boardLength must be positive');
|
||||
}
|
||||
this.boardLength = boardLength;
|
||||
this.index = ((startIndex % boardLength) + boardLength) % boardLength;
|
||||
}
|
||||
|
||||
get position(): number {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
get facing(): 1 | -1 {
|
||||
return this.direction;
|
||||
}
|
||||
|
||||
get isOnIsland(): boolean {
|
||||
return this.island != null;
|
||||
}
|
||||
|
||||
get islandTurnsLeft(): number {
|
||||
return this.island?.turnsLeft ?? 0;
|
||||
}
|
||||
|
||||
reverseDirection(): 1 | -1 {
|
||||
this.direction = this.direction === 1 ? -1 : 1;
|
||||
return this.direction;
|
||||
}
|
||||
|
||||
enterIsland(turns: number, escapeOn = 6) {
|
||||
this.island = { turnsLeft: Math.max(1, Math.trunc(turns)), escapeOn };
|
||||
}
|
||||
|
||||
clearIsland() {
|
||||
this.island = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 무인도 상태에서의 주사위 처리.
|
||||
* - escape: 6(또는 escapeOn)으로 탈출 → 이후 정상 이동
|
||||
* - wait: 턴 소모 후 대기 (turnsLeft 0이면 자동 해제, 이번 턴은 이동 없음)
|
||||
* - free: 이미 무인도 아님
|
||||
*/
|
||||
resolveIslandRoll(roll: number): 'escape' | 'wait' | 'free' {
|
||||
if (!this.island) return 'free';
|
||||
|
||||
if (roll === this.island.escapeOn) {
|
||||
this.island = null;
|
||||
return 'escape';
|
||||
}
|
||||
|
||||
this.island.turnsLeft -= 1;
|
||||
if (this.island.turnsLeft <= 0) {
|
||||
this.island = null;
|
||||
}
|
||||
return 'wait';
|
||||
}
|
||||
|
||||
teleport(index: number): number {
|
||||
this.index = ((index % this.boardLength) + this.boardLength) % this.boardLength;
|
||||
return this.index;
|
||||
}
|
||||
|
||||
moveOne(): number {
|
||||
return this.move(1);
|
||||
}
|
||||
|
||||
/** steps칸만큼 현재 방향으로 이동 */
|
||||
move(steps: number): number {
|
||||
const amount = Math.trunc(steps);
|
||||
if (amount === 0) return this.index;
|
||||
const delta = amount * this.direction;
|
||||
this.index = (this.index + delta) % this.boardLength;
|
||||
if (this.index < 0) this.index += this.boardLength;
|
||||
return this.index;
|
||||
}
|
||||
|
||||
reset(startIndex = 0): number {
|
||||
this.index = ((startIndex % this.boardLength) + this.boardLength) % this.boardLength;
|
||||
this.direction = 1;
|
||||
this.island = null;
|
||||
return this.index;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user