By

Technical – Piano Piano

Piano piano, the Italian expression for “slowly, slowly” best describes how the week’s progress has felt.

As all projects inevitably do, my project for “30” has already begun the insidious process of “Scope Creep”. My initial goal was to create a handful of gameplay “functions” in Godot by the end of April 2026, and whilst I’ve still got plenty of time my first week has been a culmination of research, the Dunning-Kruger effect, and a dawning realisation my small hills are still difficult after 8 years without any hill climbing.

I began to wonder earlier in the week, what do I actually need for my gameplay goals? Well I need art, and as with my scratch project I could use resources from other artists, but then I’m limited to what’s available within my budget (low!). So I’ll need my own art, and pixel art seems achievable for small requirements.

I first tested this using the Crocotile3D demo, and free sample art from “Mana Seed”, and the results were immediately satisfactory:

Given a year of playing with this, I feel I could get a small library of assets that would look pretty good, but then I began to realise not all the art would work “out of the box”, for example the bushes have transparent edges, whereas my 3D model probably wouldn’t… In addition to this, Crocotile3D felt like it would present some limitations being a niche software.

Given the above, I decided to create my own pixel art where possible, and then produce my own 3D models in Blender – ultimately I’d like to UV wrap the models I make with my own pixel art!

I first tried some pixel art, after all if I can make my own I don’t need to worry about the limitations of it! Unfortunately first attempts were quite varied, and a little dismal!

The 3D modelling after was quick, done again in 30 minutes and producing a fairly satisfactory model based on the one produced by Grant Abbit:

I went through the week thinking pretty positively about the future. Then today I decided to crack on with the CS50 problem set for week 2; this really made me realise how rusty I’ve become!

The first problem in the set was to take inputs for Scrabble words, score them, and determine a winner based on the scores. A fairly simple premise, but feeling confident I figured “why limit it to two players?”… why indeed. All in all, I started this at 10:00am, and finished at 3:00pm, with some time for lunch and watching some catchup for WWE.

The code itself does allow for changing the player minimum and maximum from the constants, and accounts for scores, a win condition, and can also detect ties! Though the tie detection is pretty rudimentary and doesn’t announce if there are more than one “Winner”.

Interestingly I did encounter some issues throughout, the program was largely “feature complete” by about 3 hours in, but needed a further two hours to polish and also iron out a fairly frustrating issue where I hadn’t properly accounted for uppercase letters, producing results like this!

Even more annoyingly, the CS50 debugger broke down! I put a break in at the secondary input of some early code, but the debugger was insistent no break had been placed!

Despite all of these frustrations, I managed to resolve, refactor, and produce a working, bug-free code!

// Pull Libs
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

// Define constants
#define ALPHABET_SIZE 26
#define MAX_PLAYERS 4
#define MIN_PLAYERS 2

// Prototypes
void get_alphabet(char ALPHABET[]);
void get_player_words(int pcount, string words[]);
int get_player_count(void);
int get_player_score(char ALPHABET[], const int SCORES[], string word);
int compare_scores(int player_scores[], int playercount);

// MAIN FUNCTION
int main(void)
{
    // Var Init
    const int SCORES[] = {1, 3, 3, 2,  1, 4, 2, 4, 1, 8, 5, 1, 3,
                          1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10}; // Static scores, a-z
    char ALPHABET[ALPHABET_SIZE];
    int player_count = get_player_count(); // Get player count w/ error prevention
    string words[player_count];            // Get word count from playercount
    int word_scores[player_count];         // Player score array

    get_alphabet(ALPHABET);                // Return alphabet
    get_player_words(player_count, words); // Return player words
    for (int i = 0; i < player_count; i++) // For each player, calc scoring
    {
        word_scores[i] = get_player_score(ALPHABET, SCORES, words[i]);
    }
    int winner = compare_scores(word_scores, player_count);
    printf("Player %i is the winner! score: %i\n", winner + 1, word_scores[winner]);
    for (int i = 0; i < player_count; i++) // For each player, print scoring
    {
        printf("Player %i scored %i\n", i + 1, word_scores[i]);
    }
}

// FUNCTIONS
void get_alphabet(char ALPHABET[]) // Get alphabet
{
    for (int i = 0; i < ALPHABET_SIZE; i++)
    {
        ALPHABET[i] = 'a' + i;
    }
}

void get_player_words(int pcount, string words[]) // Get words based on player count
{
    for (int i = 0; i < pcount; i++)
    {
        words[i] = get_string("Player %i's Word: ", i + 1);
    }
}

int get_player_count(void) // Get player count within defined min/max
{
    int i = 0;
    while (i < MIN_PLAYERS || i > MAX_PLAYERS)
    {
        i = get_int("How many players? (%i-%i): ", MIN_PLAYERS, MAX_PLAYERS);
        if (i < MIN_PLAYERS || i > MAX_PLAYERS)
        {
            printf("Wrong player count entered: %i\n", i);
        }
    }
    return i;
}

int get_player_score(char ALPHABET[], const int SCORES[], string word)
{
    int player_score = 0;
    int word_size = strlen(word);

    for (int i = 0; i < word_size; i++)
    {
        int j = 0;
        if (isupper(word[i]))
        {
            word[i] = tolower(word[i]);
        }
        while (word[i] != ALPHABET[j] && j < ALPHABET_SIZE)
        {
            j++;
        }
        player_score += SCORES[j];
    }
    return player_score;
}

int compare_scores(int player_scores[], int playercount) // Iterate all player scores, compare and
                                                         // replace pointer value with highest score
{
    int highscore_pointer = 0;
    for (int i = 0; i < playercount; i++)
    {
        if (player_scores[i] > player_scores[highscore_pointer])
        {
            highscore_pointer = i;
        }
        else if (i > 0 && player_scores[i] == player_scores[highscore_pointer])
        {
            printf("Tie! %i and %i\n", highscore_pointer + 1, i + 1);
        }
    }
    return highscore_pointer;
}

Leave a comment