<commit_before>#include "board.h"

#include <assert.h>
#include <math.h>
#include <set>

inline
void calculateLocalFeaturesForBlock(
        LocalFeatureState* state,
        Block* block0,
        Block* block,
        const BoardLocation& location)
{
    if(block != block0)
    {
        state->perimeter.insert(location);
    }
    if(block->getState() == EMPTY)
    {
        state->liberties.insert(location);

        state->adjacentTerritories.insert(block);
    }
    else if(block->getState() != block0->getState())
    {
        state->opponents.insert(location);

        state->adjacentOpponentBlocks.insert(block);
    }
}

inline
void handleTerritoryMember(
        Block* block0,
        Block* block,
        const int& x,
        const int& y,
        std::set<BoardLocation>& perimeter,
        std::set<BoardLocation>& directLiberties,
        std::set<BoardLocation>& friendlyLiberties,
        std::set<BoardLocation>& enemyLiberties)
{
    if(block == block0)
    {
        BoardLocation location(x, y);

        directLiberties.insert(location);
    }
    else if(block->getState() != EMPTY)
    {
        BoardLocation location(x, y);

        perimeter.insert(location);

        if(block->getState() == block0->getState())
        {
            friendlyLiberties.insert(location);
        }
        else
        {
            enemyLiberties.insert(location);
        }
    }
}

inline
int chooseSmallestDistances(
        const int size,
        const int x,
        const int y)
{
    int dx0 = x;
    int dx1 = size - x - 1;
    int dy0 = y;
    int dy1 = size - y - 1;

    int distances[2];

    if(dx0 < dx1)
    {
        distances[0] = dx0;
        distances[1] = dx1;
    }
    else
    {
        distances[0] = dx1;
        distances[1] = dx0;
    }

    if(dy0 < distances[0])
    {
        distances[1] = distances[0];
        distances[0] = dy0;
    }
    else if(dy0 < distances[1])
    {
        distances[1] = dy0;
    }

    if(dy1 < distances[1])
    {
        return dy1 + distances[0];
    }
    else
    {
        return distances[0] + distances[1];
    }
}

void Board::handleAdjacentTerritories(
        LocalFeatureState* state,
        Block* block,
        int& CETNumberOfTerritories,
        int& CETSize,
        int& CETPerimeter,
        float& CETCenterOfMass,
        int& DTNumberOfTerritories,
        int& DTDirectLiberties,
        int& DTLibertiesOfFriendlyBlocks,
        int& DTLibertiesOfEnemyBlocks) const
{
    CETNumberOfTerritories = 0;
    CETSize = 0;
    CETPerimeter = 0;
    DTNumberOfTerritories = 0;
    DTDirectLiberties = 0;
    DTLibertiesOfFriendlyBlocks = 0;
    DTLibertiesOfEnemyBlocks = 0;

    int sum = 0;

    std::set<Block*>::const_iterator itt = state->adjacentTerritories.begin();
    std::set<Block*>::const_iterator end = state->adjacentTerritories.end();

    for( ; itt != end; ++itt)
    {
        std::set<BoardLocation> perimeter;
        std::set<BoardLocation> directLiberties;
        std::set<BoardLocation> friendlyLiberties;
        std::set<BoardLocation> enemyLiberties;

        std::set<BoardLocation>::const_iterator locationItt = (*itt)->locationsBegin();
        std::set<BoardLocation>::const_iterator locationEnd = (*itt)->locationsEnd();

        int partialSum = 0;

        for( ; locationItt != locationEnd; ++locationItt)
        {
            Block* block1 = getBlock(locationItt->x - 1, locationItt->y);
            Block* block2 = getBlock(locationItt->x, locationItt->y - 1);
            Block* block3 = getBlock(locationItt->x + 1, locationItt->y);
            Block* block4 = getBlock(locationItt->x, locationItt->y + 1);

            if(block1)
            {
                handleTerritoryMember(block, block1, locationItt->x - 1, locationItt->y,
                                      perimeter, directLiberties, friendlyLiberties,
                                      enemyLiberties);
            }
            if(block2)
            {
                handleTerritoryMember(block, block2, locationItt->x, locationItt->y - 1,
                                      perimeter, directLiberties, friendlyLiberties,
                                      enemyLiberties);
            }
            if(block3)
            {
                handleTerritoryMember(block, block3, locationItt->x + 1, locationItt->y,
                                      perimeter, directLiberties, friendlyLiberties,
                                      enemyLiberties);
            }
            if(block4)
            {
                handleTerritoryMember(block, block4, locationItt->x, locationItt->y + 1,
                                      perimeter, directLiberties, friendlyLiberties,
                                      enemyLiberties);
            }

            partialSum += chooseSmallestDistances(size, locationItt->x, locationItt->y);
        }

        if(enemyLiberties.size() == 0)
        {
            ++CETNumberOfTerritories;
            CETSize += (*itt)->getSize();
            CETPerimeter += perimeter.size();

            sum += partialSum;
        }
        else
        {
            ++DTNumberOfTerritories;
            DTDirectLiberties = directLiberties.size();
            DTLibertiesOfFriendlyBlocks = friendlyLiberties.size();
            DTLibertiesOfEnemyBlocks = enemyLiberties.size();
        }
    }

    if(CETSize)
    {
        CETCenterOfMass = sum / (2.0 * CETSize);
    }
    else
    {
        CETCenterOfMass = 0.0;
    }
}

inline
void updateCountAndPerimeter(
        Block* block0,
        Block*  block,
        const int& x,
        const int& y,
        int& count,
        int& perimeter)
{
    if(block->getState() == EMPTY && block0->touches(x, y) ||
       block->getState() != block0->getState())
    {
        ++count;
    }
<commit_msg>Fix direct, friendly, and enemy liberty calculation<commit_after>#include "board.h"

#include <assert.h>
#include <math.h>
#include <set>

inline
void calculateLocalFeaturesForBlock(
        LocalFeatureState* state,
        Block* block0,
        Block* block,
        const BoardLocation& location)
{
    if(block != block0)
    {
        state->perimeter.insert(location);
    }
    if(block->getState() == EMPTY)
    {
        state->liberties.insert(location);

        state->adjacentTerritories.insert(block);
    }
    else if(block->getState() != block0->getState())
    {
        state->opponents.insert(location);

        state->adjacentOpponentBlocks.insert(block);
    }
}

inline
void handleTerritoryMember(
        Block* block0,
        Block* block,
        const int& x,
        const int& y,
        std::set<BoardLocation>& perimeter,
        bool& directLiberty,
        bool& friendlyLiberty,
        bool& enemyLiberty)
{
    if(block == block0)
    {
        directLiberty = true;
    }
    else if(block->getState() != EMPTY)
    {
        BoardLocation location(x, y);

        perimeter.insert(location);

        if(block->getState() == block0->getState())
        {
            friendlyLiberty = true;
        }
        else
        {
            enemyLiberty = true;
        }
    }
}

inline
int chooseSmallestDistances(
        const int size,
        const int x,
        const int y)
{
    int dx0 = x;
    int dx1 = size - x - 1;
    int dy0 = y;
    int dy1 = size - y - 1;

    int distances[2];

    if(dx0 < dx1)
    {
        distances[0] = dx0;
        distances[1] = dx1;
    }
    else
    {
        distances[0] = dx1;
        distances[1] = dx0;
    }

    if(dy0 < distances[0])
    {
        distances[1] = distances[0];
        distances[0] = dy0;
    }
    else if(dy0 < distances[1])
    {
        distances[1] = dy0;
    }

    if(dy1 < distances[1])
    {
        return dy1 + distances[0];
    }
    else
    {
        return distances[0] + distances[1];
    }
}

void Board::handleAdjacentTerritories(
        LocalFeatureState* state,
        Block* block,
        int& CETNumberOfTerritories,
        int& CETSize,
        int& CETPerimeter,
        float& CETCenterOfMass,
        int& DTNumberOfTerritories,
        int& DTDirectLiberties,
        int& DTLibertiesOfFriendlyBlocks,
        int& DTLibertiesOfEnemyBlocks) const
{
    CETNumberOfTerritories = 0;
    CETSize = 0;
    CETPerimeter = 0;
    DTNumberOfTerritories = 0;
    DTDirectLiberties = 0;
    DTLibertiesOfFriendlyBlocks = 0;
    DTLibertiesOfEnemyBlocks = 0;

    int sum = 0;

    std::set<Block*>::const_iterator itt = state->adjacentTerritories.begin();
    std::set<Block*>::const_iterator end = state->adjacentTerritories.end();

    for( ; itt != end; ++itt)
    {
        std::set<BoardLocation> perimeter;

        int directLiberties = 0;
        int friendlyLiberties = 0;
        int enemyLiberties = 0;

        std::set<BoardLocation>::const_iterator locationItt = (*itt)->locationsBegin();
        std::set<BoardLocation>::const_iterator locationEnd = (*itt)->locationsEnd();

        int partialSum = 0;

        for( ; locationItt != locationEnd; ++locationItt)
        {
            Block* block1 = getBlock(locationItt->x - 1, locationItt->y);
            Block* block2 = getBlock(locationItt->x, locationItt->y - 1);
            Block* block3 = getBlock(locationItt->x + 1, locationItt->y);
            Block* block4 = getBlock(locationItt->x, locationItt->y + 1);

            bool directLiberty = false;
            bool friendlyLiberty = false;
            bool enemyLiberty = false;

            if(block1)
            {
                handleTerritoryMember(block, block1, locationItt->x - 1, locationItt->y,
                                      perimeter, directLiberty, friendlyLiberty,
                                      enemyLiberty);
            }
            if(block2)
            {
                handleTerritoryMember(block, block2, locationItt->x, locationItt->y - 1,
                                      perimeter, directLiberty, friendlyLiberty,
                                      enemyLiberty);
            }
            if(block3)
            {
                handleTerritoryMember(block, block3, locationItt->x + 1, locationItt->y,
                                      perimeter, directLiberty, friendlyLiberty,
                                      enemyLiberty);
            }
            if(block4)
            {
                handleTerritoryMember(block, block4, locationItt->x, locationItt->y + 1,
                                      perimeter, directLiberty, friendlyLiberty,
                                      enemyLiberty);
            }

            if(directLiberty)
            {
                ++directLiberties;
            }
            if(friendlyLiberty)
            {
                ++friendlyLiberties;
            }
            if(enemyLiberty)
            {
                ++enemyLiberties;
            }

            partialSum += chooseSmallestDistances(size, locationItt->x, locationItt->y);
        }

        if(enemyLiberties == 0)
        {
            ++CETNumberOfTerritories;
            CETSize += (*itt)->getSize();
            CETPerimeter += perimeter.size();

            sum += partialSum;
        }
        else
        {
            ++DTNumberOfTerritories;
            DTDirectLiberties += directLiberties;
            DTLibertiesOfFriendlyBlocks += friendlyLiberties;
            DTLibertiesOfEnemyBlocks += enemyLiberties;
        }
    }

    if(CETSize)
    {
        CETCenterOfMass = sum / (2.0 * CETSize);
    }
    else
    {
        CETCenterOfMass = 0.0;
    }
}

inline
void updateCountAndPerimeter(
        Block* block0,
        Block*  block,
        const int& x,
        const int& y,
        int& count,
        int& perimeter)
{
    if(block->getState() == EMPTY && block0->touches(x, y) ||
       block->getState() != block0->getState())
    {
        ++count;
    }

{'fraction_non_alphanumeric': 0.11006768189509306, 'fraction_numerical': 0.01311336717428088, 'mean_word_length': 1.7106168310020637, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 103, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2605994', 'n_tokens_mistral': 3686, 'n_tokens_neox': 3583, 'n_words': 656}