diff options
Diffstat (limited to 'src/engine/liberty.js')
-rw-r--r-- | src/engine/liberty.js | 149 |
1 files changed, 111 insertions, 38 deletions
diff --git a/src/engine/liberty.js b/src/engine/liberty.js index 6d1bbda..7ccd77d 100644 --- a/src/engine/liberty.js +++ b/src/engine/liberty.js @@ -23,38 +23,63 @@ function checkLiberties({ team, checkedStones = [], checkedLiberties = [], + checkedEnemies = [], + isAttacking = false, + isRoot = true, }) { if (isInArray(position, checkedStones)) { - return false - } - - if (checkedLiberties.length > 0) { - console.log(team, checkedLiberties) + return } checkedStones.push(position) let surroundingSquares = getSurroundingSquares(position) - findEmptySquares( - surroundingSquares, - checkedLiberties - ) + surroundingSquares.every((z) => { + let s = board.stones[z.y][z.x] + switch (true) { + case s == undefined: + pushIfNotInArray(z, checkedLiberties) + break - findFriendlyStones( - surroundingSquares, - {team, checkedStones, checkedLiberties} - ) + case s.team == team: + handleFriendlyStone({ + position: z, + team: team, + checkedStones: checkedStones, + checkedLiberties: checkedLiberties, + checkedEnemies: checkedEnemies, + isAttacking: isAttacking, + }) + break - if (checkedLiberties.length == 1 && checkedStones.length < 2) { - return true - } + case s.team != team: + if (isAttackingEnemyStone({ + position: z, + team: s.team, + checkedEnemies: checkedEnemies, + isAttacking: isAttacking, + })) { + isAttacking = true + return false + } + break + } - if (checkedLiberties.length > 1) { return true - } + }) - return false + if (isRoot) { + let liberties = checkedLiberties + .filter(x => !Vector2.equals(x, position)) + .length + + if (liberties > 0 || isAttacking) { + return true + } + + return false + } } function isInArray(position, array) { @@ -62,6 +87,12 @@ function isInArray(position, 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)) @@ -70,27 +101,69 @@ function getSurroundingSquares(position) { ) } -function findEmptySquares(surroundingSquares, checkedLiberties) { - surroundingSquares - .filter(z => board.stones[z.y][z.x] == undefined) - .forEach(z => { - if (!isInArray(z, checkedLiberties)) { - checkedLiberties.push(z) - } - }) +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 findFriendlyStones(surroundingSquares, data) { - surroundingSquares - .filter(z => board.stones[z.y][z.x] != undefined) - .filter(z => board.stones[z.y][z.x].team == data.team) +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 => { - checkLiberties({ - position: z, - team: data.team, - checkedStones: data.checkedStones, - checkedLiberties: data.checkedLiberties, - }) + 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 +} |