【问题标题】:Calculating Win Streaks计算连胜
【发布时间】:2018-10-22 16:04:03
【问题描述】:

我正在跟踪玩家在游戏中的表现,我想自动生成玩家的当前连胜。此外,我还想跟踪玩家的最高连胜纪录。我试过查看thisthisthat,但我似乎无法调整公式以适应我的情况。

有 8 个可能的值可以输入到单元格中:

  1. 攻击胜利
  2. 攻击失败
  3. 两次进攻都赢了
  4. 两次攻击均失败
  5. 赢了,然后输了
  6. 输了,然后赢了
  7. 没有参加
  8. 被踢

我想要计算连胜的公式,使得 Player1 当前的连胜数为 8,Player2 当前的连胜数为 7,Player3 当前的连胜数为 3,依此类推。

p>

我可以使用什么公式而不使用 VBA 来生成相应的连胜记录?


其他案例研究

游戏结果示例

Player  |    War 1    |       War 2         |        War 3        |      War 4       |        War 5
----------------------------------------------------------------------------------------------------------
PlayerA | Attack Won  |   Both Attacks Won  |   Win, then Lost    |    Attack Won    |     Attack Won
PlayerB | Attack Won  |     Attack Lost     |   Lost, then Win    | Both Attacks Win |     Attack Lost
PlayerC | Attack Won  | Did not Participate | Did not Participate | Both Attacks Won |     Attack Won
PlayerD | Attack Lost |     Attack Lost     | Did not Participate | Win, then Lost   | Did not Participate

期望的连胜数输出

Player  | Highest Win Streak | Current Win Streak
--------------------------------------------------
PlayerA |        3           |         2
PlayerB |        3           |         0
PlayerC |        4           |         4
PlayerD |        1           |         0

谢谢!

【问题讨论】:

  • 你应该研究 countif() 函数。
  • @SolarMike 我不确定如何使用 countif() 函数进一步向下查看行并在检测到“丢失”时停止
  • 这比看起来更复杂。有多少不同的条目算作连胜?攻击赢/两次攻击都赢/赢,然后输了(3 个可能的条目)?如果在获胜之间没有参与,连续性是否会继续? IE。 win 不是 p win 是 1 还是 2?
  • 两次进攻都算2胜吗?

标签: vba excel excel-formula formula


【解决方案1】:

我认为您给出的案例研究需要更多解释。

VBA:

假设:

  1. 未参与 (DNP) 计数,即如果您在两次获胜之间有 DNP,则您从 DNP 之前的位置开始计算您的获胜次数。
  2. 它在开始时忽略 DNP,直到第一次获胜。
  3. 两次攻击均获胜被视为 2 次获胜。如果不是,则注释掉 3 行 Case "both attacks won"winStreak = winStreak + 2currentWinStreak = currentWinStreak + 2。它将输入Case Else并添加1。
  4. Win-then-lose 被视为获胜,然后重新计算获胜次数。
  5. Lo​​se-then-win 重置获胜次数并将当前次数加 1。
  6. StartCell 是要在计算中使用的行的列 C 值。

代码:

Option Explicit

Public Sub WriteOutValues()
    Application.ScreenUpdating = False
    Dim ws As Worksheet, currentCell As Range

    Set ws = ThisWorkbook.Worksheets("Sheet1")
    With ws
         For Each currentCell In .Range("C2", .Range("C2").End(xlDown))
            currentCell.Offset(8, -1) = GetWinStreak(currentCell)(0)
            currentCell.Offset(8, 0) = GetWinStreak(currentCell)(1)
        Next currentCell
    End With
    Application.ScreenUpdating = True
End Sub

Public Function GetWinStreak(ByVal startCell As Range) As Variant

    With startCell.Parent
        Dim loopRange As Range
        Set loopRange = .Range(startCell, startCell.End(xlToRight))
        Dim winTerms()
        winTerms = Array("attack won", "both attacks won", "win, then lost", "lost, then win")
        Dim winStreak As Long, highestWinStreak As Long, currentWinStreak As Long, currentCell As Range
        Dim testValue As String

        For Each currentCell In loopRange
            testValue = LCase$(Trim$(currentCell.Value))
            If testValue = "did not participate" And winStreak = 0 Then GoTo NextLine

            If Not IsError(Application.Match(testValue, winTerms, 0)) Then
                Select Case testValue
                Case "both attacks won"
                    winStreak = winStreak + 2
                    currentWinStreak = currentWinStreak + 2
                    If highestWinStreak < winStreak Then highestWinStreak = winStreak
                Case "win, then lost"
                    winStreak = winStreak + 1
                    If highestWinStreak < winStreak Then highestWinStreak = winStreak
                    winStreak = 0
                    currentWinStreak = 0
                Case "lost, then win"
                    winStreak = 0
                    currentWinStreak = 1
                    winStreak = winStreak + 1
                    If highestWinStreak < winStreak Then highestWinStreak = winStreak
                Case Else
                    winStreak = winStreak + 1
                    currentWinStreak = currentWinStreak + 1
                    If highestWinStreak < winStreak Then highestWinStreak = winStreak
                End Select
            ElseIf testValue = "did not participate" And winStreak > 0 Then
            Else
                winStreak = 0
                currentWinStreak = 0
            End If
NextLine:
        Next currentCell
    End With

    GetWinStreak = Array(highestWinStreak, currentWinStreak)
End Function

Alt + F11 打开VBE,右键在项目中插入标准模块,代码就进去了。

模块中的代码:

输出:

公式:

目前存在缺陷,例如1) BW(两次攻击均获胜)计为 1 分 2) 计数未保持在“未贡献”中 3) 未正确处理 WTL 和 LTW。包括作为我迄今为止最好的尝试,也许有人可以改进。上图不代表公式的输出。见下图。

因此,根据获胜的因素,修改以下内容:

(C2:J2="W") + (C2:J2="BW") + (C2:J2="WTL")

在上面的W是Win,BW是Both Win,WTL是Win Then Lose。假设这些都有助于连胜。否则,删除不计入的词条。

在B2中,往下拖行:

=MAX(FREQUENCY(IF((C2:J2="W") + (C2:J2="BW") + (C2:J2="WTL"),COLUMN($C$1:$J$1)-COLUMN($C$1)+1),IF((C2:J2="W") + (C2:J2="BW") + (C2:J2="WTL"),0,COLUMN($C$1:$J$1)-COLUMN($C$1)+1)))

您将其作为数组公式输入,这意味着您按 Ctrl + Shift + Enter,在单元格中输入公式并{ } 大括号应出现在公式的任一端。

【讨论】:

  • 很好,但它必须作为数组公式输入吗?
  • @solarmike 是的
  • @QHarr 我是按照这些思路思考的,但是当有 WTL 和 LTW 时,棘手的部分就来了……举个简单的例子:Attack Won | Attack Won | Win, then Lost | Attack Won 目前的连胜纪录为 1(W, W,W,L,W) 和最高连胜 3 (W,W,W,L,W),而Attack Won | Attack Won | Lost, then Win | Attack Won 有当前连胜2 (W,W,L,W,W) 和最高连胜 2 (W,W,L,W,W OR W,W,L,W,W)。那么该公式如何能够满足这些场景呢?附言粗体字母是针对每种情况考虑的结果。
  • 公式将给出正确的结果,我认为 W,W,W,L,W 将是 3。它会产生最大连续连胜。不是总数。
  • 请随时在更改中进行编辑。和好地方。我绝对不应该错过双赢的案例!
【解决方案2】:

因此,无需全部执行,因为您有几个不同的结果(您可能需要重新考虑如何记录数据...),您可以使用 countifs(),以 War 1 为例:

一旦您获得连胜结果列表,max() 是一种方式,但 large() 也提供更大的灵活性,即最大和次大...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多