• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Solved] Comparing scores to detect a winner while accounting for ties.

Status
Not open for further replies.
Level 13
Joined
Mar 24, 2013
Messages
1,105
I am sure this must be solved although I cannot seem to find anything useful through searching.

I am trying to check each players score at the end of the game to determine the winner. My first trigger here, I had it set it up where if two people ended with the same score both were declared the winner. I did not like that however and want to be able to detect a tie to allow me to force another round. However, I am stuck at the moment.

JASS:
    function GameWinnerFFAPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer pId = GetPlayerId(p)
     
        call Message(GetRealColoredName(p) + " won the game!")
        call SetPlayerOnScoreScreen(p, true)
     
        set p = null
    endfunction
 
    function GameWinnerFFA takes nothing returns nothing
        local integer i = 0
        local integer i2 = 0
        local force f = WINNERS
        local player p
        loop
            exitwhen i >= 12
                set p = Player(i)
                if roundWins[i2] == roundWins[i] and IsPlaying(p) then
                    call ForceAddPlayer(f, p)
                elseif roundWins[i2] < roundWins[i] then
                    call ForceClear(f)
                    set i2 = i
                    call ForceAddPlayer(f, p)
                endif
            set i = i + 1
        endloop
 
        call ForForce(f, function GameWinnerFFAPlayer)
        call ForceClear(f)

        set p = null
        set f = null
    endfunction

JASS:
    function GameWinnerFFA takes nothing returns boolean
        local integer i = 0
        local integer i2 = 0
        local force f = WINNERS
        local player p
        local integer i3 = 0
        loop
            exitwhen i >= 12
                set p = Player(i)
                if roundWins[i2] == roundWins[i] and IsPlaying(p) then
                    call ForceAddPlayer(f, p)
                    set i3 = i3 + 1
                    if i3 > 1 then
                        set totalRounds = 2
                        call Message(colorNames[13] + "Tie Detected, playing another round!")
                        call ForceClear(f)
                        set f = null
                        set p = null 
                        return false
                    endif
                elseif roundWins[i2] < roundWins[i] then
                    set i3 = 0
                    call ForceClear(f)
                    set i2 = i
                    call ForceAddPlayer(f, p)
                endif
            set i = i + 1
        endloop
 
        call ForForce(f, function GameWinnerFFAPlayer)
        call ForceClear(f)
        set f = null
        set p = null
        return true
    endfunction

In the WIP I was trying to make it so if i3 exceeds 1 then it must mean that there was a tie because two scores equaled each other, that fails though because it could such that a = b but a < c and I wont catch that.

Any guidance would be awesome.
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
Yes, one winner and the rest defeated.

The work in progress is definitely needing some tweeking. I am having difficulty figuring out how to compare the values, and then insuring no ties.

I suppose what I could do is count the amount of Players in the Force in my initial trigger and if it is larger than 1 a tie must have occured. However, I feel like there must be a way to do that during the original comparison.
 
Level 39
Joined
Feb 27, 2007
Messages
5,010
Simplest solution:
  • Loop over all players, to determine the highest score any player has.
  • Loop over all players again, adding anyone with that score to a force.
  • Count the number of players in the force. If greater than 1, tiebreaker with all players in the force.
  • Victory to whomever wins the tiebreaker game.
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
Thanks Pyro, went ahead and made it as you outlined and appears to be working well.

Appreciate it!

Here is the code for anyone interested: (Spacing got a little fouled up, and I use an extra int but should be clear enough to follow)

JASS:
    function GameWinnerFFAPlayer takes nothing returns nothing
        local player p = GetEnumPlayer()
        local integer pId = GetPlayerId(p)
        call Message(GetRealColoredName(p) + " won the game!")
        call SetPlayerOnScoreScreen(p, true)
     
        set p = null
    endfunction

function GameWinnerFFA takes nothing returns boolean
        local integer i = 0
        local integer i2 = 0
        local force f = WINNERS
        local player p
        local integer i3 = 0
        local integer i4 = 0
        local boolean b = true
        loop
            exitwhen i >= 12
                set p = Player(i)
                if roundWins[i2] <= roundWins[i] and IsPlaying(p) then
                     set i2 = i         
                     set i3 = roundWins[i2]
                endif
            set i = i + 1
        endloop
    set i = 0
    loop
         exitwhen i >= 12
            set p = Player(i)
           if roundWins[i] == i3 and IsPlaying(p) then
           set i4 = i4 + 1
           call ForceAddPlayer(f, p)
                endif
            set i = i + 1
        endloop
     
    if i4 > 1 then
          set b = true
          call Message(colorNames[13] + "Tie Detected, playing another round!")
    else
            call ForForce(f, function GameWinnerFFAPlayer)
        set b = false
    endif
 
    call ForceClear(f)
    set f = null
    set p = null
    return b
    endfunction
 
Status
Not open for further replies.
Top