Example #1
0
void
Module::set ( Log_Entry &e )
{
    for ( int i = 0; i < e.size(); ++i )
    {
        const char *s, *v;

        e.get( i, &s, &v );

        if ( ! strcmp( s, ":chain" ) )
        {
            /* This trickiness is because we may need to know the name of
               our chain before we actually get added to it. */
            int i;
            sscanf( v, "%X", &i );
            Chain *t = (Chain*)Loggable::find( i );

            assert( t );

            chain( t );
        }
    }

    for ( int i = 0; i < e.size(); ++i )
    {
        const char *s, *v;

        e.get( i, &s, &v );

/*         if ( ! strcmp( s, ":name" ) ) */
/*             label( v ); */
        if ( ! strcmp( s, ":parameter_values" ) )
        {
            set_parameters( v );
        }
        else if ( ! ( strcmp( s, ":is_default" ) ) )
        {
            is_default( atoi( v ) );
        }
        else if ( ! ( strcmp( s, ":active" ) ) )
        {
            bypass( ! atoi( v ) );
        }
        else if ( ! strcmp( s, ":chain" ) )
        {
            int i;
            sscanf( v, "%X", &i );
            Chain *t = (Chain*)Loggable::find( i );

            assert( t );

            t->add( this );
        }
    }
}
Example #2
0
/*
 * Updates the board with a move. Assumes that the move is legal.
 */
void Board::doMove(Player p, Move m) {
    if (m == MOVE_PASS)
        return;

    int x = getX(m);
    int y = getY(m);

    assert(pieces[index(x, y)] == EMPTY);
    assert(chainID[index(x, y)] == 0);
    
    pieces[index(x, y)] = p;
    zobristKey ^= zobristTable[zobristIndex(p, x, y)];

    Player victim = otherPlayer(p);

    Stone east = pieces[index(x+1, y)];
    Stone west = pieces[index(x-1, y)];
    Stone north = pieces[index(x, y+1)];
    Stone south = pieces[index(x, y-1)];
    int connectionCount = (east == p) + (west == p) + (north == p) + (south == p);

    // If the stone placed is a new chain
    if (connectionCount == 0) {
        // Record which chain this square is a part of
        chainID[index(x, y)] = nextID;

        // Add this chain to the list of chains
        Chain *cargo = new Chain(p, nextID);
        cargo->add(m);
        cargo->liberties = 0;
        if (east == EMPTY)
            cargo->addLiberty(coordToMove(x+1, y));
        if (west == EMPTY)
            cargo->addLiberty(coordToMove(x-1, y));
        if (north == EMPTY)
            cargo->addLiberty(coordToMove(x, y+1));
        if (south == EMPTY)
            cargo->addLiberty(coordToMove(x, y-1));

        chainList.add(cargo);

        nextID++;
    }

    // If the stone placed is added to an existing chain
    else if (connectionCount == 1) {
        // Find the ID of the chain we are adding this stone to
        int thisID;
        if (east == p)
            thisID = chainID[index(x+1, y)];
        else if (west == p)
            thisID = chainID[index(x-1, y)];
        else if (north == p)
            thisID = chainID[index(x, y+1)];
        else
            thisID = chainID[index(x, y-1)];

        chainID[index(x, y)] = thisID;
        Chain *node = nullptr;
        searchChainsByID(node, thisID);
        node->add(m);

        // The new stone occupies a previous liberty, but adds on however many
        // liberties it itself has
        node->removeLiberty(node->findLiberty(m));
        updateLiberty(node, x, y);
    }

    // If the stone possibly connects two existing chains
    else {
        int eastID = (east == p) * chainID[index(x+1, y)];
        int westID = (west == p) * chainID[index(x-1, y)];
        int northID = (north == p) * chainID[index(x, y+1)];
        int southID = (south == p) * chainID[index(x, y-1)];
        Chain *node = nullptr;
        bool added = false;

        if (eastID) {
            chainID[index(x, y)] = eastID;
            searchChainsByID(node, eastID);

            node->add(m);
            node->removeLiberty(node->findLiberty(m));
            updateLiberty(node, x, y);
            added = true;
        }

        if (westID) {
            if (added) {
                // If two stones from the same chain are adjacent, do nothing
                // If they are from different chains, we need to combine...
                if (westID != eastID)
                    mergeChains(node, westID, m);
            }
            else {
                chainID[index(x, y)] = westID;
                searchChainsByID(node, westID);

                node->add(m);
                node->removeLiberty(node->findLiberty(m));
                updateLiberty(node, x, y);
                added = true;
            }
        }

        if (northID) {
            if (added) {
                if (northID != eastID && northID != westID)
                    mergeChains(node, northID, m);
            }
            else {
                chainID[index(x, y)] = northID;
                searchChainsByID(node, northID);

                node->add(m);
                node->removeLiberty(node->findLiberty(m));
                updateLiberty(node, x, y);
                added = true;
            }
        }

        if (southID) {
            if (added) {
                if (southID != eastID && southID != westID && southID != northID)
                    mergeChains(node, southID, m);
            }
            else {
                chainID[index(x, y)] = southID;
                searchChainsByID(node, southID);

                node->add(m);
                node->removeLiberty(node->findLiberty(m));
                updateLiberty(node, x, y);
                added = true;
            }
        }
    }


    // Update opponent liberties
    int eastID = (east == victim) * chainID[index(x+1, y)];
    int westID = (west == victim) * chainID[index(x-1, y)];
    int northID = (north == victim) * chainID[index(x, y+1)];
    int southID = (south == victim) * chainID[index(x, y-1)];

    if (eastID) {
        Chain *node = nullptr;
        int nodeIndex = searchChainsByID(node, eastID);
        node->removeLiberty(node->findLiberty(m));

        if (node->liberties == 0)
            captureChain(node, nodeIndex);
    }

    if (westID && westID != eastID) {
        Chain *node = nullptr;
        int nodeIndex = searchChainsByID(node, westID);
        node->removeLiberty(node->findLiberty(m));

        if (node->liberties == 0)
            captureChain(node, nodeIndex);
    }

    if (northID && northID != eastID && northID != westID) {
        Chain *node = nullptr;
        int nodeIndex = searchChainsByID(node, northID);
        node->removeLiberty(node->findLiberty(m));

        if (node->liberties == 0)
            captureChain(node, nodeIndex);
    }

    if (southID && southID != eastID && southID != westID && southID != northID) {
        Chain *node = nullptr;
        int nodeIndex = searchChainsByID(node, southID);
        node->removeLiberty(node->findLiberty(m));

        if (node->liberties == 0)
            captureChain(node, nodeIndex);
    }

    // Check for a suicide
    int selfID = chainID[index(x, y)];
    Chain *node = nullptr;
    int nodeIndex = searchChainsByID(node, selfID);

    if (node->liberties == 0)
        captureChain(node, nodeIndex);


    // A debugging check
    assert(!checkChains());

    // Check if p captured any of the other player's stones with move m
    /*
    doCaptures<true>(victim, coordToMove(x+1, y));
    doCaptures<true>(victim, coordToMove(x-1, y));
    doCaptures<true>(victim, coordToMove(x, y+1));
    doCaptures<true>(victim, coordToMove(x, y-1));

    // Check if p suicided with move m
    doCaptures<true>(p, coordToMove(x, y));
    */
}