package zombie import ( "fmt" "github.com/wahyd4/zombie/models" ) // Application presents the actual the runner type Application struct { gridSize int creatures []*models.Creature commands []MoveCommand currentZombie *models.Zombie nextZombie *TransformedZombie finishedZombies []*models.Zombie score int } // TransformedZombie defines the zombies transformed from creatures, // and these type of zombies are linked one by one type TransformedZombie struct { Zombie *models.Zombie Next *TransformedZombie } // Run starts zombie with movements func (app *Application) Run() { for _, command := range app.commands { command.Execute(app.currentZombie) collided, creature := app.checkCollisionWithCreature() if collided { app.transformCreatureToZombie(creature) app.IncreaseScore() } } app.recordedFinishedZombies() if app.hasTransformedZombie() { app.updateCurrentZombie() app.updateNextZombie() app.Run() } } // Stats prints out statistic information func (app *Application) Stats() { fmt.Printf("zombies score: %d \n", app.score) var locations string for _, zombie := range app.finishedZombies { locations += fmt.Sprintf("%s ", zombie.PrintLocation()) } fmt.Printf("zombies positions: %s \n", locations) } func (app *Application) checkCollisionWithCreature() (bool, *models.Creature) { for _, creature := range app.creatures { if app.currentZombie.Coordinate == creature.Coordinate { return true, creature } } return false, nil } func (app *Application) transformCreatureToZombie(creature *models.Creature) { app.appendTransformedZombie(&models.Zombie{ GridSize: app.gridSize, Coordinate: creature.Coordinate, }) app.removeCreature(creature) } func (app *Application) removeCreature(creature *models.Creature) { creatures := app.creatures var creatureIndex int for index, tempCreature := range creatures { if creature == tempCreature { creatureIndex = index } } // assign the last index item to the deleted index, then shrink the slice creatures[creatureIndex] = creatures[len(creatures)-1] creatures[len(creatures)-1] = nil app.creatures = creatures[:len(creatures)-1] } func (app *Application) appendTransformedZombie(zombie *models.Zombie) { next := app.nextZombie for next != nil { next = next.Next } app.nextZombie = &TransformedZombie{ Zombie: zombie, Next: nil, } } func (app *Application) IncreaseScore() { app.score++ } func (app *Application) recordedFinishedZombies() { app.finishedZombies = append(app.finishedZombies, app.currentZombie) } func (app *Application) updateNextZombie() { app.nextZombie = app.nextZombie.Next } func (app *Application) updateCurrentZombie() { app.currentZombie = app.nextZombie.Zombie } func (app *Application) hasTransformedZombie() bool { return app.nextZombie != nil }