A Go version of the https://lcthw.dev/learn-code-the-hard-way/curseyou-python-rogue that makes a tiny Rogue in Go.
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
2.8 KiB
122 lines
2.8 KiB
package main
|
|
|
|
import (
|
|
"slices"
|
|
)
|
|
|
|
func (game *Game) FillPaths(target Paths, setting int) {
|
|
for y := 0 ; y < game.Height; y++ {
|
|
target[y] = slices.Repeat([]int{setting}, game.Width)
|
|
}
|
|
}
|
|
|
|
func (game *Game) Neighbors(near Position) []Position {
|
|
result := make([]Position, 0, 4)
|
|
points := compass(near, 2)
|
|
|
|
for _, pos := range points {
|
|
if game.Inbounds(pos, 0) {
|
|
result = append(result, pos)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (game *Game) NeighborWalls(pos Position) []Position {
|
|
neighbors := game.Neighbors(pos)
|
|
result := make([]Position, 0)
|
|
|
|
for _, at := range neighbors {
|
|
cell := game.Level[at.Y][at.X]
|
|
|
|
if cell == WALL {
|
|
result = append(result, at)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (game *Game) PathAddNeighbors(neighbors []Position, closed Map, near Position) []Position {
|
|
points := compass(near, 1)
|
|
|
|
for _, pos := range points {
|
|
// NOTE: if you also add !game.Occupied(pos.x, pos.y) it ????
|
|
if closed[pos.Y][pos.X] == SPACE {
|
|
closed[pos.Y][pos.X] = WALL
|
|
neighbors = append(neighbors, pos)
|
|
}
|
|
}
|
|
|
|
return neighbors
|
|
}
|
|
|
|
func (game *Game) CalculatePaths() {
|
|
in_grid := make([][]int, game.Height, game.Height)
|
|
game.FillPaths(in_grid, 1)
|
|
in_grid[game.Player.Pos.Y][game.Player.Pos.X] = 0
|
|
|
|
game.FillPaths(game.Paths, PATH_LIMIT)
|
|
closed := game.CloneMap()
|
|
starting_pixels := make([]Position, 0, 10)
|
|
open_pixels := make([]Position, 0, 10)
|
|
|
|
counter := 0
|
|
|
|
for counter < game.Height * game.Width {
|
|
x := counter % game.Width
|
|
y := counter / game.Width
|
|
|
|
if in_grid[y][x] == 0 {
|
|
game.Paths[y][x] = 0
|
|
closed[y][x] = WALL
|
|
starting_pixels = append(starting_pixels, Position{x, y})
|
|
}
|
|
|
|
counter += 1
|
|
}
|
|
|
|
for _, pos := range starting_pixels {
|
|
open_pixels = game.PathAddNeighbors(open_pixels, closed, pos)
|
|
}
|
|
|
|
counter = 1
|
|
for counter < PATH_LIMIT && len(open_pixels) > 0 {
|
|
next_open := make([]Position, 0, 10)
|
|
for _, pos := range open_pixels {
|
|
game.Paths[pos.Y][pos.X] = counter
|
|
next_open = game.PathAddNeighbors(next_open, closed, pos)
|
|
}
|
|
open_pixels = next_open
|
|
counter += 1
|
|
}
|
|
|
|
for _, pos := range open_pixels {
|
|
game.Paths[pos.Y][pos.X] = counter
|
|
}
|
|
}
|
|
|
|
func (game *Game) EnemyPathing() {
|
|
for enemy_at, _ := range game.Enemies {
|
|
// get the four directions
|
|
dirs := compass(enemy_at, 1)
|
|
|
|
// sort by closest path number
|
|
slices.SortFunc(dirs, func(a Position, b Position) int {
|
|
return game.Paths[a.Y][a.X] - game.Paths[b.Y][b.X]
|
|
})
|
|
|
|
// 0 dir is now the best direction
|
|
move_to := dirs[0]
|
|
|
|
// can we hear the player? occupied?
|
|
can_hear := game.Paths[move_to.Y][move_to.X] < HEARING_DISTANCE
|
|
occupied := game.Occupied(move_to)
|
|
|
|
if can_hear && !occupied {
|
|
// move the enemy in the best direction
|
|
game.MoveEnemy(enemy_at, move_to)
|
|
}
|
|
}
|
|
}
|
|
|