Add session and Complete Split
This commit is contained in:
parent
66d98098c5
commit
2dc039dff1
45
api.go
Normal file
45
api.go
Normal file
@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// CompleteSplit marks a split as finished and unlocks its dependent splits if they have no other dependencies
|
||||
func CompleteSplit(session *Session, split *Split) error {
|
||||
fmt.Printf("Splitting split %s (%s)\n", split.Name, split.State)
|
||||
if split.State == Locked {
|
||||
fmt.Println("Death!!")
|
||||
return errors.New("cannot complete a split that is locked")
|
||||
}
|
||||
|
||||
// Set provided split to finished
|
||||
split.State = Finished
|
||||
|
||||
// Iterate over dependencies
|
||||
for _, dep := range split.Dependencies {
|
||||
// Check if dependency has no other dependencies
|
||||
hasOtherDependencies := false
|
||||
for _, otherDep := range session.Graph.Splits {
|
||||
if otherDep == dep || otherDep.State == Finished {
|
||||
continue
|
||||
}
|
||||
for _, otherDep2 := range otherDep.Dependencies {
|
||||
if otherDep2 == dep {
|
||||
hasOtherDependencies = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasOtherDependencies {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// If no other dependencies, set dependency to unlocked
|
||||
if !hasOtherDependencies {
|
||||
dep.State = Unlocked
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
124
graph.go
Normal file
124
graph.go
Normal file
@ -0,0 +1,124 @@
|
||||
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
|
||||
}
|
138
main.go
138
main.go
@ -1,127 +1,16 @@
|
||||
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() {
|
||||
// Create a session with a random ID and read the graph from file
|
||||
session := &Session{
|
||||
ID: generateRandomID(),
|
||||
Graph: nil,
|
||||
}
|
||||
|
||||
// Read graph from file
|
||||
graph, err := ReadGraphFromFile("graph.txt")
|
||||
if err != nil {
|
||||
@ -129,8 +18,17 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Example usage
|
||||
// Set the graph for the session
|
||||
session.Graph = graph
|
||||
|
||||
fmt.Println("Session ID:", session.ID)
|
||||
fmt.Println("Graph:")
|
||||
fmt.Println("Start:", graph.Start.Name)
|
||||
fmt.Println("Final:", graph.Final.Name)
|
||||
PrettyPrintGraph(graph)
|
||||
|
||||
CompleteSplit(session, graph.Start)
|
||||
CompleteSplit(session, graph.Splits[1])
|
||||
CompleteSplit(session, graph.Splits[2])
|
||||
|
||||
PrettyPrintGraph(graph)
|
||||
fmt.Println("Done.")
|
||||
}
|
||||
|
23
print.go
Normal file
23
print.go
Normal file
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PrettyPrintGraph prints the entire graph in a readable format
|
||||
func PrettyPrintGraph(graph *Graph) {
|
||||
// Print start split
|
||||
printSplit(graph.Start, 0)
|
||||
}
|
||||
|
||||
// printSplit prints a split and its dependencies recursively with proper indentation
|
||||
func printSplit(split *Split, indent int) {
|
||||
// Print split information
|
||||
fmt.Printf("%s- %s (%s)\n", strings.Repeat(" ", indent), split.Name, split.State)
|
||||
|
||||
// Recursively print dependencies
|
||||
for _, dep := range split.Dependencies {
|
||||
printSplit(dep, indent+1)
|
||||
}
|
||||
}
|
7
session.go
Normal file
7
session.go
Normal file
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
// Session represents a user session
|
||||
type Session struct {
|
||||
ID string
|
||||
Graph *Graph
|
||||
}
|
13
util.go
Normal file
13
util.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "math/rand"
|
||||
|
||||
// generateRandomID generates a random session ID
|
||||
func generateRandomID() string {
|
||||
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
b := make([]byte, 10)
|
||||
for i := range b {
|
||||
b[i] = charset[rand.Intn(len(charset))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user