feat: BSP dungeon generation with 2D ASCII tile map

Replace list-based room display with proper 2D tile map using Binary
Space Partitioning. Rooms are carved into a 60x20 grid, connected by
L-shaped corridors, and rendered with ANSI-colored ASCII art including
fog of war visibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 00:57:16 +09:00
parent 92741d415d
commit 26784479b7
5 changed files with 490 additions and 54 deletions

View File

@@ -27,43 +27,9 @@ func renderMap(floor *dungeon.Floor) string {
if floor == nil {
return ""
}
var sb strings.Builder
headerStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("205")).Bold(true)
sb.WriteString(headerStyle.Render(fmt.Sprintf("── Catacombs B%d ──", floor.Number)))
sb.WriteString("\n\n")
roomStyle := lipgloss.NewStyle().Border(lipgloss.RoundedBorder())
dimStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("240"))
hiddenStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("236"))
for i, room := range floor.Rooms {
vis := dungeon.GetRoomVisibility(floor, i)
symbol := roomTypeSymbol(room.Type)
label := fmt.Sprintf("[%d] %s %s", i, symbol, room.Type.String())
if i == floor.CurrentRoom {
label = ">> " + label + " <<"
}
switch vis {
case dungeon.Visible:
sb.WriteString(roomStyle.Render(label))
case dungeon.Visited:
sb.WriteString(dimStyle.Render(label))
case dungeon.Hidden:
sb.WriteString(hiddenStyle.Render("[?] ???"))
}
for _, n := range room.Neighbors {
if n > i {
sb.WriteString(" --- ")
}
}
sb.WriteString("\n")
}
return sb.String()
header := headerStyle.Render(fmt.Sprintf("── Catacombs B%d ──", floor.Number))
return header + "\n" + dungeon.RenderFloor(floor, floor.CurrentRoom, true)
}
func renderHUD(state game.GameState, targetCursor int) string {