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.

123 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)
}
}
}