Files
zombie/parse.go
T

103 lines
2.5 KiB
Go

package zombie
import (
"bufio"
"fmt"
"github.com/wahyd4/zombie/models"
"log"
"os"
"strconv"
"strings"
)
const creatureSplitter = " "
var (
commandsMap = map[string]MoveCommand{
"U": &MoveUpCommand{},
"D": &MoveDownCommand{},
"L": &MoveLeftCommand{},
"R": &MoveRightCommand{},
}
)
// Application presents the actual the runner
type Application struct {
GridSize int
Zombie *models.Zombie
Creatures []*models.Creature
Commands []MoveCommand
}
// Init an application instance with given input file
func Init(input string) (*Application, error) {
file, err := os.Open(input)
if err != nil {
return nil, fmt.Errorf("failed to open file %v", err)
}
defer file.Close()
application := Application{
Zombie: &models.Zombie{},
}
scanner := bufio.NewScanner(file)
for lineIndex := 0; scanner.Scan(); lineIndex++ {
text := scanner.Text()
switch lineIndex {
case 0:
gridSize, _ := strconv.Atoi(text)
application.GridSize = gridSize
application.Zombie.GridSize = gridSize
case 1:
coordinate := parseCoordinate(text)
application.Zombie.Coordinate = coordinate
case 2:
creatures := parseCreatures(text)
application.Creatures = creatures
default:
commands := parseCommands(text)
application.Commands = commands
}
}
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("failed to read content from file %v", err)
}
return &application, nil
}
func parseCommands(commandString string) []MoveCommand {
commands := make([]MoveCommand, 0)
for _, commandRune := range commandString {
commands = append(commands, commandsMap[string(commandRune)])
}
return commands
}
func parseCoordinate(coordinate string) models.Coordinate {
coordinateWithoutBrackets := coordinate[1 : len(coordinate)-1]
coordinateArr := strings.Split(coordinateWithoutBrackets, ",")
if len(coordinateArr) != 2 {
log.Panic("coordinate string is not valid")
}
axisValues := make([]int, 0)
for _, axisValue := range coordinateArr {
value, err := strconv.Atoi(axisValue)
if err != nil {
log.Panic("cannot convert coordinate string into integers:" + err.Error())
}
axisValues = append(axisValues, value)
}
return models.Coordinate{XAxis: axisValues[0], YAxis: axisValues[1]}
}
func parseCreatures(coordinates string) []*models.Creature {
creatureCoordinates := strings.Split(coordinates, creatureSplitter)
creatures := make([]*models.Creature, 0)
for _, coordinate := range creatureCoordinates {
creatures = append(creatures, &models.Creature{Coordinate: parseCoordinate(coordinate)})
}
return creatures
}