GraphSplit/graph.go

125 lines
2.5 KiB
Go

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(1000000), // 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,
}
graph.Start.State = Unlocked
// Append splits to graph
for _, split := range splits {
graph.Splits = append(graph.Splits, split)
}
return graph, nil
}