Browse Source

Add updating special case for main board

master
NGnius 4 years ago
parent
commit
e1e97bf405
1 changed files with 114 additions and 46 deletions
  1. +114
    -46
      leadercraft-ranker/main.go

+ 114
- 46
leadercraft-ranker/main.go View File

@@ -3,7 +3,7 @@
package main // leadercraft-server

import (
"flag"
"flag"
"fmt"
"os"
"os/signal"
@@ -17,7 +17,7 @@ const (
)

var (
isClosing bool
isClosing bool
printVersionAndExit bool
)

@@ -41,24 +41,41 @@ func main() {
isClosing = true
sqlClose()
}()
// get new rankings
rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;")
// get new rankings
rows, err := db.Query("SELECT * FROM Entries WHERE rank=-1 ORDER BY time ASC;")
var players []int64
if err == nil {
var entries []*Entry
// update rank for boards
var entries []*Entry
count := 0
for rows.Next() {
entries = append(entries, &Entry{})
scanErr := rows.Scan(entries[count].Intake()...)
if scanErr == nil {
updateBoardEntries(entries[count])
count++
} else {
fmt.Println(scanErr)
}
}
for rows.Next() {
entries = append(entries, &Entry{})
scanErr := rows.Scan(entries[count].Intake()...)
if scanErr == nil {
//fmt.Printf("Updating rank for entry %d in board %d from player %d\n", entries[count].ID, entries[count].Board, entries[count].Player)
if entries[count].Board > 2 { // ignore special boards
players = append(players, entries[count].Player)
}
updateBoardEntries(entries[count])
count++
} else {
fmt.Println(scanErr)
}
}
// update special boards
for _, elem := range players {
p := &Player{ID: elem}
err := p.Load()
if err == nil {
//fmt.Printf("Updating high score for player %d\n", p.ID)
updateMainRank(p)
} else {
fmt.Println(err)
}
}
} else {
fmt.Println(err)
}
fmt.Println(err)
}
}

func initArgs() {
@@ -76,33 +93,84 @@ func parseArgs() {
}

func updateBoardEntries(entry *Entry) {
// get nearest entry that's lower and steal it's rank
nearestEntry := &Entry{}
scanErr := db.QueryRow("SELECT * FROM Entries WHERE score < $1 AND rank!= -1 AND board=$2 ORDER BY score DESC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
if (scanErr == nil) {
entry.Rank = nearestEntry.Rank
entry.Commit()
// update all ranks lower than itself
tx, _ := db.Begin()
stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank+1 WHERE rank >=$1 AND id!=$2 AND board=$3;")
_, err := stmt.Exec(entry.Rank, entry.ID, entry.Board)
if err != nil {
tx.Rollback()
fmt.Println(err)
} else {
tx.Commit()
}
} else {
// nothing to beat
scanErr = db.QueryRow("SELECT * FROM Entries WHERE score >= $1 AND rank!= -1 AND board=$2 ORDER BY score ASC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
if (scanErr == nil) {
entry.Rank = nearestEntry.Rank + 1
entry.Commit()
} else {
// no other entries
entry.Rank = 1
entry.Commit()
//fmt.Println(scanErr)
}
}
// get nearest entry that's lower and steal it's rank
nearestEntry := &Entry{}
scanErr := db.QueryRow("SELECT * FROM Entries WHERE score < $1 AND rank!= -1 AND board=$2 ORDER BY score DESC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
if scanErr == nil {
entry.Rank = nearestEntry.Rank
entry.Commit()
// update all ranks lower than itself
tx, _ := db.Begin()
stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank+1 WHERE rank >=$1 AND id!=$2 AND board=$3;")
_, err := stmt.Exec(entry.Rank, entry.ID, entry.Board)
if err != nil {
tx.Rollback()
fmt.Println(err)
} else {
tx.Commit()
}
} else {
// nothing to beat
scanErr = db.QueryRow("SELECT * FROM Entries WHERE score >= $1 AND rank!= -1 AND board=$2 ORDER BY score ASC LIMIT 1;", entry.Score, entry.Board).Scan(nearestEntry.Intake()...)
if scanErr == nil {
entry.Rank = nearestEntry.Rank + 1
entry.Commit()
} else {
// no other entries
entry.Rank = 1
entry.Commit()
}
}
}

func updateMainRank(p *Player) {
rows, err := db.Query("SELECT * FROM Entries WHERE player = $1 AND board > 2 ORDER BY score DESC LIMIT $2;", p.ID, 100)
var count int64 = 0
var sum int64 = 0
if err == nil {
for rows.Next() {
entry := &Entry{}
scanErr := rows.Scan(entry.Intake()...)
if scanErr == nil {
count++
sum += entry.Score
} else {
fmt.Println(scanErr)
return
}
}
if count > 0 && sum > 0 {
mainEntry := &Entry{
Player: p.ID,
Board: 1,
}
average := sum / count
//fmt.Printf("Average of %d/%d is %d\n", sum, count, average)
dne := db.QueryRow("SELECT * FROM Entries WHERE board=$1 AND player=$2", 1, p.ID).Scan(mainEntry.Intake()...)
if dne == nil {
tx, _ := db.Begin()
stmt, _ := tx.Prepare("UPDATE Entries SET rank=rank-1 WHERE rank >$1 AND id!=$2 AND board=$3;")
_, err := stmt.Exec(mainEntry.Rank, mainEntry.ID, 1)
if err != nil {
tx.Rollback()
fmt.Println(err)
return // abort
} else {
tx.Commit()
}
mainEntry.Score = average
mainEntry.Rank = -1
mainEntry.Commit()
} else {
createErr := newEntrySql(average, p.ID, 1)
if createErr == nil {
fmt.Println(createErr)
return
}
}
}
} else {
fmt.Println(err)
return
}
}