diff --git a/admin_endpoints.go b/admin_endpoints.go index e51dfa1..951c875 100644 --- a/admin_endpoints.go +++ b/admin_endpoints.go @@ -46,6 +46,7 @@ func handleAdmin(w http.ResponseWriter, req *http.Request) { case "mode": handleAdminSetMode(w, req, page) default: + page.TemplateData = getCondorcetResult() page.show("admin-main.html", w) } } diff --git a/admin_votes.go b/admin_votes.go index c4f6e24..e24b712 100644 --- a/admin_votes.go +++ b/admin_votes.go @@ -1,84 +1,110 @@ package main import ( - "fmt" + "errors" "net/http" "time" "github.com/gorilla/mux" ) +// getCondorcetResult returns the ranking of teams based on the condorcet method +// https://en.wikipedia.org/wiki/Condorcet_method func getCondorcetResult() []Team { + type teamPair struct { + winner *Team + loser *Team + majority float32 + } + var allPairs []teamPair var ret []Team - type rankedTeam struct { - tm *Team - wins map[string]int - losses map[string]int + for i := 0; i < len(site.Teams); i++ { + for j := i + 1; j < len(site.Teams); j++ { + // For each pairing find a winner + winner, pct, _ := findWinnerBetweenTeams(&site.Teams[i], &site.Teams[j]) + if winner != nil { + newPair := new(teamPair) + newPair.winner = winner + if winner.UUID == site.Teams[i].UUID { + newPair.loser = &site.Teams[j] + } else { + newPair.loser = &site.Teams[i] + } + newPair.majority = pct + allPairs = append(allPairs, *newPair) + } + } } - // Build our Ranked Teams slice - allRanks := make(map[string]rankedTeam) + teamWins := make(map[string]int) for i := range site.Teams { - rt := new(rankedTeam) - rt.wins = make(map[string]int) - rt.losses = make(map[string]int) - rt.tm = &site.Teams[i] - for j := range site.Teams { - if site.Teams[i].UUID != site.Teams[j].UUID { - rt.wins[site.Teams[j].UUID] = 0 - rt.losses[site.Teams[j].UUID] = 0 - } - } - allRanks[site.Teams[i].UUID] = *rt + teamWins[site.Teams[i].UUID] = 0 } - /* - Go through all votes, for each choice (ct): - * Go through all teams (tm) - * if tm was processed earlier, do nothing - * otherwise mark a win for ct against tm, and a loss for tm against cm - */ - // Now go through all of the votes and figure wins/losses for each team - for _, vt := range site.Votes { - for i := 0; i < len(vt.Choices); i++ { - var p []string - for j := i; j < len(vt.Choices); j++ { - // vt.Choices[i] wins against vt.Choices[j] - p = append(p, vt.Choices[j].Team) - allRanks[vt.Choices[i].Team].wins[vt.Choices[j].Team]++ - allRanks[vt.Choices[j].Team].losses[vt.Choices[i].Team]++ - } - // Now go through site.Teams for every team that isn't vt.Choices[i] - // and isn't in 'p', mark it as a loss for the unused team - for j := range site.Teams { - var isUsed bool - if site.Teams[j].UUID == vt.Choices[i].Team { - continue - } - for k := range p { - if site.Teams[j].UUID == p[k] { - isUsed = true - } - } - if !isUsed { - allRanks[vt.Choices[i].Team].wins[site.Teams[j].UUID]++ - allRanks[site.Teams[j].UUID].losses[vt.Choices[i].Team]++ - } - } - } + for i := range allPairs { + teamWins[allPairs[i].winner.UUID]++ } - for _, v := range allRanks { - fmt.Println("\n" + v.tm.UUID) - fmt.Println(" Wins:") - for k, v := range v.wins { - fmt.Print(" ", k, ":", v, "\n") + for len(teamWins) > 0 { //len(ret) <= len(site.Teams) { + topWins := 0 + var topTeam string + for k, v := range teamWins { + // If this team is already in ret, carry on + if uuidIsInTeamSlice(k, ret) { + continue + } + // If this is the last key in teamWins, just add it + if len(teamWins) == 1 || v > topWins { + topWins = v + topTeam = k + } } - fmt.Println(" Losses:") - for k, v := range v.losses { - fmt.Print(" ", k, ":", v, "\n") + // Remove topTeam from map + delete(teamWins, topTeam) + // Now add topTeam to ret + addTeam := site.getTeamByUUID(topTeam) + if addTeam != nil { + ret = append(ret, *addTeam) + } else { + break } } return ret } +// This is a helper function for calculating results +func uuidIsInTeamSlice(uuid string, sl []Team) bool { + for _, v := range sl { + if v.UUID == uuid { + return true + } + } + return false +} + +// findWinnerBetweenTeams returns the team that got the most votes +// and the percentage of votes they received +// or an error if a winner couldn't be determined. +func findWinnerBetweenTeams(tm1, tm2 *Team) (*Team, float32, error) { + // tally gets incremented for a tm1 win, decremented for a tm2 win + var tm1votes, tm2votes float32 + for _, v := range site.Votes { + for _, chc := range v.Choices { + if chc.Team == tm1.UUID { + tm1votes++ + break + } else if chc.Team == tm2.UUID { + tm2votes++ + break + } + } + } + ttlVotes := tm1votes + tm2votes + if tm1votes > tm2votes { + return tm1, 100 * (tm1votes / ttlVotes), nil + } else if tm1votes < tm2votes { + return tm2, 100 * (tm2votes / ttlVotes), nil + } + return nil, 50, errors.New("Unable to determine a winner") +} + func getInstantRunoffResult() []Team { var ret []Team return ret @@ -95,6 +121,7 @@ func handleAdminVotes(w http.ResponseWriter, req *http.Request, page *pageData) } type votePageData struct { AllVotes []vpdVote + Results []Team } vpd := new(votePageData) for i := range site.Votes { @@ -111,8 +138,8 @@ func handleAdminVotes(w http.ResponseWriter, req *http.Request, page *pageData) } vpd.AllVotes = append(vpd.AllVotes, *v) } + vpd.Results = getCondorcetResult() page.TemplateData = vpd - _ = getCondorcetResult() switch vars["function"] { default: diff --git a/assets.go b/assets.go index 177d019..a7ec7bc 100644 --- a/assets.go +++ b/assets.go @@ -202,28 +202,28 @@ Y8Pj6dAeZ3gBzLZbhMnSW8r0f78+9y+zlDVuQ3ZNXD8zD+/mGzZjDfK53gEAAP//D/6XxHkAAAA= "/assets/css/gjvote.css": { local: "assets/css/gjvote.css", - size: 3763, - modtime: 1499342234, + size: 3784, + modtime: 1499536516, compressed: ` H4sIAAAAAAAA/6xX62rrOBD+36cQhIUWVsbpaU4bF8pCT/sesqXYQ2TJSHKSdum7L7rYsWy5e2GhP2Jp -7vPNN2pjWo7+vEGoBYEbBnVjCrTN89+eb75ubkpJP9xtJblUBdo8Pj4+rwkTJ2nYxWDKKqmIASkKJKRg -7p7CKaukMEwYJ9kRSkHUBdruukva6ui45KQ6jlYawg/OxBmoaQq0CxFkDSOUKZ8PUTUIzNnBFCj3152C -lqg4ozx/fGKP0T0uaydSkupYK9kLihPSILreZAfgLM4m27EWZT9Za8OnoDtOPgoEgoNguOTS5oFQKRVl -qkDb7oK05EDRpqoqf3PBuiFUnq2WZgblTupHd0EbSulVGytCodcFerD1G0NSRBxB1Nh9xWXydZ5p76an -UUSvr6/PQ0sJh1oUqGLCMOXB0RsjRab7sgWDT9LYQtgoslaeGIZKCl/pXmlbPKGxYho+PRo2LRP9NLqh -4wMCHkK0ndTgkaQYJwZO7DnqTYE22/32aftkj8+sPILB8sTUgcsz1pWSnLu+GNlXzcR11vWKYfsTW9iA -8E1f6VhKTUgrckwNSIyG7QwMIwpWhgWhcwOGYd2RitnDsyLdNAbn3tc/FXRcNlJqyXvjTo3sChQKq3yd -w1eYFyewjc/UMJL+NKTqQvwmCTtQPk5pjGyjVs+Q6J2OuAuWZ+la6iAgwniPGQ8VS+cb5+j8DLhKTPeA -ozXPLz1fI4aJqmMoqeDTqvEAQac3wvJSIH/sx7atM9P0bSkIeMEJC4bRvgqsFWIE1ah8v57p29tboDwP -1JjCdoNTB8AJnc6vsAbK9JJvdyn8zFRPTBmoCJ9quwbFyh49E+0SaryMazsWykZw3USBtuyhvc5cLItr -d+ruPb8tBCa0F0QwCU1NiSE0ZLe8GSImvZHOoCElZ4NjY1fui6HfReAVhs4F2UXznBQyByl9vulZ8xzv -kGB5zXMKZkpJtQb1X7/yPM8nTLB5f39f2jCyrjnDB1B6HoBHxLiAYjLwDU+JfCUdtEBp2MGzxRazmEcm -3kbO/OGyHClHnCwTsfrf55GS+C8RRSEVFLRtL13rUdjcw+d+vw+sJinhbj1y4t9BJ9BQAgfzUaAGKGVi -nU3DY2pCpuH3ygofvtMj8olBUHZxYnmap1Rdktv8dxT+st1dIo0XCqf4mROVObBomLdktRx+ky+gIbIY -WMMmXLxgVwb2j5ZRIOjWPnBDkA85a+9c1NeH0HI/Lks5bc0BLsw9B79uRjuLp0FiVS7Ex40yUwABBgh/ -jmILgTgjiwWfSiER8AxKtsCe5cOBNz55zc9mZrTuBIndQtmBE938K+HsSnN/Q3QR1QW0LKzpvqqY1uv2 -7u/35LD/1l70D9J6HldM6UoxJhARFN225BLg9WNn35134YFw8tRhTSvJsY2qQ5yUjGfDmfsKTpd785+4 -/PlgHfrDCcyf/v8w/goAAP//zWrQALMOAAA= +Lt/MfDOjNqbl6M8bhFoQuGFQN6ZA2zz/7fnm6+amlPTD3VaSS1WgzePj4/OaMHGShl0MpqySihiQokBC +CubuKZyySgrDhHGSHaEURF2g7a67pK2OjktOquNopSH84EycgZqmQLuAIGsYoUz5eIiqQWDODqZAub/u +FLRExRHl+eMTe4zucVk7kZJUx1rJXlCckAbR9SY7AGdxNNmOtSj7yVoLn4LuOPkoEAgOguGSSxsHQqVU +lKkCbbsL0pIDRZuqqvzNBeuGUHm2WpoZlDupH90FbSilV22sCIVeF+jB5m+EpIg4gqix+4rT5PM8095N +TyNEr6+vz0NJCYdaFKhiwjDlydEbI0Wm+7IFg0/S2ERYFFkrTwxDJYXPdK+0TZ7QWDENn54Nm5aJfopu +qPjAgIeAtpMaPJMU48TAiT1HtSnQZrvfPm2f7PGZlUcwWJ6YOnB5xrpSknNXFyP7qpm4zrpeMWx/Yksb +EL7oKxVLqQlpRY6pBonZsJ2RYWTBSrMgdG7AMKw7UjF7eFakm2Jw7n3+U6DjtJFSS94bd2pkV6CQWOXz +HL5CvziBbXymhpb0pyFUB/GbIGxDeZzSGNlGpZ4x0TsdeRcsz8K1o4OACO09RjxkLB1vHKPzM/Aq0d0D +j9Y8v/R8bTBMVN2Ekgo+rRoPFHR6Iy0vBfLHvm3bOjNN35aCgBecTMHQ2leBtUSMpBqV79cjfXt7m9DU +F+B+9BWO47m2G24dKyczdn6FNVCml0N4lyLVTPXElIGK8Km2Axcre0pNtEuo8RLXdozIIriupzDL7KG9 +zhyWxbU7dfd+6C0EJrMwiGASKp0SQ2iIbnkzICa9kc6gISVng2Nj9/CLod8h8ApD5YLsonhOCpmDlD7e +dAP6we+YYIedHzSYKSXVGv9//crzPJ+Mh837+/vShpF1zRk+gNJzAJ4R41aKJ4QveErkK+mgBUrDYp5t +u3i0eWbibeTMHy7TkXLEyTIQq/99HCmJ/4IoglRQ0La8dK1GYZ0Pn/v9Pow6SQl3O5MT/zg6gYYSOJiP +AjVAKRPrIza8sCYTNvxe2evDd7pFPjEIyi5OLE8PL1WX5Db/HYW/bHeXCOOFwil++0RpDqM19FsyW46/ +yWfRgCwm1rAeF8/alYb9o2UUCLq1r94A8iFn7Z1DfX0dLZfmMpXT0hzgwtwb8etmtLN4LyT250J8XDMz +BRBggPDnCFsA4owstn4qhATgGZVsgv2UDwfe+OSJP+uZ0boTJHYLZQdOdPOvhLPrmPubQReNusCWhTXd +VxXTet3e/f2eHPbf2ov+a1qP48opXSnGBCKCotuWXAK9fuzsY/QuvBpOfnRY00pybFF1iJOS8Ww4c1/B +6XJv/hOXPx+sQ384ofnT/w/jrwAAAP//9ey+zsgOAAA= `, }, @@ -12055,14 +12055,15 @@ vh6n2F5nK55X3h/q0K8AAAD//5F9arwmAwAA "/templates/admin-main.html": { local: "templates/admin-main.html", - size: 836, - modtime: 1498141850, + size: 1024, + modtime: 1499533906, compressed: ` -H4sIAAAAAAAA/6yRzWrrMBCF9/cpBm2yspWQrW24q64Khf6tFWlsD5U1qSQnFON3L4pdSJvQhpDVAY/1 -6dOcwtAOtFUhlEKzi+iiqP4BpO8pAYp2XT30G0sa7tlgIdv1PNj0MbIDdtqSfivFnpzhfW5Zq0js8tZj -XS6kMh052bFBuVyIr8u2vcdsImSRm8ZiVpMPEY4GMAxANeA75JNBEoAljOPx6a2nTvmPYQB0BsZRVK+K -IrmmkNMfV+uuftW16hLb1Z+2L/xTtpDz9r+38D+ZwSPqpBtOizhVFRe+dscRw+KgguH82q6HR1Rdgj+l -vDW8Ud3B/C7lreF9QJ/gzynPFDTHZwAAAP//9zFOd0QDAAA= +H4sIAAAAAAAA/6ySX0vzMBTG799PcSiD3bxrNnYnbUEUvFJEp15n7VkXzJ+ZnHZI6HeXLHNUN3WMXT2l +p/n1x3OSVaKFUnLn8qQ0mlBTUvwDCO9DAmTLaXHfzKUo4dZUmLHldDuYN0RGg9GlFOVrnqyFrsw6labk +JIxOlxYX+ZDxSgnNlKmQjYfJ589WjcVRJIzI1LXE0UJYR9AbgPcgFoBvkEaDIABj6Lr+6ZUVitt37wF1 +BV2XFC9ckNB1xuIXJ+tOftWV/BjbyZ+2z+a7bMa27f9I3NvQVWMtaoIHdI0k19uSkfHBe7Bc1wgD8R8G +LVzkkM5QrSQnvObEI3VzRIrCexi06R1XCF2XMSl2kKgd2SzC+7678Ve/y9AqPGIZqnb7l2i/5uTITbWG +0A03NaI7vPLT4YRcBfgs5LnhNVcb85uQ54Y3Dm2AP4U8cLm28REAAP//GzmHcgAEAAA= `, }, @@ -12114,14 +12115,15 @@ GXvy3PwYKZ6fyZHhEKvyv82bVJmo3N8XAPZYvcMb01mHkXzjyL9wpz4sHABCwHMXXoE7Wthy9p3rhfjJ "/templates/admin-votes.html": { local: "templates/admin-votes.html", - size: 591, - modtime: 1499344306, + size: 747, + modtime: 1499532926, compressed: ` -H4sIAAAAAAAA/2xSwW7CMAy98xVW1CO0h92mtNI0Llx22NDuJjEQLU2qxKs0Vf33KW0hG3B7tl/8nu1I -xoMlMLoWvWeKmykWoCzGWIvow0zovgNtbuHm4IOmQBoUOaYgmhWA5DOhTijhMIMp3exNS5Gx7WTF57+F -V2vIMey2t4V3dF/GnWLOy2rumTKLjuSD1z9zeRggoDsRFGYNRQ/PNZR7ajuLTFtkLF+s/UyDwjjeW9TN -MEDRl1ejMI6yYn3PmB3v9APCArMTlayoyUt6efZGZf2FWqi+fMOWYBzXuQE5nXlZ57KD/xxZXfcg+eg9 -P7iBvhzW0pEFKG9jh64WTyLNZclB+WGYysuKYO8ZLUzhvb6sFh1ZTf+hWf0GAAD//xnIVWJPAgAA +H4sIAAAAAAAA/4RSTYvqMBTd91dcistnA77dIy08dONmFo7MPjZXGyZNSnIVhtL/PiRNrVOF2d3vc3JO +eLOptlfn0BAc0F81ec6aTZVxq6us78EJc0FYqT+wusG/Eoojtp0WhDtBokgrMAwZANeq6ntY3Yo30SIM +A2daxSNoZBjhLBzlJE4aQckyv1lCv455DrUW3pe5t24c6K4O18twfbJOokMJNRpCl1cBmBoUMkQhdmMQ +y9VRtehJtB1n1Dw2tlqFN+93y8ZBmE9lLn6uczbeDJWEw+lk5dfY/lWk/1p/hIeOKi0oyiTZnWjUjeTz +xMh4L18MpBAgujYlM7E6MKsjtXCosaqe6aTNZF69cO/hWHLxvsFmsJnQJNbPDc7ugnE6W0svzJLTD9B4 +phxqq30nTJn/zQMxjQaKd0VYTFrC0ZLQENNnfM4SDmfx41TZdwAAAP//q70AIOsCAAA= `, }, @@ -12176,50 +12178,56 @@ AAD//1puW/YhAwAA "/templates/public-voting.html": { local: "templates/public-voting.html", - size: 9253, - modtime: 1499346016, + size: 10440, + modtime: 1499536431, compressed: ` -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 `, }, diff --git a/assets/css/gjvote.css b/assets/css/gjvote.css index 68a1e59..20e617c 100644 --- a/assets/css/gjvote.css +++ b/assets/css/gjvote.css @@ -115,6 +115,7 @@ img.thumbnail { display: block; height: 120px; background-color: #EEE; + padding-top: 20px; } .padding { diff --git a/main.go b/main.go index 150ec12..12ddae7 100644 --- a/main.go +++ b/main.go @@ -37,6 +37,15 @@ type siteData struct { Votes []Vote } +func (s *siteData) getTeamByUUID(uuid string) *Team { + for i := range s.Teams { + if s.Teams[i].UUID == uuid { + return &s.Teams[i] + } + } + return nil +} + // pageData is stuff that changes per request type pageData struct { Site *siteData diff --git a/templates/admin-main.html b/templates/admin-main.html index 16caaf0..f508033 100644 --- a/templates/admin-main.html +++ b/templates/admin-main.html @@ -4,6 +4,16 @@ + {{ if eq .PublicMode 1 }} +
+

Current Results

+
    + {{ range $i, $v := .TemplateData }} +
  1. {{ $v.Name }}
  2. + {{ end }} +
+
+ {{ end }}

Admin Sections

diff --git a/templates/admin-votes.html b/templates/admin-votes.html index e9caecb..daeac82 100644 --- a/templates/admin-votes.html +++ b/templates/admin-votes.html @@ -1,3 +1,9 @@ +

Current Results

+
    +{{ range $i, $v := .TemplateData.Results }} +
  1. {{ $v.Name }}
  2. +{{ end }} +
diff --git a/templates/public-voting.html b/templates/public-voting.html index 34fa694..d59f817 100644 --- a/templates/public-voting.html +++ b/templates/public-voting.html @@ -1,63 +1,100 @@ {{ if not .TemplateData.Teams }} -
No games have been created
-{{ else }} -
-Rank one or more games from your favorite to least favorite. -
-
-

Your Choices

-
- - - - - - - - - - - -
RankGame NameTeam NameScreenshots
-
-
-

Unranked Games

- - - - - - - - - - - {{ range $i, $v := .TemplateData.Teams }} - - - - - - +
No games have been created
+ {{ else }} +
+ Rank one or more games from your favorite to least favorite. +
+
+

Your Choices

+
Game NameTeam NameScreenshots
Add to Vote{{ $v.Game.Name }}{{ $v.Name }} - {{ if not $v.Game.Screenshots }} - (No Screenshots) - {{ else }} - ({{ len $v.Game.Screenshots }}) - {{ end }} -
+ + + + + + + + + + + +
RankGame NameTeam NameScreenshots
+
+
+

Unranked Games

+ + + + + + + + + + + {{ range $i, $v := .TemplateData.Teams }} + + + + + + + {{ end }} + +
Game NameTeam NameScreenshots
Add to Vote{{ $v.Game.Name }}{{ $v.Name }} + {{ if not $v.Game.Screenshots }} + (No Screenshots) + {{ else }} + ({{ len $v.Game.Screenshots }}) Click to View + {{ end }} +
+
+
+
+ + + +
+
+ {{ range $i, $v := .TemplateData.Teams }} + + + {{ end }} {{ end }}