package main import ( "bufio" "errors" "fmt" "math/rand" "os" "strings" "time" ) // SplitState represents the state of a split type SplitState string const ( Locked SplitState = "locked" Unlocked SplitState = "unlocked" Started SplitState = "started" Finished SplitState = "finished" ) // Split represents a split in the speedrun graph type Split struct { ID int Name string Icon string Dependencies []*Split Timestamp time.Time State SplitState } // Graph represents the speedrun graph type Graph struct { Splits []*Split Start *Split Final *Split } // NewSplit creates a new split func NewSplit(name, icon string) *Split { return &Split{ ID: rand.Intn(1000), // Randomly generating ID Name: name, Icon: icon, Timestamp: time.Time{}, State: Locked, } } // AddDependency adds a dependency to a split func (s *Split) AddDependency(dep *Split) { s.Dependencies = append(s.Dependencies, dep) } // ReadGraphFromFile reads graph from file representation func ReadGraphFromFile(filename string) (*Graph, error) { file, err := os.Open(filename) if err != nil { return nil, err } defer file.Close() scanner := bufio.NewScanner(file) splits := make(map[string]*Split) // Read lines from file for scanner.Scan() { line := scanner.Text() parts := strings.Split(line, ",") name := parts[0] icon := parts[1] dependencies := strings.Split(parts[2], "|") // Create split split := NewSplit(name, icon) splits[name] = split // Create dependencies for _, depName := range dependencies { dep := splits[depName] if dep != nil { split.AddDependency(dep) } } } // Set start and final splits var start, final *Split for _, split := range splits { if split.Name == "Start" { start = split } else if len(split.Dependencies) == 0 { if final != nil { fmt.Println(final.Name) return nil, errors.New("more than one final split found, only one split with no dependencies can exist") } final = split } } if start == nil { return nil, errors.New("no start split found, there should be a split with name 'Start'") } if final == nil { return nil, errors.New("no final split found, there should be the only split with no dependencies") } // Create graph graph := &Graph{ Splits: make([]*Split, 0, len(splits)), Start: start, Final: final, } // Append splits to graph for _, split := range splits { graph.Splits = append(graph.Splits, split) } return graph, nil } func main() { // Read graph from file graph, err := ReadGraphFromFile("graph.txt") if err != nil { fmt.Println("Error reading graph:", err) return } // Example usage fmt.Println("Graph:") fmt.Println("Start:", graph.Start.Name) fmt.Println("Final:", graph.Final.Name) }