From fc922fe6187f5e45d81c521d06aff7b9213a622b Mon Sep 17 00:00:00 2001 From: Patrick Fairbank Date: Tue, 24 Jun 2014 23:56:21 -0700 Subject: [PATCH] Fixed bug in scheduling with excess matches. --- schedule.go | 7 ++++++- schedule_test.go | 5 +++++ setup_schedule.go | 8 ++++---- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/schedule.go b/schedule.go index 1448586..ef17628 100644 --- a/schedule.go +++ b/schedule.go @@ -8,6 +8,7 @@ package main import ( "encoding/csv" "fmt" + "math" "math/rand" "os" "strconv" @@ -29,6 +30,10 @@ func BuildRandomSchedule(teams []Team, scheduleBlocks []ScheduleBlock, matchType numTeams := len(teams) numMatches := countMatches(scheduleBlocks) matchesPerTeam := int(float32(numMatches*teamsPerMatch) / float32(numTeams)) + + // Adjust the number of matches to remove any excess from non-perfect block scheduling. + numMatches = int(math.Ceil(float64(numTeams) * float64(matchesPerTeam) / teamsPerMatch)) + file, err := os.Open(fmt.Sprintf("%s/%d_%d.csv", schedulesDir, numTeams, matchesPerTeam)) if err != nil { return nil, fmt.Errorf("No schedule template exists for %d teams and %d matches", numTeams, matchesPerTeam) @@ -77,7 +82,7 @@ func BuildRandomSchedule(teams []Team, scheduleBlocks []ScheduleBlock, matchType // Fill in the match times. matchIndex := 0 for _, block := range scheduleBlocks { - for i := 0; i < block.NumMatches; i++ { + for i := 0; i < block.NumMatches && matchIndex < numMatches; i++ { matches[matchIndex].Time = block.StartTime.Add(time.Duration(i*block.MatchSpacingSec) * time.Second) matchIndex++ } diff --git a/schedule_test.go b/schedule_test.go index 22aa5c4..ac178b4 100644 --- a/schedule_test.go +++ b/schedule_test.go @@ -67,6 +67,11 @@ func TestScheduleTeams(t *testing.T) { Red3: 115, Blue1: 110, Blue2: 114, Blue3: 102}, matches[4]) assert.Equal(t, Match{Type: "test", DisplayName: "6", Time: time.Unix(300, 0).UTC(), Red1: 118, Red2: 105, Red3: 106, Blue1: 107, Blue2: 104, Blue3: 116}, matches[5]) + + // Check with excess room for matches in the schedule. + scheduleBlocks = []ScheduleBlock{{time.Unix(0, 0).UTC(), 7, 60}} + matches, err = BuildRandomSchedule(teams, scheduleBlocks, "test") + assert.Nil(t, err) } func TestScheduleTiming(t *testing.T) { diff --git a/setup_schedule.go b/setup_schedule.go index 66542cf..2c5e9d1 100644 --- a/setup_schedule.go +++ b/setup_schedule.go @@ -34,11 +34,13 @@ func ScheduleGetHandler(w http.ResponseWriter, r *http.Request) { // Generates the schedule and presents it for review without saving it to the database. func ScheduleGeneratePostHandler(w http.ResponseWriter, r *http.Request) { r.ParseForm() + cachedMatchType = r.PostFormValue("matchType") scheduleBlocks, err := getScheduleBlocks(r) if err != nil { renderSchedule(w, r, "Incomplete or invalid schedule block parameters specified.") return } + cachedScheduleBlocks = scheduleBlocks // Build the schedule. teams, err := db.GetAllTeams() @@ -61,6 +63,7 @@ func ScheduleGeneratePostHandler(w http.ResponseWriter, r *http.Request) { renderSchedule(w, r, fmt.Sprintf("Error generating schedule: %s.", err.Error())) return } + cachedMatches = matches // Determine each team's first match. teamFirstMatches := make(map[int]string) @@ -78,11 +81,8 @@ func ScheduleGeneratePostHandler(w http.ResponseWriter, r *http.Request) { checkTeam(match.Blue2) checkTeam(match.Blue3) } - - cachedMatchType = r.PostFormValue("matchType") - cachedScheduleBlocks = scheduleBlocks - cachedMatches = matches cachedTeamFirstMatches = teamFirstMatches + http.Redirect(w, r, "/setup/schedule", 302) }