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:
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";
}
Ruby code (IDK javascript; read as pseudocode):
def f(numOfHouses, numOfHotels, numOfSkyScrapers, numOfProperties)
return "skyScraper" if numOfSkyScrapers % numOfProperties != 0
return "skyScraper" if numOfSkyScrapers == 0 && numOfHotels == numOfProperties * 2
return "hotel" if numOfHotels % numOfProperties != 0
return "hotel" if numOfHotels < 8 * numOfProperties && numOfHouses == numOfProperties * 3
return "house" if numOfHouses < 16
return "no building needed"
end
Is this clear? We build skyscrapers if either we're not maxed out and we have the right number of hotels, or we're in the process of building a set of skyscrapers (so count mod properties isn't zero).
If we're not building skyscrapers, we build hotels following the same logic.
Otherwise we build houses if we have capacity.
Sample output:
> f(0,0,0,2)
=> "house"
> f(1,0,0,2)
=> "house"
> f(2,0,0,2)
=> "house"
> f(3,0,0,2)
=> "house"
> f(4,0,0,2)
=> "house"
> f(5,0,0,2)
=> "house"
> f(6,0,0,2)
=> "hotel"
> f(3,1,0,2)
=> "hotel"
> f(0,2,0,2)
=> "house"
> f(1,2,0,2)
=> "house"
> f(2,2,0,2)
=> "house"
> f(6,2,0,2)
=> "hotel"
> f(3,3,0,2)
=> "hotel"
> f(0,4,0,2)
=> "skyScraper"