odin-raylib-game/game/debug_terrain_tools.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, "%")
}