|
|
@ -17,6 +17,8 @@ const ( |
|
|
|
WALL = '#' |
|
|
|
WALL = '#' |
|
|
|
SPACE = '.' |
|
|
|
SPACE = '.' |
|
|
|
PATH_LIMIT = 1000 |
|
|
|
PATH_LIMIT = 1000 |
|
|
|
|
|
|
|
RENDER = true |
|
|
|
|
|
|
|
SHOW_RENDER = true |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type Position struct { |
|
|
|
type Position struct { |
|
|
@ -24,6 +26,10 @@ type Position struct { |
|
|
|
y int |
|
|
|
y int |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Enemy struct { |
|
|
|
|
|
|
|
hp int |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type Game struct { |
|
|
|
type Game struct { |
|
|
|
screen tcell.Screen |
|
|
|
screen tcell.Screen |
|
|
|
level [][]rune |
|
|
|
level [][]rune |
|
|
@ -31,7 +37,7 @@ type Game struct { |
|
|
|
status string |
|
|
|
status string |
|
|
|
width int |
|
|
|
width int |
|
|
|
height int |
|
|
|
height int |
|
|
|
enemies []Position |
|
|
|
enemies map[Position]Enemy |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) DrawStatus(msg string) { |
|
|
|
func (game *Game) DrawStatus(msg string) { |
|
|
@ -58,12 +64,14 @@ func (game *Game) DrawMap() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) Render() { |
|
|
|
func (game *Game) Render() { |
|
|
|
|
|
|
|
if !RENDER { return } |
|
|
|
|
|
|
|
|
|
|
|
game.screen.Clear() |
|
|
|
game.screen.Clear() |
|
|
|
|
|
|
|
|
|
|
|
game.DrawMap() |
|
|
|
game.DrawMap() |
|
|
|
game.DrawEntity('@', game.player, tcell.ColorYellow) |
|
|
|
game.DrawEntity('@', game.player, tcell.ColorYellow) |
|
|
|
|
|
|
|
|
|
|
|
for _, pos := range game.enemies { |
|
|
|
for pos, _ := range game.enemies { |
|
|
|
game.DrawEntity('G', pos, tcell.ColorRed) |
|
|
|
game.DrawEntity('G', pos, tcell.ColorRed) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -73,12 +81,21 @@ func (game *Game) Render() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) Exit() { |
|
|
|
func (game *Game) Exit() { |
|
|
|
|
|
|
|
if RENDER { |
|
|
|
game.screen.Fini() |
|
|
|
game.screen.Fini() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
os.Exit(0) |
|
|
|
os.Exit(0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) Occupied(x int, y int) bool { |
|
|
|
func (game *Game) Occupied(x int, y int) bool { |
|
|
|
return game.level[y][x] != '.' || !game.Inbounds(Position{x, y}, 1) |
|
|
|
pos := Position{x, y} |
|
|
|
|
|
|
|
_, is_enemy := game.enemies[pos] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Inbounds comes first to prevent accessing level with bad x,y
|
|
|
|
|
|
|
|
return !game.Inbounds(pos, 1) || |
|
|
|
|
|
|
|
game.level[y][x] == WALL || |
|
|
|
|
|
|
|
is_enemy |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) MovePlayer(x_delta int, y_delta int) { |
|
|
|
func (game *Game) MovePlayer(x_delta int, y_delta int) { |
|
|
@ -88,10 +105,10 @@ func (game *Game) MovePlayer(x_delta int, y_delta int) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) HandleKeys(ev *tcell.EventKey) { |
|
|
|
func (game *Game) HandleKeys(ev *tcell.EventKey) bool { |
|
|
|
switch ev.Key() { |
|
|
|
switch ev.Key() { |
|
|
|
case tcell.KeyEscape: |
|
|
|
case tcell.KeyEscape: |
|
|
|
game.Exit() |
|
|
|
return false |
|
|
|
case tcell.KeyUp: |
|
|
|
case tcell.KeyUp: |
|
|
|
game.MovePlayer(0, -1) |
|
|
|
game.MovePlayer(0, -1) |
|
|
|
case tcell.KeyDown: |
|
|
|
case tcell.KeyDown: |
|
|
@ -104,17 +121,23 @@ func (game *Game) HandleKeys(ev *tcell.EventKey) { |
|
|
|
|
|
|
|
|
|
|
|
switch ev.Rune() { |
|
|
|
switch ev.Rune() { |
|
|
|
case 'q': |
|
|
|
case 'q': |
|
|
|
game.Exit() |
|
|
|
return false |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (game *Game) HandleEvents() { |
|
|
|
func (game *Game) HandleEvents() bool { |
|
|
|
|
|
|
|
if !RENDER { return false } |
|
|
|
|
|
|
|
|
|
|
|
switch ev := game.screen.PollEvent().(type) { |
|
|
|
switch ev := game.screen.PollEvent().(type) { |
|
|
|
case *tcell.EventResize: |
|
|
|
case *tcell.EventResize: |
|
|
|
game.screen.Sync() |
|
|
|
game.screen.Sync() |
|
|
|
case *tcell.EventKey: |
|
|
|
case *tcell.EventKey: |
|
|
|
game.HandleKeys(ev) |
|
|
|
return game.HandleKeys(ev) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func MakeGame(width int, height int) (*Game) { |
|
|
|
func MakeGame(width int, height int) (*Game) { |
|
|
@ -125,14 +148,17 @@ func MakeGame(width int, height int) (*Game) { |
|
|
|
|
|
|
|
|
|
|
|
game.width = width |
|
|
|
game.width = width |
|
|
|
game.height = height |
|
|
|
game.height = height |
|
|
|
|
|
|
|
game.enemies = make(map[Position]Enemy) |
|
|
|
|
|
|
|
|
|
|
|
game.level = make([][]rune, height, height) |
|
|
|
game.level = make([][]rune, height, height) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if RENDER { |
|
|
|
game.screen, err = tcell.NewScreen() |
|
|
|
game.screen, err = tcell.NewScreen() |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
|
|
|
|
|
|
|
|
err = game.screen.Init() |
|
|
|
err = game.screen.Init() |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
game.player = Position{1,1} |
|
|
|
game.player = Position{1,1} |
|
|
|
|
|
|
|
|
|
|
@ -236,9 +262,11 @@ func (game *Game) HuntAndKill() []Position { |
|
|
|
on = nb |
|
|
|
on = nb |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if SHOW_RENDER { |
|
|
|
game.Render() |
|
|
|
game.Render() |
|
|
|
time.Sleep(50 * time.Millisecond) |
|
|
|
time.Sleep(50 * time.Millisecond) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return dead_ends |
|
|
|
return dead_ends |
|
|
|
} |
|
|
|
} |
|
|
@ -288,8 +316,7 @@ func (game *Game) MakeMap() []Position { |
|
|
|
func (game *Game) PlaceEnemies(places []Position) { |
|
|
|
func (game *Game) PlaceEnemies(places []Position) { |
|
|
|
for _, pos := range places { |
|
|
|
for _, pos := range places { |
|
|
|
if rand.Int() % 2 == 0 { |
|
|
|
if rand.Int() % 2 == 0 { |
|
|
|
game.enemies = append(game.enemies, pos) |
|
|
|
game.enemies[pos] = Enemy{10} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -300,13 +327,14 @@ func main() { |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
if err != nil { log.Fatal(err) } |
|
|
|
dbg = log.New(out, "", log.LstdFlags) |
|
|
|
dbg = log.New(out, "", log.LstdFlags) |
|
|
|
|
|
|
|
|
|
|
|
game := MakeGame(27, 17) |
|
|
|
game := MakeGame(43, 27) |
|
|
|
dead_ends := game.MakeMap() |
|
|
|
dead_ends := game.MakeMap() |
|
|
|
game.PlaceEnemies(dead_ends) |
|
|
|
game.PlaceEnemies(dead_ends) |
|
|
|
game.Render() |
|
|
|
game.Render() |
|
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
for game.HandleEvents() { |
|
|
|
game.HandleEvents() |
|
|
|
|
|
|
|
game.Render() |
|
|
|
game.Render() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
game.Exit() |
|
|
|
} |
|
|
|
} |
|
|
|