//magnets model
MagnetsModel.java

MagnetSpace.java

MagnetAgent.java
Magnet.java

package magnets2;
//RepastJ -> SymphonyRepast modifications are marked with //SR or /*SR ... */
import java.util.Vector;
import uchicago.src.sim.space.Object2DHexagonalGrid;

// Referenced classes of package magnets2:
//            Magnet, MagnetAgent

public class MagnetSpace
{

    public MagnetSpace(int xSize, int ySize, boolean adjacent)
    {
        fluxOld = new int[6];
        fluxOld2 = new int[12];
        maxFlux = 9;
        fluxSpace = new Object2DHexagonalGrid(xSize, ySize);
        magnetSpace = new Object2DHexagonalGrid(xSize, ySize);
        xs = xSize;
        ys = ySize;
        adj = adjacent;
        resetFlux(xSize, ySize);
    }

    public void resetFlux(int xSize, int ySize)
    {
        for(int i = 0; i < xSize; i++)
        {
            for(int j = 0; j < ySize; j++)
                fluxSpace.putObjectAt(i, j, new Integer(0));

        }

    }

    public void spreadFlux(int total)
    {
        for(int i = 0; i < total; i++)
        {
            int x = (int)(Math.random() * (double)fluxSpace.getSizeX());
            int y = (int)(Math.random() * (double)fluxSpace.getSizeY());
            int currentValue = getFluxAt(x, y);
            fluxSpace.putObjectAt(x, y, new Integer(currentValue + (int)(Math.random() * (double)maxFlux * 2D - (double)maxFlux)));
        }

    }

    public void changeFlux(int flux, int x, int y)
    {
        int currentValue = getFluxAt(x, y);
        fluxSpace.putObjectAt(x, y, new Integer(currentValue + flux));
    }

    public int getFluxAt(int x, int y)
    {
        int i;
        if(fluxSpace.getObjectAt(x, y) != null)
            i = ((Integer)fluxSpace.getObjectAt(x, y)).intValue();
        else
            i = 0;
        return i;
    }

    public Object2DHexagonalGrid getCurrentFluxSpace()
    {
        return fluxSpace;
    }

    public Object2DHexagonalGrid getCurrentMagnetAgentSpace()
    {
        return magnetSpace;
    }

    public boolean IsCellOccupied(int x, int y)
    {
        boolean retVal = false;
        if(magnetSpace.getObjectAt(x, y) != null)
            retVal = true;
        return retVal;
    }

    public boolean addAgent(MagnetAgent agent)
    {
        boolean retVal = false;
        int count = 0;
        for(int countLimit = 10 * xs * ys; !retVal && count < countLimit; count++)
        {
            int x = (int)(Math.random() * (double)(xs - 4) + 2D);
            int y = (int)(Math.random() * (double)(ys - 4) + 2D);
            if(!IsCellOccupied(x, y))
            {
                Vector nma = magnetSpace.getNeighbors(x, y, 1, false);
                if(nma.isEmpty() || adj)
                {
                    magnetSpace.putObjectAt(x, y, (Magnet)agent);
                    agent.setXY(x, y);
                    agent.setS((new StringBuilder(String.valueOf(agent.getX()))).append(" ").append(agent.getY()).toString());
                    agent.setSSpace(this);
                    int dir = agent.getDirection();
                    updateFluxRing(x, y, dir, false);
                    if(r == 2)
                        updateFluxDblRing(x, y, dir, false);
                    retVal = true;
                }
            }
        }

        return retVal;
    }

    public void updateFluxRing(int x, int y, int dir, boolean cls)
    {
        int dx = 0;
        int dy = 0;
        for(ringindex = 0; ringindex < 6; ringindex++)
        {
            flux = (int)((double)maxFlux * Math.sin(1.5707963267948966D - ((double)(ringindex - dir) * 3.1415926535897931D) / 3D));
            if(x % 2 == 0)
                switch(ringindex)
                {
                case 0: // '\0'
                    dx = 0;
                    dy = -1;
                    break;

                case 1: // '\001'
                    dx = 1;
                    dy = 0;
                    break;

                case 2: // '\002'
                    dx = 1;
                    dy = 1;
                    break;

                case 3: // '\003'
                    dx = 0;
                    dy = 1;
                    break;

                case 4: // '\004'
                    dx = -1;
                    dy = 1;
                    break;

                case 5: // '\005'
                    dx = -1;
                    dy = 0;
                    break;
                }
            else
                switch(ringindex)
                {
                case 0: // '\0'
                    dx = 0;
                    dy = -1;
                    break;

                case 1: // '\001'
                    dx = 1;
                    dy = -1;
                    break;

                case 2: // '\002'
                    dx = 1;
                    dy = 0;
                    break;

                case 3: // '\003'
                    dx = 0;
                    dy = 1;
                    break;

                case 4: // '\004'
                    dx = -1;
                    dy = 0;
                    break;

                case 5: // '\005'
                    dx = -1;
                    dy = -1;
                    break;
                }
            if(cls)
                flux = -flux;
            changeFlux(flux, x + dx, y + dy);
        }

    }

    public void updateFluxDblRing(int x, int y, int dir, boolean cls)
    {
        int dx = 0;
        int dy = 0;
        for(ringindex = 0; ringindex < 12; ringindex++)
        {
            flux = (int)((double)(int)Math.sqrt(maxFlux) * Math.sin(1.5707963267948966D - ((double)(ringindex - 2 * dir) * 3.1415926535897931D) / 6D));
            if(x % 2 == 0)
                switch(ringindex)
                {
                case 0: // '\0'
                    dx = 0;
                    dy = -2;
                    break;

                case 1: // '\001'
                    dx = 1;
                    dy = -1;
                    break;

                case 2: // '\002'
                    dx = 2;
                    dy = -1;
                    break;

                case 3: // '\003'
                    dx = 2;
                    dy = 0;
                    break;

                case 4: // '\004'
                    dx = 2;
                    dy = 1;
                    break;

                case 5: // '\005'
                    dx = 1;
                    dy = 2;
                    break;

                case 6: // '\006'
                    dx = 0;
                    dy = 2;
                    break;

                case 7: // '\007'
                    dx = -1;
                    dy = 2;
                    break;

                case 8: // '\b'
                    dx = -2;
                    dy = 1;
                    break;

                case 9: // '\t'
                    dx = -2;
                    dy = 0;
                    break;

                case 10: // '\n'
                    dx = -2;
                    dy = -1;
                    break;

                case 11: // '\013'
                    dx = -1;
                    dy = -1;
                    break;
                }
            else
                switch(ringindex)
                {
                case 0: // '\0'
                    dx = 0;
                    dy = -2;
                    break;

                case 1: // '\001'
                    dx = 1;
                    dy = -2;
                    break;

                case 2: // '\002'
                    dx = 2;
                    dy = -1;
                    break;

                case 3: // '\003'
                    dx = 2;
                    dy = 0;
                    break;

                case 4: // '\004'
                    dx = 2;
                    dy = 1;
                    break;

                case 5: // '\005'
                    dx = 1;
                    dy = 1;
                    break;

                case 6: // '\006'
                    dx = 0;
                    dy = 2;
                    break;

                case 7: // '\007'
                    dx = -1;
                    dy = 1;
                    break;

                case 8: // '\b'
                    dx = -2;
                    dy = 1;
                    break;

                case 9: // '\t'
                    dx = -2;
                    dy = 0;
                    break;

                case 10: // '\n'
                    dx = -2;
                    dy = -1;
                    break;

                case 11: // '\013'
                    dx = -1;
                    dy = -2;
                    break;
                }
            if(cls)
                flux = -flux;
            changeFlux(flux, x + dx, y + dy);
        }

    }

    public boolean moveAgentAt(int x, int y, int newX, int newY, int dir, int radius)
    {
        int directionChange = 0;
        int maxRepulsion = 0;
        int maxAttraction = 0;
        int tempRepDirection = dir;
        int tempAttDirection = dir;
        boolean atract = false;
        r = radius;
        Vector nfa = fluxSpace.getNeighbors(x, y, 1, false);
        boolean retVal = false;
        Magnet sa = (Magnet)magnetSpace.getObjectAt(x, y);
        int minSum = 0;
        for(int i = 0; i < 6; i++)
        {
            fluxOld[i] = (int)((double)maxFlux * Math.sin(1.5707963267948966D - ((double)(i - dir) * 3.1415926535897931D) / 3D));
            minSum += Math.abs(fluxOld[i]);
        }

        int cumulativeFlux = minSum;
        if(r == 2)
        {
            for(int i = 0; i < 12; i++)
            {
                fluxOld2[i] = (int)((double)(int)Math.sqrt(maxFlux) * Math.sin(1.5707963267948966D - ((double)(i - 2 * dir) * 3.1415926535897931D) / 6D));
                minSum += Math.abs(fluxOld2[i]);
            }

            cumulativeFlux += minSum;
        }
        for(int d = -3; d < 3; d++)
        {
            minSum = 0;
            for(int i = 0; i < 6; i++)
            {
                int str = Integer.parseInt(nfa.get(i).toString());
                flux = (int)((double)maxFlux * Math.sin(1.5707963267948966D - ((double)(i - (dir + d)) * 3.1415926535897931D) / 3D));
                minSum += Math.abs((str - fluxOld[i]) + flux);
            }

            if(r == 2)
            {
                Vector nfa2 = fluxSpace.getNeighbors(x, y, 2, false);
                for(int i = 0; i < 12; i++)
                {
                    int str = Integer.parseInt(nfa2.get(i).toString());
                    flux = (int)((double)(int)Math.sqrt(maxFlux) * Math.sin(1.5707963267948966D - ((double)(i - 2 * (dir + d)) * 3.1415926535897931D) / 6D));
                    minSum += Math.abs((str - fluxOld2[i]) + flux);
                }

            }
            if(minSum < cumulativeFlux)
            {
                cumulativeFlux = minSum;
                directionChange = d;
            }
        }

        updateFluxRing(x, y, sa.getDirection(), true);
        if(r == 2)
            updateFluxDblRing(x, y, sa.getDirection(), true);
        sa.setDirection((sa.getDirection() + directionChange) % 6);
        updateFluxRing(x, y, sa.getDirection(), false);
        if(r == 2)
            updateFluxDblRing(x, y, sa.getDirection(), false);
        retVal = true;
        return retVal;
    }

    public void removeAgentAt(int x, int y)
    {
        magnetSpace.putObjectAt(x, y, null);
    }

    public int getTotalFlux()
    {
        int totalFlux = 0;
        for(int i = 0; i < xs; i++)
        {
            for(int j = 0; j < ys; j++)
                totalFlux += Math.abs(getFluxAt(i, j));

        }

        return totalFlux;
    }

    public Magnet getMagnetAgentAt(int x, int y)
    {
        Magnet retVal = null;
        if(magnetSpace.getObjectAt(x, y) != null)
            retVal = (Magnet)magnetSpace.getObjectAt(x, y);
        return retVal;
    }

    private Object2DHexagonalGrid fluxSpace;
    private Object2DHexagonalGrid magnetSpace;
    private int xs;
    private int ys;
    private int flux;
    private int fluxOld[];
    private int fluxOld2[];
    private int ringindex;
    private int r;
    private int maxFlux;
    private boolean adj;
}
//