158 lines
4.3 KiB
GDScript
158 lines
4.3 KiB
GDScript
extends Node
|
|
class_name MapGenerator
|
|
|
|
# Map constants
|
|
var GRID_WIDTH = Global.GRID_WIDTH
|
|
var GRID_HEIGHT = Global.GRID_HEIGHT
|
|
var EMPTY = Global.MAP_EMPTY
|
|
var PATH = Global.MAP_PATH
|
|
var START = Global.MAP_START
|
|
var FINISH = Global.MAP_FINISH
|
|
var UP_CELL = Global.MAP_UP_CELL
|
|
|
|
# Map generation parameters
|
|
var up_probability_base = 0.1 # Base probability to move up
|
|
var up_probability_increase = 0.2 # How much the probability increases each time we stay on the same row
|
|
|
|
# The map grid
|
|
var map = []
|
|
|
|
func generate_map():
|
|
# Initialize map with empty cells
|
|
map = []
|
|
for y in range(GRID_HEIGHT):
|
|
var row = []
|
|
for x in range(GRID_WIDTH):
|
|
row.append(EMPTY)
|
|
map.append(row)
|
|
|
|
# Pick a starting location in the bottom row
|
|
var current_x = RNG.randi() % GRID_WIDTH
|
|
var current_y = GRID_HEIGHT - 1
|
|
|
|
# Mark as start
|
|
map[current_y][current_x] = START
|
|
|
|
# Track visited cells to avoid loops
|
|
var visited = {}
|
|
visited[Vector2(current_x, current_y)] = true
|
|
|
|
# Path generation
|
|
var final_position = generate_path(current_x, current_y, visited)
|
|
|
|
# Set finish cell in top row and connect path to it
|
|
connect_to_finish(final_position.x, final_position.y, visited)
|
|
|
|
# Generate path from start to top row, return final position
|
|
func generate_path(current_x, current_y, visited):
|
|
var up_probability = up_probability_base
|
|
|
|
while current_y > 0: # Continue until we reach the top row
|
|
# Try to move left or right until we can't proceed further
|
|
var can_move_horizontal = true
|
|
|
|
while can_move_horizontal:
|
|
# Decide whether to try moving up
|
|
if RNG.randf() < up_probability:
|
|
# We'll try moving up
|
|
break
|
|
|
|
# Increase probability for next time
|
|
up_probability += up_probability_increase
|
|
|
|
# Choose direction randomly (left or right)
|
|
var direction = 1 if RNG.randf() > 0.5 else -1
|
|
var new_x = current_x + direction
|
|
|
|
# Check if we can move in that direction
|
|
if new_x >= 0 and new_x < GRID_WIDTH and not Vector2(new_x, current_y) in visited:
|
|
current_x = new_x
|
|
map[current_y][current_x] = PATH
|
|
visited[Vector2(current_x, current_y)] = true
|
|
else:
|
|
# Try the other direction
|
|
direction = - direction
|
|
new_x = current_x + direction
|
|
|
|
if new_x >= 0 and new_x < GRID_WIDTH and not Vector2(new_x, current_y) in visited:
|
|
current_x = new_x
|
|
map[current_y][current_x] = PATH
|
|
visited[Vector2(current_x, current_y)] = true
|
|
else:
|
|
# Can't move horizontally anymore
|
|
can_move_horizontal = false
|
|
|
|
# Mark current cell as an UP_CELL before moving up
|
|
map[current_y][current_x] = UP_CELL
|
|
|
|
# Move up
|
|
current_y -= 1
|
|
map[current_y][current_x] = PATH
|
|
visited[Vector2(current_x, current_y)] = true
|
|
|
|
# Reset up probability since we've moved up
|
|
up_probability = up_probability_base
|
|
|
|
# Return the final position (on the top row)
|
|
return Vector2(current_x, current_y)
|
|
|
|
# Connect the path to a finish point in the top row
|
|
func connect_to_finish(current_x, current_y, visited):
|
|
# Choose a finish position
|
|
var finish_x = RNG.randi() % GRID_WIDTH
|
|
|
|
# If we randomly picked the current position, we're done
|
|
if finish_x == current_x:
|
|
map[current_y][current_x] = FINISH
|
|
return
|
|
|
|
# Otherwise, create a path to the finish
|
|
var direction = 1 if finish_x > current_x else -1
|
|
|
|
# Move horizontally toward the finish position
|
|
while current_x != finish_x:
|
|
current_x += direction
|
|
|
|
# If we've already visited this cell, we have a loop - break and place finish here
|
|
if Vector2(current_x, current_y) in visited:
|
|
break
|
|
|
|
map[current_y][current_x] = PATH
|
|
visited[Vector2(current_x, current_y)] = true
|
|
|
|
# Place finish at the final position
|
|
map[current_y][current_x] = FINISH
|
|
|
|
func print_map():
|
|
print("Generated Map:")
|
|
print("- Legend: 0=Empty, 1=Path, 2=Start, 4=Finish, 3=MoveUp")
|
|
print("")
|
|
|
|
var visual_map = ""
|
|
|
|
for y in range(GRID_HEIGHT):
|
|
var row_str = ""
|
|
for x in range(GRID_WIDTH):
|
|
var cell_value = map[y][x]
|
|
match cell_value:
|
|
EMPTY: row_str += "[ ] "
|
|
PATH: row_str += "[•] "
|
|
START: row_str += "[S] "
|
|
FINISH: row_str += "[F] "
|
|
UP_CELL: row_str += "[↑] "
|
|
visual_map += row_str + "\n"
|
|
|
|
print(visual_map)
|
|
|
|
# Also print as numerical grid
|
|
visual_map = ""
|
|
for y in range(GRID_HEIGHT):
|
|
var row_str = ""
|
|
for x in range(GRID_WIDTH):
|
|
row_str += str(map[y][x]) + " "
|
|
visual_map += row_str + "\n"
|
|
|
|
print(visual_map)
|
|
|
|
func get_map():
|
|
return map
|