summaryrefslogtreecommitdiff
path: root/src/worm.cpp
blob: 31be54de7aa2640996e556fb30f27bc94c2cdf66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "worm.h"
#include "map.h"
#include "cell.h"

#include <stdlib.h>

Worm::Worm( int iId, const Position &rpStart, Map &rMap ) :
    iId( iId ),
    pCur( rpStart ),
    rMap( rMap ),
    iDist( 1 )
{
    Cell &rCur = rMap[pCur];
    rCur.iDist = iDist;
    rCur.iPath = iId;

    int iCount = 0;
    int *iDirs = new int[2];
    if( pCur[0] == 0 )
        iDirs[iCount++] = 1;
    else if( pCur[0] == rMap.getSize(0)-1 )
        iDirs[iCount++] = 2;
    if( pCur[1] == 0 )
        iDirs[iCount++] = 4;
    else if( pCur[1] == rMap.getSize(1)-1 )
        iDirs[iCount++] = 8;

    rCur.iWalls |= iDirs[rand()%iCount];
    delete[] iDirs;
}

Worm::~Worm()
{
}

int opposite( int iDir )
{
    if( iDir%2 == 1 )
        return iDir-1;
    return iDir+1;
}

bool Worm::timestep()
{
    int iDims = rMap.getDims();
    int iCount = 0;
    Position *pDirs = new Position[iDims*2];
    int *iDirs = new int[iDims*2];

    for(;;)
    {
        iCount = 0;
        bool bFoundBack = false;
        Position pBack;
        for( int j = 0; j < iDims; j++ )
        {
            int iSize = rMap.getSize( j );
            Position p1( pCur );
            p1[j]--;
            if( p1[j] >= 0 )
            {
                if( rMap[p1].iPath == 0 )
                {
                    iDirs[iCount] = j*2;
                    pDirs[iCount++] = p1;
                }
                else if( rMap[p1].iPath == iId && rMap[p1].iDist == iDist-1 )
                {
                    pBack = p1;
                    bFoundBack = true;
                }
            }
            Position p2( pCur );
            p2[j]++;
            if( p2[j] < iSize )
            {
                if( rMap[p2].iPath == 0 )
                {
                    iDirs[iCount] = j*2+1;
                    pDirs[iCount++] = p2;
                }
                else if( rMap[p2].iPath == iId && rMap[p2].iDist == iDist-1 )
                {
                    pBack = p2;
                    bFoundBack = true;
                }
            }
        }

        if( iCount > 0 )
        {
            break;
        }
        else
        {
            if( bFoundBack )
            {
                pCur = pBack;
                iDist--;
            }
            else
            {
                delete[] pDirs;
                delete[] iDirs;
                return false;
            }
        }
    }

    int iSel = rand()%iCount;
    Cell &rCur = rMap[pCur];
    rCur.iWalls |= (1<<iDirs[iSel]);
    Cell &rNext = rMap[pDirs[iSel]];
    rNext.iWalls |= (1<<opposite(iDirs[iSel]));
    rNext.iDist = ++iDist;
    rNext.iPath = iId;
    pCur = pDirs[iSel];

    delete[] pDirs;
    delete[] iDirs;

    return true;
}