diff --git a/.gitignore b/.gitignore index adf8f72..af1d6e4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ # Go workspace file go.work +GraphSplit diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e5193dc --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module GraphSplit + +go 1.22.2 diff --git a/graph.txt b/graph.txt new file mode 100644 index 0000000..ee04d18 --- /dev/null +++ b/graph.txt @@ -0,0 +1,4 @@ +Split4,icon4, +Split3,icon3,Split4 +Split2,icon2,Split4 +Start,icon1,Split2|Split3 \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..80b134a --- /dev/null +++ b/main.go @@ -0,0 +1,136 @@ +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) +}