Newer
Older
PixelPaintWar / apps / server / src / domains / game / entities / map / mapContestResolver.ts
/**
 * mapContestResolver
 * 同一セルに複数チームが重なった場合の競合判定を提供する
 * 純粋関数として切り出し,単体テストを容易にする
 */

/** 同一セルに異なるチームが存在していることを示すセンチネル値 */
export const CONTESTED_CELL = -2;

/** プレイヤーごとのグリッド位置情報 */
export type PlayerGridEntry = {
  playerId: string;
  gridIndex: number | null;
  teamId: number;
};

/**
 * 各セルの占有チームを判定し,競合セルは CONTESTED_CELL でマークする
 * @returns セルインデックス → チームID(競合時は CONTESTED_CELL)のマップ
 */
export const resolveUncontestedCells = (
  entries: PlayerGridEntry[],
): Map<number, number> => {
  const cellTeamMap = new Map<number, number>();

  for (const { gridIndex, teamId } of entries) {
    if (gridIndex === null) continue;

    const existing = cellTeamMap.get(gridIndex);
    if (existing === undefined) {
      cellTeamMap.set(gridIndex, teamId);
    } else if (existing !== CONTESTED_CELL && existing !== teamId) {
      cellTeamMap.set(gridIndex, CONTESTED_CELL);
    }
  }

  return cellTeamMap;
};

/** 指定セルが塗り可能(競合でない)かを判定する */
export const isCellPaintable = (
  cellTeamMap: Map<number, number>,
  gridIndex: number,
): boolean => {
  const ownerTeamId = cellTeamMap.get(gridIndex);
  return ownerTeamId !== undefined && ownerTeamId !== CONTESTED_CELL;
};