From 88f7691e030f77c9d6c8dc6499259502ebd03d90 Mon Sep 17 00:00:00 2001 From: simsim314 Date: Sat, 20 Dec 2014 23:10:24 +0200 Subject: [PATCH] Automated emitted gliders recognition added. Small bug fix in iterator - for edge cases. Unit test added, and code adapted to use the new automated glider removal feature. --- LifeAPI.h | 1158 ++++++++++++++++++++++++++++------------------------ UnitTest.c | 54 ++- 2 files changed, 670 insertions(+), 542 deletions(-) diff --git a/LifeAPI.h b/LifeAPI.h index f8ce1a7..50f0145 100644 --- a/LifeAPI.h +++ b/LifeAPI.h @@ -177,7 +177,7 @@ void ExpandMinMax(int* min, int* max) *min = *min - 2; *max = *max + 2; - if(*min < 0 || *max >= N) + if(*min <= 0 || *max >= N - 1) { (*min) = 0; (*max) = N - 1; @@ -425,88 +425,6 @@ int AllOff(LifeState* spark) } - -void IterateState(LifeState *lifstate) -{ - uint64_t* state = lifstate->state; - int min = lifstate->min; - int max = lifstate->max; - - uint64_t tempxor[N]; - uint64_t tempand[N]; - - uint64_t tempState[N]; - - uint64_t l, r, temp; - uint64_t x0, r0, xU, aU, xB, aB; - uint64_t a0,a1,a2,c, b0, b1, b2; - - int i, idxU, idxB; - - for(i = min; i <= max; i++) - { - temp = state[i]; - l = CirculateLeft(temp); - r = CirculateRight(temp); - tempxor[i] = l ^ r ^ temp; - tempand[i] = ((l | r) & temp) | (l & r); - } - - for(i = min; i <= max; i++) - { - if(i == 0) - idxU = N - 1; - else - idxU = i - 1; - - if(i == N - 1) - idxB = 0; - else - idxB = i + 1; - - temp = state[i]; - - x0 = tempxor[i]; - r0 = tempand[i]; - - xU = tempxor[idxU]; - aU = tempand[idxU]; - - xB = tempxor[idxB]; - aB = tempand[idxB]; - - a0 = x0^xU; - c = (x0&xU); - a1 = c^aU^r0; - a2 = (aU&r0)|((aU|r0)&c); - - b0 = xB^a0; - c = (xB&a0); - b1 = c^aB^a1; - b2 = (aB&a1)|((aB|a1)&c); - - tempState[i] = (b0&b1&(~b2)&(~a2))|((temp)&(a2^b2)&(~b0)&(~b1)); - - } - - int s = min + 1; - int e = max - 1; - - if(s == 1) - s = 0; - - if(e == N - 2) - e = N - 1; - - for(i = s; i <= e; i++) - { - state[i] = tempState[i]; - } - - RefitMinMax(lifstate); - lifstate->gen++; -} - void Reverse(uint64_t *state, int idxS, int idxE) { for(int i = 0; idxS + i < idxE - i; i++) @@ -607,6 +525,41 @@ void Transform(LifeState* state, int dx, int dy) Move(state, dx, dy); } + +void GetBoundary(LifeState* state, LifeState* boundary) +{ + for(int i = 0; i < N; i++) { + uint64_t col = state->state[i]; + Temp->state[i] = col | CirculateLeft(col) | CirculateRight(col); + } + + boundary->state[0] = Temp->state[N-1] | Temp->state[0] | Temp->state[1]; + + for(int i = 1; i < N-1; i++) + boundary->state[i] = Temp->state[i-1] | Temp->state[i] | Temp->state[i+1]; + + boundary->state[N-1] = Temp->state[N-2] | Temp->state[N-1] | Temp->state[0]; + + for(int i = 0; i < N; i++) + boundary->state[i] &= ~(state->state[i]); +} + +void GetBoundary(LifeState* state, int captureIdx) +{ + GetBoundary(state, Captures[captureIdx]); +} + +void GetBoundary(LifeState* boundary) +{ + GetBoundary(GlobalState, boundary); +} + +void GetBoundary(int captureIdx) +{ + GetBoundary(GlobalState, Captures[captureIdx]); +} + + int Parse(LifeState* state, const char* rle, int starti) { char ch; @@ -711,115 +664,539 @@ int Parse(LifeState* state, const char* rle, int dx, int dy, int dxx, int dxy, i } -LifeState* NewState(const char* rle, int dx, int dy, int dxx, int dxy, int dyx, int dyy) + +typedef struct { - LifeState* result = NewState(); - Parse(result, rle); - Transform(result, dx, dy, dxx, dxy, dyx, dyy); + LifeState* wanted; + LifeState* unwanted; - return result; -} +} LifeTarget; -LifeState* NewState(const char* rle, int dx, int dy) +LifeTarget* NewTarget(LifeState* wanted, LifeState* unwanted) { - LifeState* result = NewState(); - Parse(result, rle, dx, dy); + LifeTarget* result = (LifeTarget*)(malloc(sizeof(LifeTarget))); + + result->wanted = NewState(); + result->unwanted = NewState(); + + Copy(result->wanted, wanted); + Copy(result->unwanted, unwanted); + + RecalculateMinMax(result->wanted); + RecalculateMinMax(result->unwanted); return result; } -LifeState* NewState(const char* rle) + + +LifeTarget* NewTarget(LifeState* wanted) { - return NewState(rle, 0, 0); + GetBoundary(wanted, Temp1); + return NewTarget(wanted, Temp1); } -const char* GetRLE(LifeState *state) + +LifeTarget* NewTarget(const char* rle, int x, int y, int dxx, int dxy, int dyx, int dyy) { - LifeString* result = NewString(); + int result = Parse(Temp2, rle, x, y, dxx, dxy, dyx, dyy); - int eol_count = 0; - - for(int j = 0; j < N; j++) + if(result == SUCCESS) { - int last_val = -1; - int run_count = 0; - - for(int i = 0; i < N; i++) - { - int val = Get(i, j, state->state); - - // Flush linefeeds if we find a live cell - if(val == 1 && eol_count > 0) - { - if(eol_count > 1) - Append(result, eol_count); - - Append(result, "$"); - - eol_count = 0; - } - - // Flush current run if val changes - if (val == 1 - last_val) - { - if(run_count > 1) - Append(result, run_count); - - Append(result, last_val ? "o" : "b"); - - run_count = 0; - } - - run_count++; - last_val = val; - } - - // Flush run of live cells at end of line - if (last_val == 1) - { - if(run_count > 1) - Append(result, run_count); - - Append(result, "o"); - - run_count = 0; - } - - eol_count++; + return NewTarget(Temp2); } - - return result->value; + + return NULL; } -void PrintRLE(LifeState *state) +LifeTarget* NewTarget(const char* rle, int x, int y) { - printf("x = 0, y = 0, rule = B3/S23\n%s!\n\n", GetRLE(state)); + int result = Parse(Temp2, rle, x, y); + + if(result == SUCCESS) + { + return NewTarget(Temp2); + } + + return NULL; } -void Print() +LifeTarget* NewTarget(const char* rle) { - Print(GlobalState); + return NewTarget(rle, 0, 0); } -void Print(int idx) + +typedef struct { - Print(Captures[idx]); -} + int* xList; + int* yList; + int len; + int allocated; +} Locator; -void PrintRLE() +Locator* NewLocator() { - PrintRLE(GlobalState); + Locator* result = (Locator*)(malloc(sizeof(Locator))); + + result->xList = (int*)(malloc(sizeof(int))); + result->yList = (int*)(malloc(sizeof(int))); + result->len = 0; + result->allocated = 1; + + return result; } -void PrintRLE(int idx) +Locator* Realloc(Locator* locator) { - PrintRLE(Captures[idx]); + if(locator->allocated <= locator->len) + { + locator->allocated *= 2; + locator->xList = (int*)(realloc(locator->xList, locator->allocated * sizeof(int))); + locator->yList = (int*)(realloc(locator->yList, locator->allocated * sizeof(int))); + } } -void Evolve(LifeState* state, int numIters) +void Add(Locator* locator, int x, int y) { - for(int i = 0; i < numIters; i++) + Realloc(locator); + + locator->xList[locator->len] = x; + locator->yList[locator->len] = y; + locator->len++; +} + +Locator *State2Locator(LifeState* state) +{ + Locator* result = NewLocator(); + + for(int j = 0; j < N; j++) + { + for(int i = 0; i < N; i++) + { + int val = Get(i, j, state->state); + + if(val == 1) + Add(result, i, j); + } + } + + return result; +} + +void ClearAtX(LifeState* state, Locator* locator, int x, uint64_t val) +{ + if(val == 0ULL) + return; + + int len = locator->len; + int* xList = locator->xList; + int* yList = locator->yList; + + for(int i = 0; i < len; i++) + { + int idx = (x + xList[i] + N) % N; + int circulate = (yList[i] + 64) % 64; + + state->state[idx] &= ~CirculateLeft(val, circulate); + } +} + +uint64_t LocateAtX(LifeState* state, Locator* locator, int x, int negate) +{ + uint64_t result = ~0ULL; + int len = locator->len; + int* xList = locator->xList; + int* yList = locator->yList; + + for(int i = 0; i < len; i++) + { + int idx = (x + xList[i] + N) % N; + int circulate = (yList[i] + 64) % 64; + + if(negate == NO) + result &= CirculateRight(state->state[idx], circulate); + else + result &= ~CirculateRight(state->state[idx],circulate); + + if(result == 0ULL) + break; + } + + + return result; +} + +uint64_t LocateAtX(LifeState* state, Locator* onLocator, Locator* offLocator, int x) +{ + uint64_t onLocate = LocateAtX(state, onLocator, x, NO); + + if(onLocate == 0) + return 0; + + return onLocate & LocateAtX(state, offLocator, x, YES); +} + +void LocateInRange(LifeState* state, Locator* locator, LifeState* result, int minx, int maxx, int negate) +{ + for(int i = minx; i<= maxx; i++) + { + result->state[i] = LocateAtX(state, locator, i, negate); + } +} + +void LocateInRange(LifeState* state, Locator* onLocator, Locator* offLocator, LifeState* result, int minx, int maxx) +{ + for(int i = minx; i<= maxx; i++) + { + result->state[i] = LocateAtX(state, onLocator, offLocator, i); + } +} + +void Locate(LifeState* state, Locator* locator, LifeState* result) +{ + LocateInRange(state, locator, result, state->min, state->max, NO); +} + + +int Contains(LifeState* state, LifeTarget* target) +{ + if(Contains(state, target->wanted) == YES && AreDisjoint(state, target->unwanted) == YES) + return YES; + else + return NO; +} + +int Contains(LifeTarget* target) +{ + return Contains(GlobalState, target); +} + +void FreeTarget(LifeTarget* iter) +{ + free(iter -> wanted); + free(iter -> unwanted); + + free(iter); +} + + +typedef struct +{ + Locator* onLocator; + Locator* offLocator; +} TargetLocator; + + +TargetLocator* NewTargetLocator() +{ + TargetLocator* result = (TargetLocator*)(malloc(sizeof(TargetLocator))); + + result->onLocator = NewLocator(); + result->offLocator = NewLocator(); + + return result; +} + + +TargetLocator* Target2Locator(LifeTarget* target) +{ + TargetLocator* result = (TargetLocator*)(malloc(sizeof(TargetLocator))); + result->onLocator = State2Locator(target->wanted); + result->offLocator = State2Locator(target->unwanted); + + return result; +} + +TargetLocator* NewTargetLocator(const char* rle) +{ + TargetLocator* result = Target2Locator(NewTarget(rle, -32, -32)); + return result; +} + + +TargetLocator* NewTargetLocator(const char* rle, int x, int y) +{ + TargetLocator* result = Target2Locator(NewTarget(rle, -32 + x, -32 + y)); + return result; +} + + +uint64_t LocateAtX(LifeState* state, TargetLocator* targetLocator, int x) +{ + return LocateAtX(state, targetLocator->onLocator, targetLocator->offLocator, x); +} + +void LocateInRange(LifeState* state, TargetLocator* targetLocator, LifeState* result, int minx, int maxx) +{ + return LocateInRange(state, targetLocator->onLocator, targetLocator->offLocator, result, minx, maxx); +} + +void LocateTarget(LifeState* state, TargetLocator* targetLocator, LifeState* result) +{ + LocateInRange(state, targetLocator, result, state->min, state->max); +} + +void LocateTarget(TargetLocator* targetLocator, LifeState* result) +{ + LocateTarget(GlobalState, targetLocator, result); +} + +static TargetLocator* _glidersTarget[4]; + + +int RemoveAtX(LifeState *state, int x, int startGiderIdx) +{ + int removed = NO; + + for(int i = startGiderIdx; i < startGiderIdx + 2; i++) + { + uint64_t gld = LocateAtX(state, _glidersTarget[i], x); + + if(gld != 0) + { + removed = YES; + ClearAtX(state, _glidersTarget[i]->onLocator, x, gld); + + for(int j = 0; j < 64; j++) + { + if(gld % 2 == 1) + { + Append(state->emittedGliders, "("); + Append(state->emittedGliders, i); + Append(state->emittedGliders, ","); + Append(state->emittedGliders, j); + Append(state->emittedGliders, ","); + Append(state->emittedGliders, state->gen); + Append(state->emittedGliders, ","); + Append(state->emittedGliders, x); + Append(state->emittedGliders, ")"); + } + + gld = gld >> 1; + + if(gld == 0) + break; + } + } + } + + return removed; +} + + +void RemoveGliders(LifeState *state) +{ + int removed = NO; + int x = 1; + + if(state->min <= 1) + if(RemoveAtX(state, 1, 0) == YES) + removed = YES; + + if(state->max >= N - 2) + if(RemoveAtX(state, N - 2, 2) == YES) + removed = YES; + + if(removed == YES) + RecalculateMinMax(state); +} + +void IterateState(LifeState *lifstate) +{ + uint64_t* state = lifstate->state; + int min = lifstate->min; + int max = lifstate->max; + + uint64_t tempxor[N]; + uint64_t tempand[N]; + + uint64_t tempState[N]; + + uint64_t l, r, temp; + uint64_t x0, r0, xU, aU, xB, aB; + uint64_t a0,a1,a2,c, b0, b1, b2; + + int i, idxU, idxB; + + for(i = min; i <= max; i++) + { + temp = state[i]; + l = CirculateLeft(temp); + r = CirculateRight(temp); + tempxor[i] = l ^ r ^ temp; + tempand[i] = ((l | r) & temp) | (l & r); + } + + for(i = min; i <= max; i++) + { + if(i == 0) + idxU = N - 1; + else + idxU = i - 1; + + if(i == N - 1) + idxB = 0; + else + idxB = i + 1; + + temp = state[i]; + + x0 = tempxor[i]; + r0 = tempand[i]; + + xU = tempxor[idxU]; + aU = tempand[idxU]; + + xB = tempxor[idxB]; + aB = tempand[idxB]; + + a0 = x0^xU; + c = (x0&xU); + a1 = c^aU^r0; + a2 = (aU&r0)|((aU|r0)&c); + + b0 = xB^a0; + c = (xB&a0); + b1 = c^aB^a1; + b2 = (aB&a1)|((aB|a1)&c); + + tempState[i] = (b0&b1&(~b2)&(~a2))|((temp)&(a2^b2)&(~b0)&(~b1)); + + } + + int s = min + 1; + int e = max - 1; + + if(s == 1) + s = 0; + + if(e == N - 2) + e = N - 1; + + for(i = s; i <= e; i++) + { + state[i] = tempState[i]; + } + + RefitMinMax(lifstate); + lifstate->gen++; + +} + + +LifeState* NewState(const char* rle, int dx, int dy, int dxx, int dxy, int dyx, int dyy) +{ + LifeState* result = NewState(); + Parse(result, rle); + Transform(result, dx, dy, dxx, dxy, dyx, dyy); + + return result; +} + +LifeState* NewState(const char* rle, int dx, int dy) +{ + LifeState* result = NewState(); + Parse(result, rle, dx, dy); + + return result; +} + +LifeState* NewState(const char* rle) +{ + return NewState(rle, 0, 0); +} + +const char* GetRLE(LifeState *state) +{ + LifeString* result = NewString(); + + int eol_count = 0; + + for(int j = 0; j < N; j++) + { + int last_val = -1; + int run_count = 0; + + for(int i = 0; i < N; i++) + { + int val = Get(i, j, state->state); + + // Flush linefeeds if we find a live cell + if(val == 1 && eol_count > 0) + { + if(eol_count > 1) + Append(result, eol_count); + + Append(result, "$"); + + eol_count = 0; + } + + // Flush current run if val changes + if (val == 1 - last_val) + { + if(run_count > 1) + Append(result, run_count); + + Append(result, last_val ? "o" : "b"); + + run_count = 0; + } + + run_count++; + last_val = val; + } + + // Flush run of live cells at end of line + if (last_val == 1) + { + if(run_count > 1) + Append(result, run_count); + + Append(result, "o"); + + run_count = 0; + } + + eol_count++; + } + + return result->value; +} + +void PrintRLE(LifeState *state) +{ + printf("x = 0, y = 0, rule = B3/S23\n%s!\n\n", GetRLE(state)); +} + +void Print() +{ + Print(GlobalState); +} + +void Print(int idx) +{ + Print(Captures[idx]); +} + +void PrintRLE() +{ + PrintRLE(GlobalState); +} + +void PrintRLE(int idx) +{ + PrintRLE(Captures[idx]); +} + +void Evolve(LifeState* state, int numIters) +{ + for(int i = 0; i < numIters; i++) + { IterateState(state); + RemoveGliders(state); + } } void Evolve(LifeState* after, LifeState* before, int numIters) @@ -872,11 +1249,19 @@ void New() { Captures[i] = NewState(); } + + _glidersTarget[0] = NewTargetLocator("2o$obo$o!"); + _glidersTarget[1] = NewTargetLocator("o$obo$2o!"); + _glidersTarget[2] = NewTargetLocator("b2o$obo$2bo!", -2, 0); + _glidersTarget[3] = NewTargetLocator("2bo$obo$b2o!", -2, 0); + } else { ClearData(GlobalState); } + + } void Capture(LifeState* cap, int idx) @@ -935,11 +1320,10 @@ void PutState(int idx) void PutState(LifeState* state, int dx, int dy, int dxx, int dxy, int dyx, int dyy) { - ClearData(Temp); - Copy(Temp, state); - Transform(Temp, dx, dy, dxx, dxy, dyx, dyy); - - PutState(Temp); + ClearData(Temp1); + Copy(Temp1, state); + Transform(Temp1, dx, dy, dxx, dxy, dyx, dyy); + PutState(Temp1); } void PutState(LifeState* state, CopyType op) @@ -1174,216 +1558,101 @@ int Next(LifeIterator *iter1, LifeIterator *iter2, LifeIterator *iter3, LifeIter } int Next(LifeIterator *iter1[], int numIters) -{ - return Next(iter1, numIters, YES); -} - -void FreeIterator(LifeIterator* iter) -{ - for(int i = 0; i < iter->s; i++) - free(iter->States[i]); - - free(iter); -} - -void Join(LifeState* state, LifeIterator* iter) -{ - Join(state, iter->States[iter -> curs], iter->curx, iter->cury); -} - -void PutState(LifeIterator* iter) -{ - Join(GlobalState, iter->States[iter -> curs], iter->curx, iter->cury); -} - -void SetCurrent(LifeIterator* iter, int curx, int cury, int curs) -{ - iter -> curx = curx; - iter -> cury = cury; - iter -> curs = curs; -} - -int Validate(LifeIterator *iter1, LifeIterator *iter2) -{ - if(!(iter1->curx >= iter2->x && iter1->curx < iter2->x + iter2->w)) - return SUCCESS; - - if(!(iter1->cury >= iter2->y && iter1->cury < iter2->y + iter2->h)) - return SUCCESS; - - if(!(iter2->curx >= iter1->x && iter2->curx < iter1->x + iter1->w)) - return SUCCESS; - - if(!(iter2->cury >= iter1->y && iter2->cury < iter1->y + iter1->h)) - return SUCCESS; - - if(iter1->curx != iter2->curx) - { - if((iter1->curx + iter2->curx) % 2 == 0) - { - if(iter1->curx > iter2->curx) - return SUCCESS; - else - return FAIL; - } - else - { - if(iter1->curx > iter2->curx) - return FAIL; - else - return SUCCESS; - } - } - - if(iter1->cury != iter2->cury) - { - if((iter1->cury + iter2->cury) % 2 == 0) - { - if(iter1->cury > iter2->cury) - return SUCCESS; - else - return FAIL; - } - else - { - if(iter1->cury > iter2->cury) - return FAIL; - else - return SUCCESS; - } - } - - if((iter1->curs + iter2->curs) % 2 == 0) - { - if(iter1->curs > iter2->curs) - return SUCCESS; - else - return FAIL; - } - else - { - if(iter1->curs > iter2->curs) - return FAIL; - else - return SUCCESS; - } - - return SUCCESS; -} - -void GetBoundary(LifeState* state, LifeState* boundary) -{ - for(int i = 0; i < N; i++) { - uint64_t col = state->state[i]; - Temp->state[i] = col | CirculateLeft(col) | CirculateRight(col); - } - - boundary->state[0] = Temp->state[N-1] | Temp->state[0] | Temp->state[1]; - - for(int i = 1; i < N-1; i++) - boundary->state[i] = Temp->state[i-1] | Temp->state[i] | Temp->state[i+1]; - - boundary->state[N-1] = Temp->state[N-2] | Temp->state[N-1] | Temp->state[0]; - - for(int i = 0; i < N; i++) - boundary->state[i] &= ~(state->state[i]); -} - -void GetBoundary(LifeState* state, int captureIdx) -{ - GetBoundary(state, Captures[captureIdx]); -} - -void GetBoundary(LifeState* boundary) -{ - GetBoundary(GlobalState, boundary); -} - -void GetBoundary(int captureIdx) -{ - GetBoundary(GlobalState, Captures[captureIdx]); -} - -typedef struct -{ - LifeState* wanted; - LifeState* unwanted; - -} LifeTarget; - -LifeTarget* NewTarget(LifeState* wanted, LifeState* unwanted) -{ - LifeTarget* result = (LifeTarget*)(malloc(sizeof(LifeTarget))); - - result->wanted = NewState(); - result->unwanted = NewState(); - - Copy(result->wanted, wanted); - Copy(result->unwanted, unwanted); - - RecalculateMinMax(result->wanted); - RecalculateMinMax(result->unwanted); - - return result; -} - - - -LifeTarget* NewTarget(LifeState* wanted) -{ - GetBoundary(wanted, Temp1); - return NewTarget(wanted, Temp1); -} - - -LifeTarget* NewTarget(const char* rle, int x, int y, int dxx, int dxy, int dyx, int dyy) -{ - int result = Parse(Temp2, rle, x, y, dxx, dxy, dyx, dyy); - - if(result == SUCCESS) - { - return NewTarget(Temp2); - } - - return NULL; -} - -LifeTarget* NewTarget(const char* rle, int x, int y) -{ - int result = Parse(Temp2, rle, x, y); - - if(result == SUCCESS) - { - return NewTarget(Temp2); - } - - return NULL; +{ + return Next(iter1, numIters, YES); } -LifeTarget* NewTarget(const char* rle) +void FreeIterator(LifeIterator* iter) { - return NewTarget(rle, 0, 0); + for(int i = 0; i < iter->s; i++) + free(iter->States[i]); + + free(iter); } -int Contains(LifeState* state, LifeTarget* target) +void Join(LifeState* state, LifeIterator* iter) { - if(Contains(state, target->wanted) == YES && AreDisjoint(state, target->unwanted) == YES) - return YES; - else - return NO; + Join(state, iter->States[iter -> curs], iter->curx, iter->cury); } -int Contains(LifeTarget* target) +void PutState(LifeIterator* iter) { - return Contains(GlobalState, target); + Join(GlobalState, iter->States[iter -> curs], iter->curx, iter->cury); } -void FreeTarget(LifeTarget* iter) +void SetCurrent(LifeIterator* iter, int curx, int cury, int curs) { - free(iter -> wanted); - free(iter -> unwanted); + iter -> curx = curx; + iter -> cury = cury; + iter -> curs = curs; +} + +int Validate(LifeIterator *iter1, LifeIterator *iter2) +{ + if(!(iter1->curx >= iter2->x && iter1->curx < iter2->x + iter2->w)) + return SUCCESS; - free(iter); + if(!(iter1->cury >= iter2->y && iter1->cury < iter2->y + iter2->h)) + return SUCCESS; + + if(!(iter2->curx >= iter1->x && iter2->curx < iter1->x + iter1->w)) + return SUCCESS; + + if(!(iter2->cury >= iter1->y && iter2->cury < iter1->y + iter1->h)) + return SUCCESS; + + if(iter1->curx != iter2->curx) + { + if((iter1->curx + iter2->curx) % 2 == 0) + { + if(iter1->curx > iter2->curx) + return SUCCESS; + else + return FAIL; + } + else + { + if(iter1->curx > iter2->curx) + return FAIL; + else + return SUCCESS; + } + } + + if(iter1->cury != iter2->cury) + { + if((iter1->cury + iter2->cury) % 2 == 0) + { + if(iter1->cury > iter2->cury) + return SUCCESS; + else + return FAIL; + } + else + { + if(iter1->cury > iter2->cury) + return FAIL; + else + return SUCCESS; + } + } + + if((iter1->curs + iter2->curs) % 2 == 0) + { + if(iter1->curs > iter2->curs) + return SUCCESS; + else + return FAIL; + } + else + { + if(iter1->curs > iter2->curs) + return FAIL; + else + return SUCCESS; + } + + return SUCCESS; } typedef struct @@ -1490,170 +1759,3 @@ LifeResults* LoadResults(const char* filePath) return results; } -typedef struct -{ - int* xList; - int* yList; - int len; - int allocated; -} Locator; - -Locator* NewLocator() -{ - Locator* result = (Locator*)(malloc(sizeof(Locator))); - - result->xList = (int*)(malloc(sizeof(int))); - result->yList = (int*)(malloc(sizeof(int))); - result->len = 0; - result->allocated = 1; - - return result; -} - -Locator* Realloc(Locator* locator) -{ - if(locator->allocated <= locator->len) - { - locator->allocated *= 2; - locator->xList = (int*)(realloc(locator->xList, locator->allocated * sizeof(int))); - locator->yList = (int*)(realloc(locator->yList, locator->allocated * sizeof(int))); - } -} - -void Add(Locator* locator, int x, int y) -{ - Realloc(locator); - - locator->xList[locator->len] = x; - locator->yList[locator->len] = y; - locator->len++; -} - -Locator *State2Locator(LifeState* state) -{ - Locator* result = NewLocator(); - - for(int j = 0; j < N; j++) - { - for(int i = 0; i < N; i++) - { - int val = Get(i, j, state->state); - - if(val == 1) - Add(result, i, j); - } - } - - return result; -} - -uint64_t LocateAtX(LifeState* state, Locator* locator, int x, int negate) -{ - uint64_t result = ~0ULL; - int len = locator->len; - int* xList = locator->xList; - int* yList = locator->yList; - - for(int i = 0; i < len; i++) - { - int idx = (x + xList[i] + N) % N; - - int circulate = yList[i]; - - if(negate == NO) - result &= CirculateRight(state->state[idx], circulate); - else - result &= ~CirculateRight(state->state[idx], circulate); - - if(result == 0ULL) - break; - } - - - return result; -} - -uint64_t LocateAtX(LifeState* state, Locator* onLocator, Locator* offLocator, LifeState* result, int x) -{ - uint64_t onLocate = LocateAtX(state, onLocator, x, NO); - - if(onLocate == 0) - return 0; - - return onLocate & LocateAtX(state, offLocator, x, YES); -} - -void LocateInRange(LifeState* state, Locator* locator, LifeState* result, int minx, int maxx, int negate) -{ - for(int i = minx; i<= maxx; i++) - { - result->state[i] = LocateAtX(state, locator, i, negate); - } -} - -void LocateInRange(LifeState* state, Locator* onLocator, Locator* offLocator, LifeState* result, int minx, int maxx) -{ - for(int i = minx; i<= maxx; i++) - { - result->state[i] = LocateAtX(state, onLocator, offLocator, result, i); - } -} - -void Locate(LifeState* state, Locator* locator, LifeState* result) -{ - LocateInRange(state, locator, result, state->min, state->max, NO); -} - -typedef struct -{ - Locator* onLocator; - Locator* offLocator; -} TargetLocator; - - -TargetLocator* NewTargetLocator() -{ - TargetLocator* result = (TargetLocator*)(malloc(sizeof(TargetLocator))); - - result->onLocator = NewLocator(); - result->offLocator = NewLocator(); - - return result; -} - - -TargetLocator* Target2Locator(LifeTarget* target) -{ - TargetLocator* result = (TargetLocator*)(malloc(sizeof(TargetLocator))); - result->onLocator = State2Locator(target->wanted); - result->offLocator = State2Locator(target->unwanted); - - return result; -} - -TargetLocator* NewTargetLocator(const char* rle) -{ - TargetLocator* result = Target2Locator(NewTarget(rle, -32, -32)); - return result; -} - -uint64_t LocateAtX(LifeState* state, TargetLocator* targetLocator, LifeState* result, int x) -{ - return LocateAtX(state, targetLocator->onLocator, targetLocator->offLocator, result, x); -} - -void LocateInRange(LifeState* state, TargetLocator* targetLocator, LifeState* result, int minx, int maxx) -{ - return LocateInRange(state, targetLocator->onLocator, targetLocator->offLocator, result, minx, maxx); -} - -void LocateTarget(LifeState* state, TargetLocator* targetLocator, LifeState* result) -{ - LocateInRange(state, targetLocator, result, state->min, state->max); -} - -void LocateTarget(TargetLocator* targetLocator, LifeState* result) -{ - LocateTarget(GlobalState, targetLocator, result); -} - diff --git a/UnitTest.c b/UnitTest.c index 4162d2e..50966c7 100644 --- a/UnitTest.c +++ b/UnitTest.c @@ -16,6 +16,22 @@ int Assert(int counter, int expected, const char* testName) } } +int Assert(char* counter, char* expected, const char* testName) +{ + if(strcmp(counter, expected) != 0) + { + printf("\n\n %s Failed :(\n", testName); + return FAIL; + } + else + { + printf("\n\n %s Succeeded!!\n", testName); + + return SUCCESS; + } +} + + int Test1() { @@ -48,20 +64,12 @@ int Test1() if(pop != GetPop()) continue; - //Just iterate - the glider will run all over tha place - we're on torus anyway - Run(180); + //Just iterate - the glider will run all over the place - we're on torus anyway + Run(200); - //potential glider - if(GetPop() == 5) + if(GetPop() == 0 && strlen(GlobalState->emittedGliders->value) > 0) { - int min = GlobalState->min; - int max = GlobalState->max; - - //evolve - Run(16); - - if(GetPop() == 5 && !(min == GlobalState->min && max == GlobalState->max)) - counter++; + counter++; } } while(Next(blckiter1, glditer, NO) == SUCCESS); @@ -192,8 +200,6 @@ int Test5() } - - int Test6() { printf("\n Save-Load Results test"); @@ -233,6 +239,23 @@ int Test7() return (Assert(GetCell(result, 0, 0) * GetCell(result, 10, 10), 1, "Test7") == SUCCESS); } +int Test8() +{ + printf("\n Gliders removal basic"); + + LifeState* pat = NewState("3o$o$bo!"); + + New(); + PutState(pat); + PutState(pat, 15, 6, -1, 0, 0, 1); + PutState(pat, 12, 17, -1, 0, 0, -1); + PutState(pat, -13, 11, 1, 0, 0, -1); + Run(150); + + return (Assert(GlobalState->emittedGliders->value, "(2,22,62,62)(1,60,74,1)(3,2,74,62)(0,0,126,1)", "Test8") == SUCCESS); +} + + int RunTests() { int result = SUCCESS; @@ -255,6 +278,9 @@ int RunTests() if(Test7() == FAIL) result = FAIL; + if(Test8() == FAIL) + result = FAIL; + //Slow but basic test, will run at the end if(Test3() == FAIL) result = FAIL;