summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorniliara-edu <nil.jimeno@estudiant.fjaverianas.com>2024-12-18 10:08:08 +0100
committerniliara-edu <nil.jimeno@estudiant.fjaverianas.com>2024-12-18 10:08:08 +0100
commit827d1d8e533e45360ead5cbb5cab5547d2252282 (patch)
tree288bdd82c2ce0e75f98a5e69ba70dc42f16cace2
parentcd65b9535168e2bf610fd8feb2024e866d3b449d (diff)
liberty rule rebuilt
-rw-r--r--src/engine/liberty.js215
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
-}