static void *monteCarloTaskStart(void *initialData) { assert(initialData != NULL); MonteCarloConfig *mcc = (MonteCarloConfig*) initialData; int nb = floor(world.worldSize / mcc->boxSize); if (nb < 0) die("World so small (or boxSize so big) that I can't fit a " "single box in there!\n"); /* adjust boxsize to get the correct world size! */ double trueBoxSize = world.worldSize / nb; printf("Requested boxsize %f, actual box size %f\n", mcc->boxSize, trueBoxSize); if (world.twoDimensional) { printf("Allocating grid for 2D world, %d boxes/dim.\n", nb); allocGrid(nb, nb, 1, trueBoxSize); } else { printf("Allocating grid for 3D world, %d boxes/dim.\n", nb); allocGrid(nb, nb, nb, trueBoxSize); } fillWorld(); MonteCarloState *state = malloc(sizeof(*state)); state->conf = *mcc; state->attempted = 0; state->accepted = 0; free(mcc); return state; }
void cellularAutomataRound(short **grid, char birthParameters[9], char survivalParameters[9]) { short i, j, nbCount, newX, newY; enum directions dir; short **buffer2; buffer2 = allocGrid(); copyGrid(buffer2, grid); // Make a backup of grid in buffer2, so that each generation is isolated. for(i=0; i<DCOLS; i++) { for(j=0; j<DROWS; j++) { nbCount = 0; for (dir=0; dir< DIRECTION_COUNT; dir++) { newX = i + nbDirs[dir][0]; newY = j + nbDirs[dir][1]; if (coordinatesAreInMap(newX, newY) && buffer2[newX][newY]) { nbCount++; } } if (!buffer2[i][j] && birthParameters[nbCount] == 't') { grid[i][j] = 1; // birth } else if (buffer2[i][j] && survivalParameters[nbCount] == 't') { // survival } else { grid[i][j] = 0; // death } } } freeGrid(buffer2); }
short pathingDistance(short x1, short y1, short x2, short y2, unsigned long blockingTerrainFlags) { short retval, **distanceMap = allocGrid(); calculateDistances(distanceMap, x2, y2, blockingTerrainFlags, NULL, true, true); retval = distanceMap[x1][y1]; freeGrid(distanceMap); return retval; }
boolean getQualifyingPathLocNear(short *retValX, short *retValY, short x, short y, boolean hallwaysAllowed, unsigned long blockingTerrainFlags, unsigned long blockingMapFlags, unsigned long forbiddenTerrainFlags, unsigned long forbiddenMapFlags, boolean deterministic) { short **grid, **costMap; short loc[2]; // First check the given location to see if it works, as an optimization. if (!cellHasTerrainFlag(x, y, blockingTerrainFlags | forbiddenTerrainFlags) && !(pmap[x][y].flags & (blockingMapFlags | forbiddenMapFlags)) && (hallwaysAllowed || passableArcCount(x, y) <= 1)) { *retValX = x; *retValY = y; return true; } // Allocate the grids. grid = allocGrid(); costMap = allocGrid(); // Start with a base of a high number everywhere. fillGrid(grid, 30000); fillGrid(costMap, 1); // Block off the pathing blockers. getTerrainGrid(costMap, PDS_FORBIDDEN, blockingTerrainFlags, blockingMapFlags); if (blockingTerrainFlags & (T_OBSTRUCTS_DIAGONAL_MOVEMENT | T_OBSTRUCTS_PASSABILITY)) { getTerrainGrid(costMap, PDS_OBSTRUCTION, T_OBSTRUCTS_DIAGONAL_MOVEMENT, 0); } // Run the distance scan. grid[x][y] = 1; costMap[x][y] = 1; dijkstraScan(grid, costMap, true); findReplaceGrid(grid, 30000, 30000, 0); // Block off invalid targets that aren't pathing blockers. getTerrainGrid(grid, 0, forbiddenTerrainFlags, forbiddenMapFlags); if (!hallwaysAllowed) { getPassableArcGrid(grid, 2, 10, 0); } // Get the solution. randomLeastPositiveLocationInGrid(grid, retValX, retValY, deterministic); // dumpLevelToScreen(); // displayGrid(grid); // if (coordinatesAreInMap(*retValX, *retValY)) { // hiliteCell(*retValX, *retValY, &yellow, 100, true); // } // temporaryMessage("Qualifying path selected:", true); freeGrid(grid); freeGrid(costMap); // Fall back to a pathing-agnostic alternative if there are no solutions. if (*retValX == -1 && *retValY == -1) { if (getQualifyingLocNear(loc, x, y, hallwaysAllowed, NULL, (blockingTerrainFlags | forbiddenTerrainFlags), (blockingMapFlags | forbiddenMapFlags), false, deterministic)) { *retValX = loc[0]; *retValY = loc[1]; return true; // Found a fallback solution. } else { return false; // No solutions. } } else { return true; // Found a primary solution. } }