125 lines
2.5 KiB
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
|
|
}
|