Tour localSearch_randomBestPath(Instance pInstance, int pTryNb) {
	Tour ret, buffTour;
	int first2opt, second2opt;
	int i;

	buffTour = tour_randomWalk(pInstance);	
	ret = buffTour;
    if(gVerboseMode) {
        printf("Random walk:\n ");
        tour_display(buffTour);
        printf("\n\n");
    }
	for(i=0 ; i < pTryNb ; ++i) { 
		do { 
            first2opt = util_rand(1, pInstance.nbTowns);
            second2opt = util_rand(1, pInstance.nbTowns);
		} while(first2opt == second2opt || 
				(first2opt == second2opt-1 || second2opt == first2opt-1));
		tour_2opt(&buffTour, first2opt, second2opt); 

		if(buffTour.length < ret.length) { 
			ret = buffTour;
            if(gVerboseMode) {
                printf("\nMeilleur tour après 2opt numéro %d: \n", i+1);  
                tour_display(ret);
                printf("\n");
            }

		}
	}

	return ret;
}
Exemple #2
0
/**
 *
 *  rct2: 0x00685A93
 */
void research_items_shuffle()
{
    rct_research_item *researchItem, *researchOrderBase, researchItemTemp;
    int32_t i, numNonResearchedItems;

    // Skip pre-researched items
    for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++)
    {
    }
    researchItem++;
    researchOrderBase = researchItem;

    // Count non pre-researched items
    numNonResearchedItems = 0;
    for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++)
        numNonResearchedItems++;

    // Shuffle list
    for (i = 0; i < numNonResearchedItems; i++)
    {
        int32_t ri = util_rand() % numNonResearchedItems;
        if (ri == i)
            continue;

        researchItemTemp = researchOrderBase[i];
        researchOrderBase[i] = researchOrderBase[ri];
        researchOrderBase[ri] = researchItemTemp;
    }
}
Exemple #3
0
static void mapgen_blobs(sint32 count, sint32 lowSize, sint32 highSize, sint32 lowHeight, sint32 highHeight)
{
	sint32 i;
	sint32 sizeRange = highSize - lowSize;
	sint32 heightRange = highHeight - lowHeight;

	sint32 border = 2 + (util_rand() % 24);
	sint32 borderRange = _heightSize - (border * 2);
	for (i = 0; i < count; i++) {
		sint32 radius = lowSize + (util_rand() % sizeRange);
		mapgen_blob(
			border + (util_rand() % borderRange),
			border + (util_rand() % borderRange),
			(sint32)(M_PI * radius * radius),
			lowHeight + (util_rand() % heightRange)
		);
	}
}
Exemple #4
0
static void mapgen_blobs(int count, int lowSize, int highSize, int lowHeight, int highHeight)
{
	int i;
	int sizeRange = highSize - lowSize;
	int heightRange = highHeight - lowHeight;

	int border = 2 + (util_rand() % 24);
	int borderRange = _heightSize - (border * 2);
	for (i = 0; i < count; i++) {
		int radius = lowSize + (util_rand() % sizeRange);
		mapgen_blob(
			border + (util_rand() % borderRange),
			border + (util_rand() % borderRange),
			(int)(M_PI * radius * radius),
			lowHeight + (util_rand() % heightRange)
		);
	}
}
Exemple #5
0
static void window_mapgen_random_mouseup(rct_window *w, int widgetIndex)
{
	mapgen_settings mapgenSettings;

	switch (widgetIndex) {
	case WIDX_CLOSE:
		window_close(w);
		break;
	case WIDX_TAB_1:
	case WIDX_TAB_2:
	case WIDX_TAB_3:
		window_mapgen_set_page(w, widgetIndex - WIDX_TAB_1);
		break;
	case WIDX_GENERATE:
		mapgenSettings.mapSize = _mapSize;
		mapgenSettings.height = _baseHeight + 2;
		mapgenSettings.waterLevel = _waterLevel + 2;
		mapgenSettings.floor = _randomTerrrain ? -1 : _floorTexture;
		mapgenSettings.wall = _randomTerrrain ? -1 : _wallTexture;
		mapgenSettings.trees = _placeTrees;

		mapgenSettings.simplex_low = util_rand() % 4;
		mapgenSettings.simplex_high = 12 + (util_rand() % (32 - 12));
		mapgenSettings.simplex_base_freq = 1.75f;
		mapgenSettings.simplex_octaves = 6;

		mapgen_generate(&mapgenSettings);
		gfx_invalidate_screen();
		break;
	case WIDX_RANDOM_TERRAIN:
		_randomTerrrain ^= 1;
		break;
	case WIDX_PLACE_TREES:
		_placeTrees ^= 1;
		break;
	}
}
Exemple #6
0
static void mapgen_place_tree(sint32 type, sint32 x, sint32 y)
{
	sint32 surfaceZ;
	rct_map_element *mapElement;
	rct_scenery_entry *sceneryEntry = get_small_scenery_entry(type);

	surfaceZ = map_element_height(x * 32 + 16, y * 32 + 16) / 8;
	mapElement = map_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8));
	assert(mapElement != NULL);
	mapElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3);

	mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (util_rand() & 3);
	mapElement->properties.scenery.type = type;
	mapElement->properties.scenery.age = 0;
	mapElement->properties.scenery.colour_1 = COLOUR_YELLOW;
}
Exemple #7
0
static void mapgen_place_tree(int type, int x, int y)
{
	int surfaceZ;
	rct_map_element *mapElement;
	rct_scenery_entry *sceneryEntry = g_smallSceneryEntries[type];

	surfaceZ = map_element_height(x * 32 + 16, y * 32 + 16) / 8;
	mapElement = map_element_insert(x, y, surfaceZ, (1 | 2 | 4 | 8));
	mapElement->clearance_height = surfaceZ + (sceneryEntry->small_scenery.height >> 3);

	mapElement->type = MAP_ELEMENT_TYPE_SCENERY | (util_rand() % 3);
	mapElement->properties.scenery.type = type;
	mapElement->properties.scenery.age = 0;
	mapElement->properties.scenery.colour_1 = 26;
	mapElement->properties.scenery.colour_1 = 18;
}
Exemple #8
0
static void noise_rand()
{
	for (sint32 i = 0; i < countof(perm); i++)
		perm[i] = util_rand() & 0xFF;
}
Exemple #9
0
/**
 * Sets a rough circular blob of tiles of the specified size to the specified height.
 */
static void mapgen_blob(sint32 cx, sint32 cy, sint32 size, sint32 height)
{
	sint32 x, y, currentSize, direction;

	x = cx;
	y = cy;
	currentSize = 1;
	direction = 0;
	set_height(x, y, BLOB_HEIGHT);

	while (currentSize < size) {
		if (util_rand() % 2 == 0) {
			set_height(x, y, BLOB_HEIGHT);
			currentSize++;
		}

		switch (direction) {
		case 0:
			if (y == 0) {
				currentSize = size;
				break;
			}

			y--;
			if (get_height(x + 1, y) != BLOB_HEIGHT)
				direction = 1;
			else if (get_height(x, y - 1) != BLOB_HEIGHT)
				direction = 0;
			else if (get_height(x - 1, y) != BLOB_HEIGHT)
				direction = 3;
			break;
		case 1:
			if (x == _heightSize - 1) {
				currentSize = size;
				break;
			}

			x++;
			if (get_height(x, y + 1) != BLOB_HEIGHT)
				direction = 2;
			else if (get_height(x + 1, y) != BLOB_HEIGHT)
				direction = 1;
			else if (get_height(x, y - 1) != BLOB_HEIGHT)
				direction = 0;
			break;
		case 2:
			if (y == _heightSize - 1) {
				currentSize = size;
				break;
			}

			y++;
			if (get_height(x - 1, y) != BLOB_HEIGHT)
				direction = 3;
			else if (get_height(x, y + 1) != BLOB_HEIGHT)
				direction = 2;
			else if (get_height(x + 1, y) != BLOB_HEIGHT)
				direction = 1;
			break;
		case 3:
			if (x == 0) {
				currentSize = size;
				break;
			}

			x--;
			if (get_height(x, y - 1) != BLOB_HEIGHT)
				direction = 0;
			else if (get_height(x - 1, y) != BLOB_HEIGHT)
				direction = 3;
			else if (get_height(x, y + 1) != BLOB_HEIGHT)
				direction = 2;
			break;
		}
	}

	mapgen_blob_fill(height);
}
Exemple #10
0
/**
 * Randomly places a selection of preset trees on the map. Picks the right tree for the terrain it is placing it on.
 */
static void mapgen_place_trees()
{
	sint32 numGrassTreeIds = 0, numDesertTreeIds = 0, numSnowTreeIds = 0;
	sint32 *grassTreeIds = (sint32*)malloc(countof(GrassTrees) * sizeof(sint32));
	sint32 *desertTreeIds = (sint32*)malloc(countof(DesertTrees) * sizeof(sint32));
	sint32 *snowTreeIds = (sint32*)malloc(countof(SnowTrees) * sizeof(sint32));

	for (sint32 i = 0; i < object_entry_group_counts[OBJECT_TYPE_SMALL_SCENERY]; i++) {
		rct_scenery_entry *sceneryEntry = get_small_scenery_entry(i);
		rct_object_entry_extended *entry = &object_entry_groups[OBJECT_TYPE_SMALL_SCENERY].entries[i];

		if (sceneryEntry == (rct_scenery_entry*)-1 || sceneryEntry == NULL)
			continue;

		sint32 j;
		for (j = 0; j < countof(GrassTrees); j++)
			if (strncmp(GrassTrees[j], entry->name, 8) == 0)
				break;
		if (j != countof(GrassTrees)) {
			grassTreeIds[numGrassTreeIds++] = i;
			continue;
		}

		for (j = 0; j < countof(DesertTrees); j++)
			if (strncmp(DesertTrees[j], entry->name, 8) == 0)
				break;
		if (j != countof(DesertTrees)) {
			desertTreeIds[numDesertTreeIds++] = i;
			continue;
		}

		for (j = 0; j < countof(SnowTrees); j++)
			if (strncmp(SnowTrees[j], entry->name, 8) == 0)
				break;
		if (j != countof(SnowTrees)) {
			snowTreeIds[numSnowTreeIds++] = i;
			continue;
		}
	}

	sint32 availablePositionsCount = 0;
	struct { sint32 x; sint32 y; } tmp, *pos, *availablePositions;
	availablePositions = malloc(256 * 256 * sizeof(tmp));

	// Create list of available tiles
	for (sint32 y = 1; y < gMapSize - 1; y++) {
		for (sint32 x = 1; x < gMapSize - 1; x++) {
			rct_map_element *mapElement = map_get_surface_element_at(x, y);

			// Exclude water tiles
			if ((mapElement->properties.surface.terrain & 0x1F) != 0)
				continue;

			pos = &availablePositions[availablePositionsCount++];
			pos->x = x;
			pos->y = y;
		}
	}

	// Shuffle list
	for (sint32 i = 0; i < availablePositionsCount; i++) {
		sint32 rindex = util_rand() % availablePositionsCount;
		if (rindex == i)
			continue;

		tmp = availablePositions[i];
		availablePositions[i] = availablePositions[rindex];
		availablePositions[rindex] = tmp;
	}

	// Place trees
	float treeToLandRatio = (10 + (util_rand() % 30)) / 100.0f;
	sint32 numTrees = max(4, (sint32)(availablePositionsCount * treeToLandRatio));

	for (sint32 i = 0; i < numTrees; i++) {
		pos = &availablePositions[i];

		sint32 type = -1;
		rct_map_element *mapElement = map_get_surface_element_at(pos->x, pos->y);
		switch (map_element_get_terrain(mapElement)) {
		case TERRAIN_GRASS:
		case TERRAIN_DIRT:
		case TERRAIN_GRASS_CLUMPS:
			if (numGrassTreeIds == 0)
				break;

			type = grassTreeIds[util_rand() % numGrassTreeIds];
			break;

		case TERRAIN_SAND:
		case TERRAIN_SAND_DARK:
		case TERRAIN_SAND_LIGHT:
			if (numDesertTreeIds == 0)
				break;

			if (util_rand() % 4 == 0)
				type = desertTreeIds[util_rand() % numDesertTreeIds];
			break;

		case TERRAIN_ICE:
			if (numSnowTreeIds == 0)
				break;

			type = snowTreeIds[util_rand() % numSnowTreeIds];
			break;
		}

		if (type != -1)
			mapgen_place_tree(type, pos->x, pos->y);
	}

	free(availablePositions);
	free(grassTreeIds);
	free(desertTreeIds);
	free(snowTreeIds);
}
Exemple #11
0
void mapgen_generate(mapgen_settings *settings)
{
	sint32 x, y, mapSize, floorTexture, wallTexture, waterLevel;
	rct_map_element *mapElement;

	util_srand((sint32)SDL_GetTicks());

	mapSize = settings->mapSize;
	floorTexture = settings->floor;
	wallTexture = settings->wall;
	waterLevel = settings->waterLevel;

	if (floorTexture == -1)
		floorTexture = BaseTerrain[util_rand() % countof(BaseTerrain)];

	if (wallTexture == -1) {
		// Base edge type on surface type
		switch (floorTexture) {
		case TERRAIN_DIRT:
			wallTexture = TERRAIN_EDGE_WOOD_RED;
			break;
		case TERRAIN_ICE:
			wallTexture = TERRAIN_EDGE_ICE;
			break;
		default:
			wallTexture = TERRAIN_EDGE_ROCK;
			break;
		}
	}

	map_clear_all_elements();

	// Initialise the base map
	map_init(mapSize);
	for (y = 1; y < mapSize - 1; y++) {
		for (x = 1; x < mapSize - 1; x++) {
			mapElement = map_get_surface_element_at(x, y);
			map_element_set_terrain(mapElement, floorTexture);
			map_element_set_terrain_edge(mapElement, wallTexture);
			mapElement->base_height = settings->height;
			mapElement->clearance_height = settings->height;
		}
	}

	// Create the temporary height map and initialise
	_heightSize = mapSize * 2;
	_height = (uint8*)malloc(_heightSize * _heightSize * sizeof(uint8));
	memset(_height, 0, _heightSize * _heightSize * sizeof(uint8));

	if (1) {
		mapgen_simplex(settings);
		mapgen_smooth_height(2 + (util_rand() % 6));
	} else {
		// Keep overwriting the map with rough cicular blobs of different sizes and heights.
		// This procedural method can produce intersecting contour like land and lakes.
		// Large blobs, general shape of map
		mapgen_blobs(6, _heightSize / 2, _heightSize * 4, 4, 16);
		// Medium blobs
		mapgen_blobs(12, _heightSize / 16, _heightSize / 8, 4, 18);
		// Small blobs, small hills and lakes
		mapgen_blobs(32, _heightSize / 32, _heightSize / 16, 4, 18);

		// Smooth the land so that their aren't cliffs round every blob.
		mapgen_smooth_height(2);
	}

	// Set the game map to the height map
	mapgen_set_height();
	free(_height);

	// Set the tile slopes so that there are no cliffs
	while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { }

	// Add the water
	mapgen_set_water_level(waterLevel);

	// Add sandy beaches
	sint32 beachTexture = floorTexture;
	if (settings->floor == -1 && floorTexture == TERRAIN_GRASS) {
		switch (util_rand() % 4) {
		case 0:
			beachTexture = TERRAIN_SAND;
			break;
		case 1:
			beachTexture = TERRAIN_SAND_LIGHT;
			break;
		}
	}
	for (y = 1; y < mapSize - 1; y++) {
		for (x = 1; x < mapSize - 1; x++) {
			mapElement = map_get_surface_element_at(x, y);

			if (mapElement->base_height < waterLevel + 6)
				map_element_set_terrain(mapElement, beachTexture);
		}
	}

	// Place the trees
	if (settings->trees != 0)
		mapgen_place_trees();

	map_reorganise_elements();
}
Exemple #12
0
/**
 * Weather & climate update iteration.
 * Gradually changes the weather parameters towards their determined next values.
 */
void climate_update()
{
    // Only do climate logic if playing (not in scenario editor or title screen)
    if (gScreenFlags & (~SCREEN_FLAGS_PLAYING)) return;

    if (!gCheatsFreezeClimate)
    {
        if (gClimateUpdateTimer)
        {
            if (gClimateUpdateTimer == 960)
            {
                auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE);
                context_broadcast_intent(&intent);
            }
            gClimateUpdateTimer--;
        }
        else if (!(gCurrentTicks & 0x7F))
        {
            if (gClimateCurrent.Temperature == gClimateNext.Temperature)
            {
                if (gClimateCurrent.WeatherGloom == gClimateNext.WeatherGloom)
                {
                    gClimateCurrent.WeatherEffect = gClimateNext.WeatherEffect;
                    _thunderTimer = 0;
                    _lightningTimer = 0;

                    if (gClimateCurrent.RainLevel == gClimateNext.RainLevel)
                    {
                        gClimateCurrent.Weather = gClimateNext.Weather;
                        climate_determine_future_weather(scenario_rand());
                        auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE);
                        context_broadcast_intent(&intent);
                    }
                    else if (gClimateNext.RainLevel <= RAIN_LEVEL_HEAVY)
                    {
                        gClimateCurrent.RainLevel = climate_step_weather_level(gClimateCurrent.RainLevel, gClimateNext.RainLevel);
                    }
                }
                else
                {
                    gClimateCurrent.WeatherGloom = climate_step_weather_level(gClimateCurrent.WeatherGloom, gClimateNext.WeatherGloom);
                    gfx_invalidate_screen();
                }
            }
            else
            {
                gClimateCurrent.Temperature = climate_step_weather_level(gClimateCurrent.Temperature, gClimateNext.Temperature);
                auto intent = Intent(INTENT_ACTION_UPDATE_CLIMATE);
                context_broadcast_intent(&intent);
            }
        }

    }

    if (_thunderTimer != 0)
    {
        climate_update_lightning();
        climate_update_thunder();
    }
    else if (gClimateCurrent.WeatherEffect == WEATHER_EFFECT_STORM)
    {
        // Create new thunder and lightning
        uint32 randomNumber = util_rand();
        if ((randomNumber & 0xFFFF) <= 0x1B4)
        {
            randomNumber >>= 16;
            _thunderTimer = 43 + (randomNumber % 64);
            _lightningTimer = randomNumber % 32;
        }