import { Vector2 } from "../engine/vector2.js" import { getPiece } from "../engine/getPiece.js" import { PLAYER } from "../constants.js" const SURROUNDING = [ new Vector2(-1, 0), new Vector2(0, 1), new Vector2(0, -1), new Vector2(1, 0), ] export function hasLiberties({ position, team }) { if (getPiece(position) != undefined) return false let groups = getSurroundingGroups(position, team) groups.push(position) let liberties = getGroupLiberties(groups) liberties = Vector2.removeIfInArray(position, liberties) if (liberties.length == 0) { let enemies = getGroupSurroundingEnemies(groups, team) let enemyLiberties = getGroupLiberties(enemies) enemyLiberties = Vector2.removeIfInArray(position, enemyLiberties) return (enemyLiberties.length == 0) } return (liberties.length > 0) } function getLiberties(position) { return getSurroundingSquares(position) .filter(p => getPiece(p) == undefined) } function getGroupLiberties(group) { let checkedPositions = [] group .map(p => getLiberties(p)) .forEach(g => g .forEach(p => Vector2.pushIfNotInArray(p, checkedPositions)) ) return checkedPositions } function getGroup({position, checkedPositions = []}) { if (Vector2.isInArray(position, checkedPositions)) { return } checkedPositions.push(position) let team = getPiece(position).team getSurroundingSquares(position) .filter(p => getPiece(p) != undefined) .filter(p => getPiece(p).team == team) .forEach(p => { getGroup({ position: p, checkedPositions: checkedPositions }) }) return checkedPositions } function getSurroundingGroups(position, team) { let surroundingGroups = getSurroundingSquares(position) .filter(p => getPiece(p) != undefined) .filter(p => getPiece(p).team == team) .map(p => getGroup({position: p})) if (surroundingGroups.length == 0) { return [] } return surroundingGroups .reduce((partialArray = [], newGroup) => { if (newGroup.length == 0) { return partialArray } if (Vector2.isInArray(newGroup[0], partialArray)) { return partialArray } return partialArray.concat(newGroup) }) } function getGroupSurroundingEnemies(group, playerTeam) { if (group.length == 0) return [] let team = PLAYER.OPPOSITE(playerTeam) let surroundingEnemies = group .map(p => getSurroundingGroups(p, team)) if (surroundingEnemies.length == 0) return [] return surroundingEnemies .reduce((partialArray = [], newGroup) => { if (newGroup.length == 0) { return partialArray } if (Vector2.isInArray(newGroup[0], partialArray)) { return partialArray } return partialArray.concat(newGroup) }) } function getSurroundingSquares(position) { return Array.from(SURROUNDING) .map(v => Vector2.sum(v, position)) .filter(z => 0 <= z.x && z.x < board.size && 0 <= z.y && z.y < board.size ) }