207 lines
7.4 KiB
Odin
207 lines
7.4 KiB
Odin
package game
|
|
|
|
import "core:fmt"
|
|
import "core:math/noise"
|
|
|
|
// Fixed desert finding procedure
|
|
find_desert :: proc(seed: i64) -> (found: bool, pos: Vec2i) {
|
|
search_radius := 1000
|
|
step_size := 20 // Check every 20 blocks to speed up the search
|
|
|
|
// Track how many desert tiles we find for debugging
|
|
desert_count := 0
|
|
total_checked := 0
|
|
last_desert_pos := Vec2i{0, 0}
|
|
|
|
fmt.println("Searching for deserts with seed:", seed)
|
|
|
|
for x := -search_radius; x < search_radius; x += step_size {
|
|
for y := -search_radius; y < search_radius; y += step_size {
|
|
pos := Vec2i{x, y}
|
|
biome := get_biome_type(pos, seed)
|
|
total_checked += 1
|
|
|
|
if biome.type == .DESERT {
|
|
desert_count += 1
|
|
last_desert_pos = pos
|
|
fmt.println("Found desert at:", pos)
|
|
|
|
if desert_count <= 5 { // Only report the first few to avoid spam
|
|
// Verify by checking adjacent tiles to confirm it's not just a single glitched tile
|
|
desert_size := 0
|
|
check_radius := 3
|
|
|
|
for cx := -check_radius; cx <= check_radius; cx += 1 {
|
|
for cy := -check_radius; cy <= check_radius; cy += 1 {
|
|
check_pos := Vec2i{x + cx, y + cy}
|
|
check_biome := get_biome_type(check_pos, seed)
|
|
|
|
if check_biome.type == .DESERT {
|
|
desert_size += 1
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.println(" Desert size (in 7x7 area):", desert_size, "out of", (check_radius*2+1)*(check_radius*2+1))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Report desert statistics
|
|
desert_percentage := f32(desert_count) / f32(total_checked) * 100.0
|
|
fmt.println("Desert statistics:")
|
|
fmt.println(" Total positions checked:", total_checked)
|
|
fmt.println(" Desert tiles found:", desert_count)
|
|
fmt.println(" Desert percentage:", desert_percentage, "%")
|
|
|
|
if desert_count > 0 {
|
|
return true, last_desert_pos // Return the last desert found
|
|
} else {
|
|
fmt.println("No desert found within search radius")
|
|
return false, Vec2i{0, 0}
|
|
}
|
|
}
|
|
|
|
// Create a biome distribution map to visualize the actual distribution
|
|
generate_biome_map :: proc(seed: i64, width: int, height: int) {
|
|
biome_counts := [BiomeType]int{}
|
|
total_tiles := width * height
|
|
|
|
fmt.println("Generating biome distribution map", width, "x", height)
|
|
|
|
// First pass - count biomes
|
|
for y := 0; y < height; y += 1 {
|
|
for x := 0; x < width; x += 1 {
|
|
// Use a different area of the world for better sampling
|
|
world_x := (x - width/2) * 20
|
|
world_y := (y - height/2) * 20
|
|
|
|
biome := get_biome_type(Vec2i{world_x, world_y}, seed)
|
|
biome_counts[biome.type] += 1
|
|
|
|
// Print a character representing each biome for a ASCII map
|
|
if y % 5 == 0 && x % 5 == 0 { // Print sparse map to fit in console
|
|
c := '?'
|
|
switch biome.type {
|
|
case .DESERT: c = 'D'
|
|
case .GRASSLAND: c = 'G'
|
|
case .FOREST: c = 'F'
|
|
case .LAKE: c = 'L'
|
|
}
|
|
fmt.print(c)
|
|
}
|
|
}
|
|
if y % 5 == 0 {
|
|
fmt.println()
|
|
}
|
|
}
|
|
|
|
// Print biome statistics
|
|
fmt.println("\nBiome Distribution:")
|
|
fmt.println(" Total area:", total_tiles, "tiles")
|
|
|
|
for biome_type, count in biome_counts {
|
|
percentage := f32(count) / f32(total_tiles) * 100.0
|
|
fmt.println(" ", biome_type, ":", count, "tiles (", percentage, "%)")
|
|
}
|
|
}
|
|
|
|
// Debug the noise distribution directly
|
|
debug_noise_values :: proc(seed: i64) {
|
|
// Import math package at the top of your file
|
|
// import "core:math"
|
|
|
|
// Collect some sample values to see the actual distribution
|
|
samples := 1000
|
|
temp_values := make([dynamic]f64, 0, samples)
|
|
moisture_values := make([dynamic]f64, 0, samples)
|
|
|
|
for i := 0; i < samples; i += 1 {
|
|
// Sample across a wide area
|
|
x := (i % 50) * 100 - 2500
|
|
y := (i / 50) * 100 - 2500
|
|
|
|
// Generate values the same way as in get_biome_type
|
|
continent_scale := 0.001
|
|
region_scale := 0.005
|
|
|
|
moisture_seed := seed + 20000
|
|
temperature_seed := seed + 30000
|
|
|
|
// Get raw noise values
|
|
moisture := noise.noise_2d(moisture_seed, {f64(x) * region_scale, f64(y) * region_scale})
|
|
temperature := noise.noise_2d(temperature_seed, {f64(x) * region_scale, f64(y) * region_scale})
|
|
|
|
// Apply the same transformations as in your get_biome_type function
|
|
// Remove this line if you don't have math imported, or replace with your own pow implementation
|
|
// temperature = math.pow(temperature * 0.5 + 0.5, 0.8) * 2.0 - 1.0
|
|
|
|
// Normalize to 0-1 range
|
|
normalized_moisture := f64(moisture * 0.5 + 0.5)
|
|
normalized_temperature := f64(temperature * 0.5 + 0.5)
|
|
|
|
append_elem(&temp_values, normalized_temperature)
|
|
append_elem(&moisture_values, normalized_moisture)
|
|
}
|
|
|
|
// Calculate statistics
|
|
temp_min, temp_max, temp_avg := 1.0, 0.0, 0.0
|
|
moisture_min, moisture_max, moisture_avg := 1.0, 0.0, 0.0
|
|
|
|
for i := 0; i < samples; i += 1 {
|
|
temp := temp_values[i]
|
|
moisture := moisture_values[i]
|
|
|
|
temp_avg += temp
|
|
moisture_avg += moisture
|
|
|
|
temp_min = min(temp_min, temp)
|
|
temp_max = max(temp_max, temp)
|
|
moisture_min = min(moisture_min, moisture)
|
|
moisture_max = max(moisture_max, moisture)
|
|
}
|
|
|
|
temp_avg /= f64(samples)
|
|
moisture_avg /= f64(samples)
|
|
|
|
// Print statistics
|
|
fmt.println("Temperature values (normalized to 0-1):")
|
|
fmt.println(" Min:", temp_min, "Max:", temp_max, "Avg:", temp_avg)
|
|
fmt.println("Moisture values (normalized to 0-1):")
|
|
fmt.println(" Min:", moisture_min, "Max:", moisture_max, "Avg:", moisture_avg)
|
|
|
|
// Count how many points would qualify as deserts with different thresholds
|
|
desert_count_strict := 0
|
|
desert_count_medium := 0
|
|
desert_count_loose := 0
|
|
|
|
for i := 0; i < samples; i += 1 {
|
|
temp := temp_values[i]
|
|
moisture := moisture_values[i]
|
|
|
|
// Strict: temp > 0.55 && moisture < 0.4
|
|
if temp > 0.55 && moisture < 0.4 {
|
|
desert_count_strict += 1
|
|
}
|
|
|
|
// Medium: temp > 0.4 && moisture < 0.6
|
|
if temp > 0.4 && moisture < 0.6 {
|
|
desert_count_medium += 1
|
|
}
|
|
|
|
// Loose: temp > 0.3 || moisture < 0.4
|
|
if temp > 0.3 || moisture < 0.4 {
|
|
desert_count_loose += 1
|
|
}
|
|
}
|
|
|
|
fmt.println("\nDesert qualification rates with different thresholds:")
|
|
fmt.println(" Strict (temp > 0.55 && moisture < 0.4):",
|
|
f32(desert_count_strict)/f32(samples)*100.0, "%")
|
|
fmt.println(" Medium (temp > 0.4 && moisture < 0.6):",
|
|
f32(desert_count_medium)/f32(samples)*100.0, "%")
|
|
fmt.println(" Loose (temp > 0.3 || moisture < 0.4):",
|
|
f32(desert_count_loose)/f32(samples)*100.0, "%")
|
|
}
|