diff options
author | niliara-edu <nil.jimeno@estudiant.fjaverianas.com> | 2024-12-18 10:08:08 +0100 |
---|---|---|
committer | niliara-edu <nil.jimeno@estudiant.fjaverianas.com> | 2024-12-18 10:08:08 +0100 |
commit | 827d1d8e533e45360ead5cbb5cab5547d2252282 (patch) | |
tree | 288bdd82c2ce0e75f98a5e69ba70dc42f16cace2 | |
parent | cd65b9535168e2bf610fd8feb2024e866d3b449d (diff) |
liberty rule rebuilt
-rw-r--r-- | src/engine/liberty.js | 215 |
1 files changed, 76 insertions, 139 deletions
diff --git a/src/engine/liberty.js b/src/engine/liberty.js index 9f2049c..7c51ae2 100644 --- a/src/engine/liberty.js +++ b/src/engine/liberty.js @@ -1,5 +1,6 @@ import { board } from "../board.js" import { Vector2 } from "../engine/vector2.js" +import { PLAYER } from "../constants.js" const SURROUNDING = [ new Vector2(-1, 0), @@ -14,20 +15,87 @@ export function hasLiberties({ }) { 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 - // }) + groups.push(position) + + let liberties = getGroupLiberties(groups) + liberties = removeIfInArray(position, liberties) + + if (liberties.length == 0) { + let enemies = getGroupSurroundingEnemies(groups, team) + let enemyLiberties = getGroupLiberties(enemies) + enemyLiberties = removeIfInArray(position, enemyLiberties) + return (enemyLiberties.length == 0) + } + + return (liberties.length > 0) } -function getSurroundingGroups(position, team) { +function removeIfInArray(value, array) { + return array.filter(x => !Vector2.equals(value, x)) +} + +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 => pushIfNotInArray(p, checkedPositions)) + ) + + return checkedPositions +} + +function getGroupSurroundingEnemies(group, playerTeam) { + if (group.length == 0) return [] + + let team = playerTeam == PLAYER.BLACK ? + PLAYER.WHITE : + PLAYER.BLACK + + 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 (isInArray(newGroup[0], partialArray)) { + return partialArray + } + + return partialArray.concat(newGroup) + }) +} + +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 (isInArray(newGroup[0], partialArray)) { + return partialArray + } + + return partialArray.concat(newGroup) + }) } function getGroup({position, checkedPositions = []}) { @@ -55,70 +123,6 @@ 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)) @@ -137,70 +141,3 @@ function getSurroundingSquares(position) { 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 -} |