Search code examples
cblackjack

C - Optimize winner selection


I'm making the game seven and a half (similar to black jack) and at the end I have to check who has the highest score equal or below 7.5 and print the player or players with that score, this is what I've made but idk if there is a more optimal way of doing this

//Winner selection
    printf("\nThe winning player (s) is / are:\n");

    //checks highest score
    for (int i = 0; i < players; i++)
    {
        if (score[i] <= 7.5)
        {
            if (score[i] >= max_score)
            {
                max_score = score[i];
            }
        }
    }

    //checks players with that score
    for (int i = 0; i < players; i++)
    {
        if (score[i] <= 7.5)
        {
            if (score[i] == max_score)
            {
                winners[i] = 1;
            }
            else
            {
                winners[i] = -1;
            }
        }
        else
        {
            winners[i] = -1;
        }
    }

    //prints the winners
    for (int i = 0; i < players; i++)
    {
        if (winners[i] == 1)
        {
            printf("Player %d\n", i + 1);
        }
    }

And in case you want to see the full code or you want to try to play it here it is:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//deck
#define AS 1
#define DOS 2
#define TRES 3
#define CUATRO 4
#define CINCO 5
#define SEIS 6
#define SIETE 7
#define SOTA 0.5
#define CABALLO 0.5
#define REY 0.5
#define ncards 40

// rand num gen
int random_number(int a, int b)
{
    return a + rand() % (b - a + 1);
}

int main()
{
    int players, winners[4], j = 0;
    double score[4], max_score = 0;
    char play;
    //whole deck
    double cards[ncards] = {AS, DOS, TRES, CUATRO, CINCO, SEIS, SIETE, SOTA, CABALLO, REY,

                            AS, DOS, TRES, CUATRO, CINCO, SEIS, SIETE, SOTA, CABALLO, REY,

                            AS, DOS, TRES, CUATRO, CINCO, SEIS, SIETE, SOTA, CABALLO, REY,

                            AS, DOS, TRES, CUATRO, CINCO, SEIS, SIETE, SOTA, CABALLO, REY};

    //new seed
    srand((unsigned)time(NULL));

    //shuffle cards
    for (int i = 0; i < 100; i++)
    {
        cards[random_number(0, ncards)] = cards[random_number(0, ncards)];
    }

    //determine num of players
    do
    {
        printf("\nHow many players (maximum 4)? ");
        scanf("%d", &players);
    } while (players > 4);

    //game execution
    for (int i = 0; i < players; i++)
    {
        score[i] = 0;
        play = 'y';
        printf("\nPlayer %d ==========\n", i + 1);
        do
        {
            score[i] += cards[j];
            if (score[i] < 7.5)
            {
                printf("\nYour partial score is %.1lf.", score[i]);
                j++;
                printf("\nDo you want a card (y/n)? ");
                scanf(" %c", &play);
            }
            else if (score[i] == 7.5)
            {
                printf("You've exactly 7.5!");
            }

            else
            {
                printf("\nYou've gone !! You stay with %.1lf points!", score[i]);
            }

        } while (score[i] < 7.5 && play == 'y');
    }

    //Winner selection
    printf("\nThe winning player (s) is / are:\n");

    //checks highest score
    for (int i = 0; i < players; i++)
    {
        if (score[i] <= 7.5)
        {
            if (score[i] >= max_score)
            {
                max_score = score[i];
            }
        }
    }

    //checks players with that score
    for (int i = 0; i < players; i++)
    {
        if (score[i] <= 7.5)
        {
            if (score[i] == max_score)
            {
                winners[i] = 1;
            }
            else
            {
                winners[i] = -1;
            }
        }
        else
        {
            winners[i] = -1;
        }
    }

    //prints the winners
    for (int i = 0; i < players; i++)
    {
        if (winners[i] == 1)
        {
            printf("Player %d\n", i + 1);
        }
    }
}

Solution

  • You can optimize this loop:

    for (int i = 0; i < players; i++)
    {
        if (score[i] <= 7.5)
        {
            if (score[i] == max_score)
            {
                winners[i] = 1;
            }
            else
            {
                winners[i] = -1;
            }
        }
        else
        {
            winners[i] = -1;
        }
    }
    

    To simply be:

    for (int i = 0; i < players; i++)
    {
        winners[i] = ((score[i] <= 7.5) && (score[i] == max_score)) ? 1 : -1;
    }
    

    And for improved style:

    Instead of -1 to indicate a non-winner, just use zero. It's a boolean after all.

    Then the winner loop is simply:

    for (int i = 0; i < players; i++)
    {
        winners[i] = ( (score[i] <= 7.5) && (score[i] == max_score) );
    }
    

    The print loop:

    //prints the winners
    for (int i = 0; i < players; i++)
    {
        if (winners[i])
        {
            printf("Player %d\n", i + 1);
        }
    }