aboutsummaryrefslogtreecommitdiff
path: root/internal/game/map.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/map.go')
-rw-r--r--internal/game/map.go317
1 files changed, 0 insertions, 317 deletions
diff --git a/internal/game/map.go b/internal/game/map.go
deleted file mode 100644
index 32d3d7c..0000000
--- a/internal/game/map.go
+++ /dev/null
@@ -1,317 +0,0 @@
-package game
-
-import (
- "strings"
-
- "thehouseoficarus/internal/world"
-)
-
-type mapGlyphs struct {
- topLeft, topRight rune
- bottomLeft, bottomRight rune
- side rune
- topFill rune
- connectorH, connectorV rune
- upArrow, downArrow rune
-}
-
-func mapGlyphsForPlayer(unicode bool) mapGlyphs {
- if unicode {
- return mapGlyphs{
- topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
- side: '║', topFill: '═', connectorH: '─', connectorV: '│',
- upArrow: '↑', downArrow: '↓',
- }
- }
- return mapGlyphs{
- topLeft: '.', topRight: '.', bottomLeft: ':', bottomRight: ':',
- side: ':', topFill: '.', connectorH: '-', connectorV: '|',
- upArrow: '^', downArrow: 'v',
- }
-}
-
-type mapGraph struct {
- posToRoom map[[2]int]int
- roomToPos map[int][2]int
-}
-
-var bfsDirs = []struct {
- dir world.ExitDir
- dx, dy int
-}{
- {world.North, 0, -1},
- {world.South, 0, 1},
- {world.East, 1, 0},
- {world.West, -1, 0},
-}
-
-func buildGraph(g *Game, startRoomID int) *mapGraph {
- mg := &mapGraph{
- posToRoom: make(map[[2]int]int),
- roomToPos: make(map[int][2]int),
- }
-
- type node struct {
- roomID int
- x, y int
- }
- queue := []node{{startRoomID, 0, 0}}
- mg.posToRoom[[2]int{0, 0}] = startRoomID
- mg.roomToPos[startRoomID] = [2]int{0, 0}
-
- for len(queue) > 0 {
- n := queue[0]
- queue = queue[1:]
-
- room, ok := loadRoom(g, n.roomID)
- if !ok {
- continue
- }
-
- for _, d := range bfsDirs {
- targetID, ok := exitTarget(room, d.dir)
- if !ok {
- continue
- }
- if _, visited := mg.roomToPos[targetID]; visited {
- continue
- }
- nx, ny := n.x + d.dx, n.y + d.dy
- mg.posToRoom[[2]int{nx, ny}] = targetID
- mg.roomToPos[targetID] = [2]int{nx, ny}
- queue = append(queue, node{targetID, nx, ny})
- }
- }
-
- return mg
-}
-
-func buildTinyMap(g *Game, roomID int, mg mapGlyphs) []string {
- bg := buildGraph(g, roomID)
-
- grid := make([][]rune, 5)
- for i := range grid {
- grid[i] = make([]rune, 5)
- for j := range grid[i] {
- grid[i][j] = ' '
- }
- }
-
- for y := -1; y <= 1; y++ {
- for x := -1; x <= 1; x++ {
- pos := [2]int{x, y}
- rid, ok := bg.posToRoom[pos]
- if !ok {
- continue
- }
- gr := (y + 1) * 2
- gc := (x + 1) * 2
- if rid == roomID {
- grid[gr][gc] = '@'
- } else {
- grid[gr][gc] = roomMapSymbol(g, rid)
- }
- }
- }
-
- for y := -1; y <= 1; y++ {
- for x := -1; x <= 0; x++ {
- leftPos := [2]int{x, y}
- rightPos := [2]int{x + 1, y}
- leftRoom, leftOK := bg.posToRoom[leftPos]
- rightRoom, rightOK := bg.posToRoom[rightPos]
- if !leftOK || !rightOK {
- continue
- }
- if exitsConnect(g, leftRoom, rightRoom, world.East, world.West) {
- grid[(y+1)*2][(x+1)*2+1] = mg.connectorH
- }
- }
- }
-
- for y := -1; y <= 0; y++ {
- for x := -1; x <= 1; x++ {
- topPos := [2]int{x, y}
- bottomPos := [2]int{x, y + 1}
- topRoom, topOK := bg.posToRoom[topPos]
- bottomRoom, bottomOK := bg.posToRoom[bottomPos]
- if !topOK || !bottomOK {
- continue
- }
- if exitsConnect(g, topRoom, bottomRoom, world.South, world.North) {
- grid[(y+1)*2+1][(x+1)*2] = mg.connectorV
- }
- }
- }
-
- cur, _ := loadRoom(g, roomID)
- if cur != nil {
- if _, ok := exitTarget(cur, world.Up); ok {
- grid[1][3] = mg.upArrow
- }
- if _, ok := exitTarget(cur, world.Down); ok {
- grid[3][1] = mg.downArrow
- }
- }
-
- topFill := strings.Repeat(string(mg.topFill), 5)
- lines := make([]string, 7)
- lines[0] = string(mg.topLeft) + topFill + string(mg.topRight)
- for row := 0; row < 5; row++ {
- lines[row+1] = string(mg.side) + string(grid[row]) + string(mg.side)
- }
- botFill := strings.Repeat(string(mg.topFill), 5)
- lines[6] = string(mg.bottomLeft) + botFill + string(mg.bottomRight)
-
- return lines
-}
-
-func exitsConnect(g *Game, room1, room2 int, dir12, dir21 world.ExitDir) bool {
- r1, ok := loadRoom(g, room1)
- if !ok {
- return false
- }
- if id, ok := exitTarget(r1, dir12); ok && id == room2 {
- return true
- }
- r2, ok := loadRoom(g, room2)
- if !ok {
- return false
- }
- id, ok := exitTarget(r2, dir21)
- return ok && id == room1
-}
-
-func exitTarget(room *world.Room, dir world.ExitDir) (int, bool) {
- if room == nil {
- return 0, false
- }
- exit, ok := room.Exits[dir]
- if !ok {
- return 0, false
- }
- return exit.Room, true
-}
-
-func loadRoom(g *Game, roomID int) (*world.Room, bool) {
- if roomID == 0 {
- return nil, false
- }
- room, err := g.World.LoadRoom(roomID)
- if err != nil {
- return nil, false
- }
- return room, true
-}
-
-func roomMapSymbol(g *Game, roomID int) rune {
- room, ok := loadRoom(g, roomID)
- if !ok {
- return '?'
- }
- if room.MapSymbol != "" {
- runes := []rune(room.MapSymbol)
- return runes[0]
- }
- return 'o'
-}
-
-func stripBlankRows(lines []string) []string {
- var out []string
- for _, line := range lines {
- if strings.TrimSpace(line) != "" {
- out = append(out, line)
- }
- }
- return out
-}
-
-func leftTrimCommon(lines []string) []string {
- min := -1
- for _, line := range lines {
- if strings.TrimSpace(line) == "" {
- continue
- }
- n := 0
- for _, r := range line {
- if r == ' ' {
- n++
- } else {
- break
- }
- }
- if min < 0 || n < min {
- min = n
- }
- }
- if min <= 0 {
- return lines
- }
- result := make([]string, len(lines))
- for i, line := range lines {
- if len(line) <= min {
- result[i] = ""
- } else {
- result[i] = line[min:]
- }
- }
- return result
-}
-
-func buildFullMap(g *Game, roomID, mapWidth, mapHeight int, mg mapGlyphs) []string {
- bg := buildGraph(g, roomID)
-
- grid := make([][]rune, mapHeight)
- for i := range grid {
- grid[i] = make([]rune, mapWidth)
- for j := range grid[i] {
- grid[i][j] = ' '
- }
- }
-
- cx := mapWidth / 2
- cy := mapHeight / 2
-
- for pos, rid := range bg.posToRoom {
- gr := cy + pos[1]*2
- gc := cx + pos[0]*2
- if gr < 0 || gr >= mapHeight || gc < 0 || gc >= mapWidth {
- continue
- }
- if rid == roomID {
- grid[gr][gc] = '@'
- } else {
- grid[gr][gc] = roomMapSymbol(g, rid)
- }
- }
-
- for pos, rid := range bg.posToRoom {
- x, y := pos[0], pos[1]
-
- if rightID, ok := bg.posToRoom[[2]int{x + 1, y}]; ok {
- if exitsConnect(g, rid, rightID, world.East, world.West) {
- gr := cy + y*2
- gc := cx + x*2 + 1
- if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth {
- grid[gr][gc] = mg.connectorH
- }
- }
- }
-
- if bottomID, ok := bg.posToRoom[[2]int{x, y + 1}]; ok {
- if exitsConnect(g, rid, bottomID, world.South, world.North) {
- gr := cy + y*2 + 1
- gc := cx + x*2
- if gr >= 0 && gr < mapHeight && gc >= 0 && gc < mapWidth {
- grid[gr][gc] = mg.connectorV
- }
- }
- }
- }
-
- lines := make([]string, mapHeight)
- for i := range grid {
- lines[i] = string(grid[i])
- }
- return lines
-}