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

#define maxTilesPerPlayer 7
#define tilePileSize 100
#define numLetters 26

typedef struct GAMES
{
    char tiles[maxTilesPerPlayer];
} games;

// returns true if there are no non-nul characters in tile_pile.
int is_empty(const char* tile_pile)
{
    for (unsigned i = 0; i < tilePileSize; ++i)
    {
        if (tile_pile[i])
            return 0;
    }

    return 1;
}

// returns the address of the first non-nul character in [beg, end)
// or NULL if one is not found.
const char* first_nonzero(const char* beg, const char* end)
{
    while (beg != end)
    {
        if (*beg)
            return beg;

        ++beg;
    }

    return NULL;
}

// extracts a random tile from tile_pile.
char extract_tile(char* tile_pile)
{
    // pick a random index to begin with.
    unsigned index = rand() % tilePileSize;

    // if the element at that random index is zero, find the next element in the pile
    // that is not.
    if (!tile_pile[index]) 
    {
        const char* result = first_nonzero(tile_pile+index+1, tile_pile+tilePileSize);
        if (result)
            index = result - tile_pile;
        else if ((result = first_nonzero(tile_pile, tile_pile+index)))
            index = result - tile_pile;
    }
    
    // mark the tile as used.
    char tile = tile_pile[index];
    tile_pile[index] = '\0';

    return tile;
}

// attempts to replace used tiles for player from tile_pile
void replenish_player_tiles(games* player, char* tile_pile)
{
    for (unsigned i = 0; i < maxTilesPerPlayer; ++i)
        if (!player->tiles[i] && !is_empty(tile_pile))
            player->tiles[i] = extract_tile(tile_pile);
}

void player_tiles(games* players, unsigned playerIndex, char* tile_pile)
{
    games* player = players+playerIndex;

    replenish_player_tiles(player, tile_pile);

    printf("Player %d's Tiles: { ", playerIndex+1); 
    for (unsigned i = 0; i < maxTilesPerPlayer ; ++i)
        if ( player->tiles[i] )
            printf("%c ", player->tiles[i]);
    printf("}\n");
}

unsigned initialLetterFreq[numLetters] =
{
    9,  // A
    2,  // B
    2,  // C
    4,  // D
    12, // E
    2,  // F
    3,  // G
    2,  // H
    9,  // I
    1,  // J
    1,  // K
    4,  // L
    2,  // M
    5,  // N
    8,  // O
    2,  // P
    1,  // Q
    6,  // R
    4,  // S
    6,  // T
    4,  // U
    2,  // V
    2,  // W
    1,  // X
    2,  // Y
    1,  // Z
};

void fill_tile_pile(char* pile, unsigned letterFreqs [])
{
    const char* end = pile + tilePileSize;

    char * cursor = pile;
    for (unsigned i = 0; i < numLetters; ++i)
        for (unsigned j = 0; j < letterFreqs[i] && cursor != end; ++j)
            *cursor++ = 'A' + i;

    while (cursor != end)
        *cursor++ = '\0';
}

int main()
{
    srand(time(0));

    char tile_pile[tilePileSize];

    fill_tile_pile(tile_pile, initialLetterFreq);

    games player = {{'\0'}};

    while (!is_empty(tile_pile))
    {
        player_tiles(&player, 0, tile_pile);

		// remove (up to) 3 of the player's tiles
        player.tiles[rand() % maxTilesPerPlayer] = '\0';
        player.tiles[rand() % maxTilesPerPlayer] = '\0';
        player.tiles[rand() % maxTilesPerPlayer] = '\0';
    }
}