Loop problem.
#1

So I am making a "Capture the flag" game. But I have some problems when the game ends. It's supposed to loop through all the players, and if it's a tie or a win it sends you a clientmessage and gives money.

pawn Код:
else if(FlagInfo[lRedScore] == FlagInfo[lGreenScore])
                {
                    if(GreenTeam[i] == true || RedTeam[i] == true)
                    {
                        GivePlayerMoney(i, 5000);
                        SendClientMessage(i, C_GREEN, "FLAGGAME TEST!");
                    }
                }
So, this checks if the game is a tie, and gives the players cash etc. But when there are 2 teams, 1 player in both team, then it sends the message twice, gives the money twice, when 2 teams, 2 players in both team, it sends the message four times, gives the money four times.

How should I use break here, to send the message only once?
Reply
#2

Can you show us your whole loop?
Reply
#3

The previous code was translated for better understanding, this is the code:

pawn Код:
public LippLoppeb()
{
    new string[256];
    format(string, sizeof(string),"LIPUMДNG: Mдng on lхppenud! {FF0000}PUNANE:{FFFFFF} %d, {00FF1A}ROHELINE:{FFFFFF} %d,{FFFFFF} vхitja tiimi liikmed saavad auhinna!",LipuInfo[lPunaneskoor], LipuInfo[lRohelineskoor]);
    SendClientMessageToAll(C_WHITE, string);

    for(new i= 0; i<MAX_PLAYERS; i++)
    {
        if(IsPlayerConnected(i))
        {
            if(RohelineTiim[i] == true || PunaneTiim[i] == true)
            {
                SetPlayerInterior(i, 0);
                SpawnPlayer(i);
            }
            {
                if(LipuInfo[lPunaneskoor] > LipuInfo[lRohelineskoor])
                {
                    if(PunaneTiim[i] == true)
                    {
                        GivePlayerMoney(i, 10000);
                        SendClientMessage(i, C_GREEN, "LIPUMДNG: {D7DE16}Jesss!{33AA33} Olid vхitja tiimis ning teenisid 10 000$!");
                    }
                }
                else if(LipuInfo[lPunaneskoor] < LipuInfo[lRohelineskoor])
                {
                    if(RohelineTiim[i] == true)
                    {
                        GivePlayerMoney(i, 10000);
                        SendClientMessage(i, C_GREEN, "LIPUMДNG: {D7DE16}Jesss!{33AA33} Olid vхitja tiimis ning teenisid 10 000$!");
                    }
                }
                else if(LipuInfo[lPunaneskoor] == LipuInfo[lRohelineskoor])
                {
                    if(RohelineTiim[i] == true || PunaneTiim[i] == true)
                    {
                        GivePlayerMoney(i, 5000);
                        SendClientMessage(i, C_GREEN, "LIPUMДNG: {D7DE16}Jesss!{33AA33} Oli viik ning teenisid 5 000$!");
                    }
                }
            }
        }
    }
    return 1;
}
So this message:
pawn Код:
SendClientMessage(i, C_GREEN, "LIPUMДNG: {D7DE16}Jesss!{33AA33} Oli viik ning teenisid 5 000$!");
And the others too (except the first one that's outside the loop) are sent twice when 2 players are in the flag game. When 4 players playing the game, the message is sent 4 times to every player.
Reply
#4

Shouldn't it be:

pawn Код:
SendClientMessage(playerid, COLOR_GREEN, "LIPUMДNG: {D7DE16}Jesss!{33AA33} Oli viik ning teenisid 5 000$!");
Hope it helps.
Reply
#5

No.. when using loop it's "i", or else it wouldn't loop through all the players and see which team they are in.
pawn Код:
for(new i= 0; i<MAX_PLAYERS; i++)
Reply
#6

Aaah, M'kay.
I've not learnt about loops yet, So my bad ;P
Reply
#7

Maybe I should use
pawn Код:
break;
or what I really need some help on this case.
Reply
#8

BUMP!
Reply
#9

Nice to Estonians around here.

Anyways, why not have just one array to store which team the player is in.
pawn Код:
new pTeam[MAX_PLAYERS];
#define TIIM_ROHELINE 1
#define TIIM_PUNANE 2

// Set it whenever you assign a team like PunaneTiim[playerid] = 1 before, but do pTeam[playerid] = TIIM_PUNANE instead!

// And reset in OnPlayerDisconnect!
public OnPlayerDisconnect(playerid)
{
    pTeam[playerid] = 0;
}
This logic allows you to improve your loop, so far you don't even actually need a IsPlayerConnected check (if a player is disconnected, pTeam value is 0).
I don't see an obvious error, but might be because I'm tired or cannot just spot anything that would cause such behavior. However what you could ultimately try is to determine which team wins before entering a loop at all, this way you don't have to run 3 if-statements in your loop every iteration.

Also a small logic approach here:
pawn Код:
redScore = 2;
greenScore = 2;
if(redScore > greenScore)
    // red team won
else if(greenScore > redScore)
    // green team won
else
    // scores are equal
is exactly the same as
pawn Код:
redScore = 2;
greenScore = 2;
if(redScore > greenScore)
    // red team won
else if(greenScore > redScore)
    // green team won
else if(greenScore == redScore)
    // scores are equal
I don't know if this is somehow optimized by the compiler or if it makes a difference, but it is a better practice to write the code like my first example anyways, without the unneeded extra if-statement.

Also, if you ask about the break statement, a code like this:
pawn Код:
for(new i = 0; i != 10; i++)
{
    if(i == 5)
    {
        break;
    }
    printf("%d", i);
}
Would output:
0 1 2 3 4
... and then stop processing the loop. The same goes for players. If at, lets say iterator 2 (player 2) you decide to use break, your loop only covers 2 players and then stops. So nope, you most likely don't need to use break.

However an useful way to use continue, another interesting keyword, is to do something like this:
pawn Код:
// before:
for(new i = 0; i != MAX_PLAYERS; i++)
{
    if(pTeam[i] != 0)
    {
        // code
    }
}

// after
for(new i = 0; i != MAX_PLAYERS; i++)
{
    if(pTeam[i] == 0)
        continue;
    // code
}
These codes produce the same result.
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)