* Initial addition of a game exporter * Fix snake state bug, remove test logs, fix final output line being empty * Ignore test JSONL file * Added explanation for design decision on the you key in SnakeResponse * Adjust gitignore to be more generic * Retain consistency in usage of pointer * Re-word explanation to refer to requests instead of responses * Remove unnecessary nil check * Check error returned by WriteString * Change file permissions for output file * Initialise gameexporter regardless of whether output is requested * Print error and exit if export to file fails * Added another comment explaining reasoning around export checks * Fixed broken test due to changed return type
86 lines
1.9 KiB
Go
86 lines
1.9 KiB
Go
package commands
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/BattlesnakeOfficial/rules/client"
|
|
)
|
|
|
|
type GameExporter struct {
|
|
game client.Game
|
|
snakeRequests []client.SnakeRequest
|
|
winner SnakeState
|
|
isDraw bool
|
|
}
|
|
|
|
type result struct {
|
|
WinnerID string `json:"winnerId"`
|
|
WinnerName string `json:"winnerName"`
|
|
IsDraw bool `json:"isDraw"`
|
|
}
|
|
|
|
func (ge *GameExporter) FlushToFile(filepath string, format string) error {
|
|
var formattedOutput []string
|
|
var formattingErr error
|
|
|
|
// TODO: Support more formats
|
|
if format == "JSONL" {
|
|
formattedOutput, formattingErr = ge.ConvertToJSON()
|
|
} else {
|
|
log.Fatalf("Invalid output format passed: %s", format)
|
|
}
|
|
|
|
if formattingErr != nil {
|
|
return formattingErr
|
|
}
|
|
|
|
f, err := os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
for _, line := range formattedOutput {
|
|
_, err := f.WriteString(fmt.Sprintf("%s\n", line))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
log.Printf("Written %d lines of output to file: %s\n", len(formattedOutput), filepath)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ge *GameExporter) ConvertToJSON() ([]string, error) {
|
|
output := make([]string, 0)
|
|
serialisedGame, err := json.Marshal(ge.game)
|
|
if err != nil {
|
|
return output, err
|
|
}
|
|
output = append(output, string(serialisedGame))
|
|
for _, board := range ge.snakeRequests {
|
|
serialisedBoard, err := json.Marshal(board)
|
|
if err != nil {
|
|
return output, err
|
|
}
|
|
output = append(output, string(serialisedBoard))
|
|
}
|
|
serialisedResult, err := json.Marshal(result{
|
|
WinnerID: ge.winner.ID,
|
|
WinnerName: ge.winner.Name,
|
|
IsDraw: ge.isDraw,
|
|
})
|
|
if err != nil {
|
|
return output, err
|
|
}
|
|
output = append(output, string(serialisedResult))
|
|
return output, nil
|
|
}
|
|
|
|
func (ge *GameExporter) AddSnakeRequest(snakeRequest client.SnakeRequest) {
|
|
ge.snakeRequests = append(ge.snakeRequests, snakeRequest)
|
|
}
|