import { board } from "../board.js" import { Vector2 } from "../engine/vector2.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) // if (stones.length > 0) console.log(stones) // console.log(stones) return true // return checkLiberties({ // position, // team // }) } function getSurroundingGroups(position, team) { return getSurroundingSquares(position) .filter(p => getPiece(p) != undefined) .filter(p => getPiece(p).team == team) .map(p => getGroup({position: p})) } function getGroup({position, checkedPositions = []}) { if (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 getPiece(position) { return board.stones[position.y][position.x] } function checkLiberties({ position, team, checkedStones = [], checkedLiberties = [], checkedEnemies = [], isAttacking = false, isRoot = true, }) { if (isInArray(position, checkedStones)) { return } checkedStones.push(position) let surroundingSquares = getSurroundingSquares(position) surroundingSquares.every((z) => { let s = board.stones[z.y][z.x] switch (true) { case s == undefined: pushIfNotInArray(z, checkedLiberties) break case s.team == team: handleFriendlyStone({ position: z, team: team, checkedStones: checkedStones, checkedLiberties: checkedLiberties, checkedEnemies: checkedEnemies, isAttacking: isAttacking, }) break case s.team != team: if (isAttackingEnemyStone({ position: z, team: s.team, checkedEnemies: checkedEnemies, isAttacking: isAttacking, })) { isAttacking = true return false } break } return true }) if (isRoot) { let liberties = checkedLiberties .filter(x => !Vector2.equals(x, position)) .length if (liberties > 0 || isAttacking) { return true } return false } } function isInArray(position, array) { return Array.from(array) .some(p => Vector2.equals(p, position)) } function pushIfNotInArray(position, array) { if (!isInArray(position, array)) { array.push(position) } } 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 ) } function handleFriendlyStone(data) { checkLiberties({ position: data.position, team: data.team, checkedStones: data.checkedStones, checkedLiberties: data.checkedLiberties, checkedEnemies: data.checkedEnemies, isAttacking: data.isAttacking, isRoot: false, }) } function isAttackingEnemyStone({ position, isAttacking, checkedEnemies, }) { if (isAttacking) { return } let liberties = getEnemyLiberties({ position: position, team: board.stones[position.y][position.x].team, checkedEnemies: checkedEnemies, }) if (liberties == 1) { return true } return false } function getEnemyLiberties({ position, team, checkedEnemies, checkedEnemyLiberties = [], }) { if (isInArray(position, checkedEnemies)) { return } checkedEnemies.push(position) getSurroundingSquares(position) .forEach(z => { let s = board.stones[z.y][z.x] switch (true) { case s == undefined: pushIfNotInArray(z, checkedEnemyLiberties) break case s.team == team: getEnemyLiberties({ position: z, team: team, checkedEnemies: checkedEnemies, checkedEnemyLiberties: checkedEnemyLiberties, }) break } }) return checkedEnemyLiberties.length }