From 5442a0ec08e7558c77fa16849c2abafefe33d06c Mon Sep 17 00:00:00 2001 From: zc-meng Date: Fri, 20 Sep 2024 11:19:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/Game.kt | 3 +- src/main/kotlin/Statistics.kt | 149 ++++++++++++++++++++++++++++----- src/main/kotlin/gm/Getscore.kt | 125 +++++++++++++++++++++++++-- 3 files changed, 245 insertions(+), 32 deletions(-) diff --git a/src/main/kotlin/Game.kt b/src/main/kotlin/Game.kt index 0f6a2e11..b449cb0e 100644 --- a/src/main/kotlin/Game.kt +++ b/src/main/kotlin/Game.kt @@ -238,7 +238,8 @@ class Game(val id: Int, totalPlayerCount: Int, val actorRef: ActorRef) { for (p in humanPlayers) { if (humanPlayers.size <= 1) Statistics.addEnergy(p.playerName, -1) else Statistics.addEnergy(p.playerName, humanPlayers.size * 2) - playerGameResultList.add(PlayerGameResult(p.playerName, winners.any { it === p }, p.originIdentity)) + playerGameResultList.add(PlayerGameResult(p.playerName, winners.any { it === p }, + p.originIdentity, p.originSecretTask)) } Statistics.addPlayerGameCount(playerGameResultList) Statistics.calculateRankList() diff --git a/src/main/kotlin/Statistics.kt b/src/main/kotlin/Statistics.kt index 9f2c5afe..a84c9f81 100644 --- a/src/main/kotlin/Statistics.kt +++ b/src/main/kotlin/Statistics.kt @@ -3,6 +3,7 @@ package com.fengsheng import com.fengsheng.ScoreFactory.addScore import com.fengsheng.protos.Common.* import com.fengsheng.protos.Common.color.* +import com.fengsheng.protos.Common.secret_task.* import com.fengsheng.protos.getRecordListToc import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel @@ -79,38 +80,93 @@ object Statistics { var rbgame = 0 var blackwin = 0 var blackgame = 0 + var killerwin = 0 + var killergame = 0 + var stealerwin = 0 + var stealergame = 0 + var collectorwin = 0 + var collectorgame = 0 + var mutatorwin = 0 + var mutatorgame = 0 + var pioneerwin = 0 + var pioneergame = 0 + var disturberwin = 0 + var disturbergame = 0 + var sweeperwin = 0 + var sweepergame = 0 var updateTrial = false for (count in playerGameResultList) { if (count.isWin) { - when (count.identity) { - Black -> { - blackwin++ + if (count.identity == Black) { + blackwin++ + when (count.secret_task) { + Killer -> killerwin++ + Stealer -> stealerwin++ + Collector -> collectorwin++ + Mutator -> mutatorwin++ + Pioneer -> pioneerwin++ + Disturber -> disturberwin++ + Sweeper -> sweeperwin++ + else -> {} } - else -> { - rbwin++ - } - } + } else rbwin++ win++ if (trialStartTime.remove(count.playerName) != null) updateTrial = true } - when (count.identity) { - Black -> { - blackgame++ + if (count.identity == Black) { + blackgame++ + when (count.secret_task) { + Killer -> killergame++ + Stealer -> stealergame++ + Collector -> collectorgame++ + Mutator -> mutatorgame++ + Pioneer -> pioneergame++ + Disturber -> disturbergame++ + Sweeper -> sweepergame++ + else -> {} } - else -> { - rbgame++ - } - } + } else rbgame++ game++ playerInfoMap.computeIfPresent(count.playerName) { _, v -> val addWin = if (count.isWin) 1 else 0 val addRbWin = if (count.isWin && count.identity != Black) 1 else 0 val addBlackWin = if (count.isWin && count.identity == Black) 1 else 0 + val addKillerWin = if (count.isWin && count.identity == Black && count.secret_task == Killer) 1 else 0 + val addStealerWin = if (count.isWin && count.identity == Black && count.secret_task == Stealer) 1 else 0 + val addCollectorWin = if (count.isWin && count.identity == Black && count.secret_task == Collector) 1 else 0 + val addMutatorWin = if (count.isWin && count.identity == Black && count.secret_task == Mutator) 1 else 0 + val addPioneerWin = if (count.isWin && count.identity == Black && count.secret_task == Pioneer) 1 else 0 + val addDisturberWin = if (count.isWin && count.identity == Black && count.secret_task == Disturber) 1 else 0 + val addSweeperWin = if (count.isWin && count.identity == Black && count.secret_task == Sweeper) 1 else 0 val addRbGame = if (count.identity != Black) 1 else 0 val addBlackGame = if (count.identity == Black) 1 else 0 - v.copy(winCount = v.winCount + addWin, gameCount = v.gameCount + 1, lastTime = now, - rbWinCount = v.rbWinCount + addRbWin, blackWinCount = v.blackWinCount + addBlackWin, - rbGameCount = v.rbGameCount + addRbGame, blackGameCount = v.blackGameCount + addBlackGame) + val addKillerGame = if (count.identity == Black && count.secret_task == Killer) 1 else 0 + val addStealerGame = if (count.identity == Black && count.secret_task == Stealer) 1 else 0 + val addCollectorGame = if (count.identity == Black && count.secret_task == Collector) 1 else 0 + val addMutatorGame = if (count.identity == Black && count.secret_task == Mutator) 1 else 0 + val addPioneerGame = if (count.identity == Black && count.secret_task == Pioneer) 1 else 0 + val addDisturberGame = if (count.identity == Black && count.secret_task == Disturber) 1 else 0 + val addSweeperGame = if (count.identity == Black && count.secret_task == Sweeper) 1 else 0 + v.copy(winCount = v.winCount + addWin, + gameCount = v.gameCount + 1, lastTime = now, + rbWinCount = v.rbWinCount + addRbWin, + blackWinCount = v.blackWinCount + addBlackWin, + killerWinCount = v.killerWinCount + addKillerWin, + stealerWinCount = v.stealerWinCount + addStealerWin, + collectorWinCount = v.collectorWinCount + addCollectorWin, + mutatorWinCount = v.mutatorWinCount + addMutatorWin, + pioneerWinCount = v.pioneerWinCount + addPioneerWin, + disturberWinCount = v.disturberWinCount + addDisturberWin, + sweeperWinCount = v.sweeperWinCount + addSweeperWin, + rbGameCount = v.rbGameCount + addRbGame, + blackGameCount = v.blackGameCount + addBlackGame, + killerGameCount = v.killerGameCount + addKillerGame, + stealerGameCount = v.stealerGameCount + addStealerGame, + collectorGameCount = v.collectorGameCount + addCollectorGame, + mutatorGameCount = v.mutatorGameCount + addMutatorGame, + pioneerGameCount = v.pioneerGameCount + addPioneerGame, + disturberGameCount = v.disturberGameCount + addDisturberGame, + sweeperGameCount = v.sweeperGameCount + addSweeperGame) } } totalWinCount.addAndGet(win) @@ -126,7 +182,8 @@ object Statistics { fun register(name: String): Boolean { val now = System.currentTimeMillis() - val result = playerInfoMap.putIfAbsent(name, PlayerInfo(name, 0, "", 0, 0, 0, "", now, 10, 0, 0, 0, 0, 0)) == null + val result = playerInfoMap.putIfAbsent(name, PlayerInfo(name, 0, "", 0, 0, 0, "", now, 10, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) == null if (result) pool.trySend(::savePlayerInfo) return result } @@ -313,7 +370,21 @@ object Statistics { sb.append(info.rbWinCount).append(',') sb.append(info.rbGameCount).append(',') sb.append(info.blackWinCount).append(',') - sb.append(info.blackGameCount).append('\n') + sb.append(info.blackGameCount).append(',') + sb.append(info.killerWinCount).append(',') + sb.append(info.killerGameCount).append(',') + sb.append(info.stealerWinCount).append(',') + sb.append(info.stealerGameCount).append(',') + sb.append(info.collectorWinCount).append(',') + sb.append(info.collectorGameCount).append(',') + sb.append(info.mutatorWinCount).append(',') + sb.append(info.mutatorGameCount).append(',') + sb.append(info.pioneerWinCount).append(',') + sb.append(info.pioneerGameCount).append(',') + sb.append(info.disturberWinCount).append(',') + sb.append(info.disturberGameCount).append(',') + sb.append(info.sweeperWinCount).append(',') + sb.append(info.sweeperGameCount).append('\n') } writeFile("playerInfo.csv", sb.toString().toByteArray()) sb.clear() @@ -342,7 +413,7 @@ object Statistics { var line: String while (true) { line = reader.readLine() ?: break - val a = line.split(",".toRegex(), limit = 14) + val a = line.split(",".toRegex(), limit = 28) val pwd = a[4] val score = if (a[3].length < 6) a[3].toInt() else 0 // 以前这个位置是deviceId val name = a[2] @@ -357,8 +428,26 @@ object Statistics { val rbGameCount = a.getOrNull(11)?.toInt() ?: 0 val blackWinCount = a.getOrNull(12)?.toInt() ?: 0 val blackGameCount = a.getOrNull(13)?.toInt() ?: 0 + val killerWinCount = a.getOrNull(14)?.toInt() ?: 0 + val killerGameCount = a.getOrNull(15)?.toInt() ?: 0 + val stealerWinCount = a.getOrNull(16)?.toInt() ?: 0 + val stealerGameCount = a.getOrNull(17)?.toInt() ?: 0 + val collectorWinCount = a.getOrNull(18)?.toInt() ?: 0 + val collectorGameCount = a.getOrNull(19)?.toInt() ?: 0 + val mutatorWinCount = a.getOrNull(20)?.toInt() ?: 0 + val mutatorGameCount = a.getOrNull(21)?.toInt() ?: 0 + val pioneerWinCount = a.getOrNull(22)?.toInt() ?: 0 + val pioneerGameCount = a.getOrNull(23)?.toInt() ?: 0 + val disturberWinCount = a.getOrNull(24)?.toInt() ?: 0 + val disturberGameCount = a.getOrNull(25)?.toInt() ?: 0 + val sweeperWinCount = a.getOrNull(26)?.toInt() ?: 0 + val sweeperGameCount = a.getOrNull(27)?.toInt() ?: 0 val p = PlayerInfo(name, score, pwd, win, game, forbid, title, lt, energy, maxScore, - rbWinCount, rbGameCount, blackWinCount, blackGameCount) + rbWinCount, rbGameCount, blackWinCount, blackGameCount, + killerWinCount, killerGameCount, stealerWinCount, stealerGameCount, + collectorWinCount, collectorGameCount, mutatorWinCount, mutatorGameCount, + pioneerWinCount, pioneerGameCount, disturberWinCount, disturberGameCount, + sweeperWinCount, sweeperGameCount) if (playerInfoMap.put(name, p) != null) throw RuntimeException("数据错误,有重复的玩家name") winCount += win @@ -443,7 +532,7 @@ object Statistics { val totalPlayerCount: Int ) - class PlayerGameResult(val playerName: String, val isWin: Boolean, val identity: color) + class PlayerGameResult(val playerName: String, val isWin: Boolean, val identity: color, val secret_task: secret_task) data class PlayerGameCount(val winCount: Int, val gameCount: Int) { fun random(): PlayerGameCount { @@ -470,7 +559,21 @@ object Statistics { val rbWinCount: Int, val rbGameCount: Int, val blackWinCount: Int, - val blackGameCount: Int + val blackGameCount: Int, + val killerWinCount: Int, + val killerGameCount: Int, + val stealerWinCount: Int, + val stealerGameCount: Int, + val collectorWinCount: Int, + val collectorGameCount: Int, + val mutatorWinCount: Int, + val mutatorGameCount: Int, + val pioneerWinCount: Int, + val pioneerGameCount: Int, + val disturberWinCount: Int, + val disturberGameCount: Int, + val sweeperWinCount: Int, + val sweeperGameCount: Int ) : Comparable { val scoreWithDecay: Int get() { diff --git a/src/main/kotlin/gm/Getscore.kt b/src/main/kotlin/gm/Getscore.kt index 4e30ea22..fb84390a 100644 --- a/src/main/kotlin/gm/Getscore.kt +++ b/src/main/kotlin/gm/Getscore.kt @@ -1,8 +1,11 @@ package com.fengsheng.gm - import com.fengsheng.QQPusher import com.fengsheng.ScoreFactory import com.fengsheng.Statistics +import com.fengsheng.protos.Common +import java.io.BufferedReader +import java.io.FileInputStream +import java.io.InputStreamReader import java.util.function.Function class Getscore : Function, Any> { @@ -13,6 +16,71 @@ class Getscore : Function, Any> { if (playerInfo == null) { "{\"result\": \"${name}已身死道消\"}" } else { + fun IntArray.inc(index: Int? = null) { + this[0]++ + if (index != null) { + this[2]++ + this[index]++ + } else { + this[1]++ + } + } + fun HashMap.sum(index: Int): Int { + var sum = 0 + this.forEach { sum += it.value[index] } + return sum + } + val gameCount = HashMap() + val winCount = HashMap() + FileInputStream("stat.csv").use { `is` -> + BufferedReader(InputStreamReader(`is`)).use { reader -> + var line: String? + while (true) { + line = reader.readLine() + if (line == null) break + val a = line.split(Regex(",")).dropLastWhile { it.isEmpty() } + val role = Common.role.valueOf(a[0]) + val appear = gameCount.computeIfAbsent(role) { IntArray(10) } + val win = winCount.computeIfAbsent(role) { IntArray(10) } + val index = + if ("Black" == a[2]) Common.secret_task.valueOf(a[3]).number + 3 + else null + appear.inc(index) + if (a[1].toBoolean()) win.inc(index) + } + } + } + val winRateSum = + if (gameCount.sum(0) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(0) * 100.0 / gameCount.sum(0)) + val rbWinRateSum = + if (gameCount.sum(1) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(1) * 100.0 / gameCount.sum(1)) + val blackWinRateSum = + if (gameCount.sum(2) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(2) * 100.0 / gameCount.sum(2)) + val killerWinRateSum = + if (gameCount.sum(3) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(3) * 100.0 / gameCount.sum(3)) + val stealerWinRateSum = + if (gameCount.sum(4) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(4) * 100.0 / gameCount.sum(4)) + val collectorWinRateSum = + if (gameCount.sum(5) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(5) * 100.0 / gameCount.sum(5)) + val mutatorWinRateSum = + if (gameCount.sum(6) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(6) * 100.0 / gameCount.sum(6)) + val pioneerWinRateSum = + if (gameCount.sum(7) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(7) * 100.0 / gameCount.sum(7)) + val disturberWinRateSum = + if (gameCount.sum(8) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(8) * 100.0 / gameCount.sum(8)) + val sweeperWinRateSum = + if (gameCount.sum(9) == 0) "0.00%" + else "%.2f%%".format(winCount.sum(9) * 100.0 / gameCount.sum(9)) + val score = playerInfo.scoreWithDecay val rank = ScoreFactory.getRankNameByScore(score) val total = playerInfo.gameCount @@ -21,16 +89,57 @@ class Getscore : Function, Any> { else "%.2f%%".format(playerInfo.winCount * 100.0 / total) val energy = playerInfo.energy val rbGameCount = playerInfo.rbGameCount - val winRbRate = - if (playerInfo.rbGameCount == 0) "0.00%" + val rbWinRate = + if (rbGameCount == 0) "0.00%" else "%.2f%%".format(playerInfo.rbWinCount * 100.0 / rbGameCount) val blackGameCount = playerInfo.blackGameCount - val winBlackRate = - if (playerInfo.blackGameCount == 0) "0.00%" + val blackWinRate = + if (blackGameCount == 0) "0.00%" else "%.2f%%".format(playerInfo.blackWinCount * 100.0 / blackGameCount) - var s1 = "$name·$rank·$score,总场次:$total(军潜:$rbGameCount,神秘人:$blackGameCount)," - var s2 = "胜率:$winRate(军潜:$winRbRate,神秘人:$winBlackRate),精力:$energy" - var s = s1 + s2 + val killerGameCount = playerInfo.killerGameCount + val killerWinRate = + if (killerGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.killerWinCount * 100.0 / killerGameCount) + val stealerGameCount = playerInfo.stealerGameCount + val stealerWinRate = + if (stealerGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.stealerWinCount * 100.0 / stealerGameCount) + val collectorGameCount = playerInfo.collectorGameCount + val collectorWinRate = + if (collectorGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.collectorWinCount * 100.0 / collectorGameCount) + val mutatorGameCount = playerInfo.mutatorGameCount + val mutatorWinRate = + if (mutatorGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.mutatorWinCount * 100.0 / mutatorGameCount) + val pioneerGameCount = playerInfo.pioneerGameCount + val pioneerWinRate = + if (pioneerGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.pioneerWinCount * 100.0 / pioneerGameCount) + val disturberGameCount = playerInfo.disturberGameCount + val disturberWinRate = + if (disturberGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.disturberWinCount * 100.0 / disturberGameCount) + val sweeperGameCount = playerInfo.sweeperGameCount + val sweeperWinRate = + if (sweeperGameCount == 0) "0.00%" + else "%.2f%%".format(playerInfo.sweeperWinCount * 100.0 / sweeperGameCount) + var s1 = "$name·$rank·$score,总场次:$total,胜率:$winRate\n" + var s2 = "-----------------------------------\n" + var s3 = "身份\t 胜率\t 平均胜率\t 场次\n" + val s4 = "总计\t $winRate\t $winRateSum\t $total\n" + var s5 = "军潜\t $rbWinRate\t $rbWinRateSum\t $rbGameCount\n" + var s6 = "神秘人\t $blackWinRate\t $blackWinRateSum\t $blackGameCount\n" + var s7 = "镇压者\t $killerWinRate\t $killerWinRateSum\t $killerGameCount\n" + var s8 = "篡夺者\t $stealerWinRate\t $stealerWinRateSum\t $stealerGameCount\n" + var s9 = "双面间谍\t $collectorWinRate\t $collectorWinRateSum\t $collectorGameCount\n" + var s10 = "诱变者\t $mutatorWinRate\t $mutatorWinRateSum\t $mutatorGameCount\n" + var s11 = "先行者\t $pioneerWinRate\t $pioneerWinRateSum\t $pioneerGameCount\n" + var s12 = "搅局者\t $disturberWinRate\t $disturberWinRateSum\t $disturberGameCount\n" + var s13 = "清道夫\t $sweeperWinRate\t $sweeperWinRateSum\t $sweeperGameCount\n" + var s14 = "-----------------------------------\n" + var s15 = "剩余精力:$energy" + var s = s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15 if (playerInfo.score != score) s += "(长期不打会掉分,打一场即可全部恢复)" val history = QQPusher.getHistory(name) if (history.isNotEmpty())