diff --git a/main.go b/main.go index 695b1cb..b0d72ff 100644 --- a/main.go +++ b/main.go @@ -34,13 +34,15 @@ type Position struct { type Enemy struct { hp int + pos Position + damage int } type Game struct { screen tcell.Screen level Map paths Paths - player Position + player Enemy status string width int height int @@ -104,7 +106,7 @@ func (game *Game) Render() { game.DrawPaths() } - game.DrawEntity('@', game.player, tcell.ColorYellow) + game.DrawEntity('@', game.player.pos, tcell.ColorYellow) for pos, _ := range game.enemies { game.DrawEntity('G', pos, tcell.ColorRed) @@ -126,7 +128,7 @@ func (game *Game) Exit() { func (game *Game) Occupied(x int, y int) bool { pos := Position{x, y} _, is_enemy := game.enemies[pos] - is_player := pos == game.player + is_player := pos == game.player.pos // Inbounds comes first to prevent accessing level with bad x,y return !game.Inbounds(pos, 1) || @@ -135,7 +137,7 @@ func (game *Game) Occupied(x int, y int) bool { is_player } -func (game *Game) Death() { +func (game *Game) EnemyDeath() { is_dead := make([]Position, 0, len(game.enemies)) for pos, enemy := range game.enemies { @@ -149,28 +151,37 @@ func (game *Game) Death() { } } +func (game *Game) ApplyDamage(attacker *Enemy, defender *Enemy) { + damage := rand.Int() % attacker.damage + defender.hp -= damage + if damage == 0 { + game.Status("MISSED!") + } else if defender.hp > 0 { + game.Status(fmt.Sprintf("HIT %d damage", damage)) + } else { + game.Status("DEAD!") + } +} + func (game *Game) Attack(target Position) { enemy, hit_enemy := game.enemies[target] if hit_enemy { - damage := rand.Int() % 10 - enemy.hp -= damage - if damage == 0 { - game.Status("YOU MISSED!") - } else if enemy.hp > 0 { - game.Status(fmt.Sprintf("HIT %d damage", damage)) - } else { - game.Status("ENEMY DEAD!") - } + game.ApplyDamage(&game.player, enemy) + game.ApplyDamage(enemy, &game.player) } } func (game *Game) MovePlayer(x_delta int, y_delta int) { - target := Position{game.player.x + x_delta, game.player.y + y_delta} + target := Position{ + game.player.pos.x + x_delta, + game.player.pos.y + y_delta, + } + if game.Occupied(target.x, target.y) { game.Attack(target) } else { - game.player = target + game.player.pos = target } } @@ -209,11 +220,19 @@ func (game *Game) HandleEvents() bool { return true } -func MakeGame(width int, height int) (*Game) { - var game Game +func (game *Game) InitScreen() { + encoding.Register() + var err error + game.screen, err = tcell.NewScreen() + if err != nil { log.Fatal(err) } - encoding.Register() + err = game.screen.Init() + if err != nil { log.Fatal(err) } +} + +func MakeGame(width int, height int) (*Game) { + var game Game game.width = width game.height = height @@ -222,15 +241,7 @@ func MakeGame(width int, height int) (*Game) { game.level = make(Map, height, height) game.paths = make(Paths, height, height) - if RENDER { - game.screen, err = tcell.NewScreen() - if err != nil { log.Fatal(err) } - - err = game.screen.Init() - if err != nil { log.Fatal(err) } - } - - game.player = Position{1,1} + game.player = Enemy{20, Position{1,1}, 4} return &game } @@ -401,7 +412,7 @@ func (game *Game) PathAddNeighbors(neighbors []Position, closed Map, near Positi func (game *Game) PathEnemies() { in_grid := make([][]int, game.height, game.height) game.FillPaths(in_grid, 1) - in_grid[game.player.y][game.player.x] = 0 + in_grid[game.player.pos.y][game.player.pos.x] = 0 game.FillPaths(game.paths, PATH_LIMIT) closed := game.CloneMap() @@ -496,27 +507,42 @@ func (game *Game) MakeMap() []Position { func (game *Game) PlaceEnemies(places []Position) { for _, pos := range places { if rand.Int() % 2 == 0 { - game.enemies[pos] = &Enemy{10} + game.enemies[pos] = &Enemy{10, pos, 4} } } } +func (game *Game) Restart() { + game.Status("YOU DIED! Try again.") + game.player.hp = 20 + game.player.pos = Position{1,1} + game.screen.Clear() +} + func main() { out, err := os.Create("debug.log") if err != nil { log.Fatal(err) } dbg = log.New(out, "", log.LstdFlags) game := MakeGame(27, 17) - dead_ends := game.MakeMap() - game.PlaceEnemies(dead_ends) - game.Render() - - for game.HandleEvents() { - game.Death() - game.PathEnemies() - game.EnemyMovement() + game.InitScreen() + + for { + dead_ends := game.MakeMap() + game.PlaceEnemies(dead_ends) game.Render() - } - game.Exit() + for game.HandleEvents() && game.player.hp > 0 { + game.EnemyDeath() + game.PathEnemies() + game.EnemyMovement() + game.Render() + } + + if game.player.hp <= 0 { + game.Restart() + } else { + game.Exit() + } + } }