import std/[json, strutils, sequtils] type BotRoundResult* = object name*: string score*: int rank*: int survived*: bool RoundResult* = object round*: int results*: seq[BotRoundResult] BotResult* = object name*: string totalScore*: int rank*: int firstPlaces*: int survivalCount*: int BattleResult* = object bots*: seq[string] rounds*: seq[RoundResult] results*: seq[BotResult] winners*: seq[string] # bots with rank == 1 proc parseServerOutput*(stdout: string): BattleResult = for line in stdout.splitLines(): let s = line.strip() if s.len == 0 or s[0] != '{': continue let node = parseJson(s) case node["event"].getStr() of "game_started": result.bots = node["bots"].getElems().mapIt(it.getStr()) of "round_ended": var rr = RoundResult(round: node["round"].getInt()) for r in node["results"].getElems(): rr.results.add BotRoundResult( name: r["name"].getStr(), score: r["score"].getInt(), rank: r["rank"].getInt(), survived: r["survived"].getBool() ) result.rounds.add rr of "battle_ended": for r in node["results"].getElems(): result.results.add BotResult( name: r["name"].getStr(), totalScore: r["totalScore"].getInt(), rank: r["rank"].getInt(), firstPlaces: r["firstPlaces"].getInt(), survivalCount: r["survivalCount"].getInt() ) result.winners = result.results.filterIt(it.rank == 1).mapIt(it.name) else: discard when isMainModule: const sample = """ {"event":"game_started","bots":["Alpha","Beta"]} {"event":"round_ended","round":1,"results":[{"name":"Alpha","score":150,"rank":1,"survived":true},{"name":"Beta","score":80,"rank":2,"survived":false}]} {"event":"round_ended","round":2,"results":[{"name":"Beta","score":200,"rank":1,"survived":true},{"name":"Alpha","score":60,"rank":2,"survived":false}]} {"event":"battle_ended","results":[{"name":"Alpha","totalScore":500,"rank":1,"firstPlaces":3,"survivalCount":5},{"name":"Beta","totalScore":300,"rank":2,"firstPlaces":1,"survivalCount":2}]} not json, should be ignored """ let br = parseServerOutput(sample) assert br.bots == @["Alpha", "Beta"] assert br.rounds.len == 2 assert br.rounds[0].round == 1 assert br.rounds[0].results[0].name == "Alpha" assert br.rounds[0].results[0].score == 150 assert br.rounds[0].results[0].rank == 1 assert br.rounds[0].results[0].survived == true assert br.rounds[1].results[0].name == "Beta" assert br.rounds[1].results[1].survived == false assert br.results.len == 2 assert br.results[0].name == "Alpha" assert br.results[0].totalScore == 500 assert br.results[0].firstPlaces == 3 assert br.results[0].survivalCount == 5 assert br.winners == @["Alpha"] echo "all assertions passed"