Determine next building upgrade in Monopoly

Each street in Monopoly is comprised of 2 or 3 different properties.

When a user upgrades a street, it will build 1 of 3 buildings on the appropriate property.

  • House – least valuable, will build this by default, max 16 per property.

  • Hotel – costs 3 houses to build. Max 8 per property.

  • Sky scraper – most valuable, costs 2 hotels to build, max 1 per property.

Each type of building needs to be spread evenly. For example if there’s 2 properties, the order of upgrades would be:

  1. House on property 1
  2. House on property 2
  3. House on property 1
  4. House on property 2
  5. House on property 1
  6. House on property 2
  7. Hotel on property 1 (also delete 3 houses)
  8. Hotel on property 2 (also delete 3 houses)
  9. House on property 1

The only time there would be more than 3 houses on a property is after the skyscrapers and hotels are both maxed out, then the houses would stack up until 16 on each property.

I need a function that will calculate this. The parameters of this function are numOfProperties, numOfSkyScrapers, numOfHotels, numOfHouses and it needs to output which building should be next.

This function cannot use looping. I think the mod operator would be useful.

My code below works when there is 1 property. But with 2 properties, upgrade 8 is a house when it should be a hotel. It’s because after the first hotel upgrade, it deletes that properties 3 houses, so the total number is 3 again and builds another house.

I’m not sure how I can make this dynamic and work for all amount of properties

function nextBuilding(numProperties, numHouses, numHotels, numSkyscrapers) {
    // Maximum limits per property
    const maxHousesPerProperty = 16;
    const maxHotelsPerProperty = 8;
    const maxSkyscrapersPerProperty = 1;

    // Conversion ratios
    const housesPerHotel = 3;
    const hotelsPerSkyscraper = 2;

    // Calculate the number of buildings per property
    const housesPerProperty = Math.floor(numHouses / numProperties);
    const hotelsPerProperty = Math.floor(numHotels / numProperties);
    const skyscrapersPerProperty = Math.floor(numSkyscrapers / numProperties);

    // Calculate remainders to help balance the properties
    const housesRemainder = numHouses % numProperties;
    const hotelsRemainder = numHotels % numProperties;
    const skyscrapersRemainder = numSkyscrapers % numProperties;

    // Determine the position for the next building
    const nextPropertyIndex = (numHouses + (numHotels * housesPerHotel) + (numSkyscrapers * hotelsPerSkyscraper * housesPerHotel)) % numProperties;

    // Determine the next building to construct
    if ((skyscrapersPerProperty < maxSkyscrapersPerProperty) && (numHotels >= hotelsPerSkyscraper)) {
        // Check if there are enough hotels for the next skyscraper
        return "skyscraper";
    }
    if ((hotelsPerProperty < maxHotelsPerProperty) && (numHouses >= housesPerHotel)) {
        // Check if there are enough houses for the next hotel
        return "hotel";
    }
    if (housesPerProperty < maxHousesPerProperty) {
        return "house";
    }

    return "No building needed";
}