Politics and War Wiki
Politics and War Wiki
Advertisement

Formulas relation to cities.

New City Cost Formula

Exponential

This formula is cubic.

Next City Cost = 50000*(X-1)^3 + 150000*X + 75000
  • Where X is the current number of cities.

Infrastructure Cost Formula

This formula is exponential.

The formula for infrastructure cost is:

Infra Unit Cost = [((Current Infra-10)^2.2) / 710] + 300

Using the above formula to plug in the cost per unit results in the formula for infra cost.

Cost = Infra Unit Cost * Infra to buy

The following PHP function calculates the infra price:

<?php 
function infraPrice($amount) {
    //old return (pow(abs($amount-10),1.95)*0.01) + 300; 
    return (pow(abs($amount - 10), 2.2) / 710) + 300;
    } 
function calcInfraValue($starting_amount = 0, $ending_amount = 100) {
    //set some vars
    $value = 0;
    $cost_of_chunk = 0;

    //round values to nearest 2 decimals
    $starting_amount = round($starting_amount, 2);
    $ending_amount = round($ending_amount, 2);

    //check difference between amounts
    $difference = $ending_amount - $starting_amount;

    //cap out at 10,000 to prevent script running forever
    if ($difference > 10000) {
        return "Error";
        } 

    //if values are the same, no need to continue
    if ($difference == 0) {
        $value = 0;
        return $value;
        }

    //if values are not the same, we need to make sure that the starting amount is smaller than the ending amount
    if ($difference < 0) {
        $infraPrice = 150;
        $value = $infraPrice * $difference;
        return $value;
        }

    //break into chunks of 100, and get the price
    if ($difference > 100 AND ( $difference % 100 == 0)) {
        $cost_of_chunk = round(infraPrice($starting_amount), 2) * 100;
        
        //recursively get value of next chunk
        $value += ($cost_of_chunk + calcInfraValue(($starting_amount + 100), $ending_amount));
        return $value;
        }

    //see if the amount left is not divisible by 100 but greater than 100
    if ($difference > 100 AND ( $difference % 100 != 0)) {
        $cost_of_chunk = round(infraPrice($starting_amount), 2) * ($difference % 100);

        //recursively get value of next chunk
        $value += ($cost_of_chunk + calcInfraValue(($starting_amount + ($difference % 100)), $ending_amount));
        return $value;
        }

    //if there's less or equal to 100 left, just add that. No need for recursion
    if ($difference <= 100) {
        $cost_of_chunk = round(infraPrice($starting_amount), 2) * $difference;
        $value += $cost_of_chunk;
        return $value;
        }
    }
?>
Google sheets

The following is the app script version for google sheets of the above PHP.

function calculateInfrastructureCost(startRange = "A2:A", endRange = "B2:B", outputRange = "C2:C", outputToSheet = true, calledFromFormula = true) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var startValues = sheet.getRange(startRange).getValues();
  var endValues = sheet.getRange(endRange).getValues();
  var costValues = [];
  for (var i = 0; i < startValues.length; i++) {
    var start = startValues[i][0];
    var end = endValues[i][0];
    if (start !== "" && end !== "") {
      var cost = calcInfraValue(start, end);
      costValues.push([cost]);
    } else {
      costValues.push([""]);
    }
  }
  
  if (outputToSheet && !calledFromFormula) {
    try {
      sheet.getRange(outputRange).setValues(costValues);
    } catch (error) {
      // Handle error
    }
  }
  
  return costValues;
}
function infraPrice(amount) {
  if (amount < 10) {
    return 300;
  } else {
    return Math.pow(Math.abs(amount - 10), 2.2) / 710 + 300;
  }
}

function calcInfraValue(startingAmount, endingAmount) {
  // round values to nearest 2 decimals
  startingAmount = Math.round(startingAmount * 100) / 100;
  endingAmount = Math.round(endingAmount * 100) / 100;

  // check difference between amounts
  const difference = endingAmount - startingAmount;

  // cap out at 10,000 to prevent script running forever
  if (difference > 10000) {
    return "Error";
  }

  // if values are the same, no need to continue
  if (difference === 0) {
    return 0;
  }

  // if values are not the same, we need to make sure that the starting amount is smaller than the ending amount
  if (difference < 0) {
    const infraPrice = 150;
    return infraPrice * difference;
  }

  // break into chunks of 100, and get the price
  if (difference > 100 && difference % 100 === 0) {
    const costOfChunk = Math.round(infraPrice(startingAmount) * 100) / 100 * 100;

    // recursively get value of next chunk
    return costOfChunk + calcInfraValue(startingAmount + 100, endingAmount);
  }

  // see if the amount left is not divisible by 100 but greater than 100
  if (difference > 100 && difference % 100 !== 0) {
    const costOfChunk = Math.round(infraPrice(startingAmount) * 100) / 100 * (difference % 100);

    // recursively get value of next chunk
    return costOfChunk + calcInfraValue(startingAmount + (difference % 100), endingAmount);
  }

  // if there's less or equal to 100 left, just add that. No need for recursion
  if (difference <= 100) {
    const costOfChunk = Math.round(infraPrice(startingAmount) * 100) / 100 * difference;
    return costOfChunk;
  }
}

In the function calculateInfrastructureCost, there are 5 variables: startRange, endRange, outputRange, outputToSheet, and calledFromFormula.

startRange is the cell or range of cells with the starting infrastructure of the city or cities. endRange is the cell or range of cells with the desired ending infrastructure of the city or cities. outputRange is the cell or range of cells where you would like to display the results. outputToSheet lets you toggle whether to use calculateInfrastructureCost in this way on or off with true or false. In the code above, it is set to use cells A2:A for the starting infrastructure, B2:B for the ending infrastructure, C2:C for the results, and it is turned on (true). The last variable, calledFromFormula, indicates whether the function is being called from a formula in a cell or from a script. By default, it is set to true, which means that the function is being called from a formula in a cell. However, when calling the function from a script, you should set calledFromFormula to false. This can be done by passing false as the fifth argument when calling the function. Alternatively, if you are not going to use calls from a cell and only plan to call the function from a script, you can set the calledFromFormula variable to false in the code above.

If you have set the above values to what you want and have it turned on (outputToSheet = true), you will need to set up a trigger in Apps Script, in the triggers menu. Alternatively, if you are using the API, add calculateInfrastructureCost("A2:A", "B2:B", "C2:C", true, false); to the end of your script calling the API so it runs after.

If you prefer not to write to your sheet automatically, you can set outputToSheet = false to stop it from writing to your sheet and use the following formula: =calculateInfrastructureCost("startValue/s", "endValue/s")

Examples:

=calculateInfrastructureCost("A2","B2") will display the result in the cell where the formula is entered.

=calculateInfrastructureCost("A2:A","B2:B") will display the results starting with the cell where the formula is entered and continuing down the column. If your sheet is an older version of Google Sheets, you will need to add an array to the formula to achieve this: =ARRAYFORMULA(calculateInfrastructureCost("A2:A", "B2:B"))

Land Cost Formula

This formula is exponential.

The formula for the cost of one unit of land is the following:

Land Unit Cost  = 0.002*(Current Land-20)^2 + 50

Using the above formula to plug in the cost per unit results in the formula for land cost.

Cost = Land Unit Cost * Land to buy

The following PHP function calculates the land price:

<?php

function landPrice($amount) {

	return (.002*($amount-20)*($amount-20))+50;
	
}

function calcLandValue($starting_amount=20, $ending_amount = 500) {

	//set some vars
	$value 		   = 0;
	$cost_of_chunk = 0;
	
	//round values to nearest 2 decimals
	$starting_amount = round($starting_amount,2);
	$ending_amount   = round($ending_amount,  2);
	
	//check difference between amounts
	$difference = $ending_amount - $starting_amount;
	
	//cap out at 10,000 to prevent script running forever
	if($difference > 10000) {
		return "Error";
	}
	
	//if values are the same, no need to continue
	if($difference == 0) {
		$value = 0;
		return $value;
	}
	
	//if values are not the same, we need to make sure that the starting amount is smaller than the ending amount
	if($difference < 0) {
		$landPrice = 50;
		$value = $landPrice * $difference;
		return $value;
	}
	
	//break into chunks of 500, and get the price
	if($difference > 500 AND ($difference % 500 == 0)) {
		
		$cost_of_chunk = round(landPrice($starting_amount),2) * 500;
		//recursively get value of next chunk
		$value 		  += ($cost_of_chunk + calcLandValue(($starting_amount + 500), $ending_amount));
		return $value;
		
	}
	
	//see if the amount left is not divisible by 500 but greater than 500
	if($difference > 500 AND ($difference % 500 != 0)) {
		
		$cost_of_chunk = round(landPrice($starting_amount),2) * ($difference % 500);
		//recursively get value of next chunk
		$value += ($cost_of_chunk + calcLandValue(($starting_amount + ($difference % 500)), $ending_amount));
		return $value;
		
	}
	
	//if there's less or equal to 500 left, just add that. No need for recursion
	if($difference <= 500) {
		$cost_of_chunk = round(landPrice($starting_amount),2) * $difference;
		$value 		  += $cost_of_chunk;
		return $value;
	}
	
}

?>


Population Formulas

Before other factors are applied, the formula for population by infrastructure is:

Base Population = Infrastructure * 100

The formula after all everything's been factored in is:

Population = (Base Pop - ((Disease Rate * 100 * Infra)/100) - MAX((Crime Rate / 10) * (100*Infra) - 25, 0) * (1 + ln(CityAgeInDays)/15)

Or simplified

Population = (Base Pop - Disease Deaths - Crime Deaths) * Age Bonus

The age bonus is a function of decreasing returns to city age. The formula is:

Age Bonus = 1 + ln(CityAgeInDays)/15

Population Density Formula

  • The formula used for population density when factoring Disease is different than the actual population density. The reason for this, is that Disease (based on Population Density) will kill a percentage of the Base Population, lowering the displayed Population Density. If there was no difference, the formula would feed back on each other.

Equation Specific Formula

Population Density = Base Population / Land Area

Displayed Population Formula

Population Density = Actual Population / Land Area

Crime and Disease Rate Formulas

Note: Both formulas are returned as a percent for use in the population lost formulas.

Crime

Note: 0≤ Crime Rate ≤100

Crime (%) = ((103 - Commerce)^2 + ( Infrastructure * 100))/(111111) - Police Modifier

Where Police Modifier is:

Police Modifier = (# of Police Stations)*(2.5)

Disease

Disease Rate = ((((Population Density^2) * 0.01) - 25)/100) + (Base Population/100000) + Pollution Modifier - Hospital Modifier
  • Pop density is based on base population not on displayed population

Pollution Modifier is the increase to disease, from increasing Pollution.

Pollution Modifier = Pollution Index * 0.05

Hospital Modifier is the amount of disease reduced by buying Hospitals.

Hospital Modifier = Hospital Count * 2.5

Population Lost Formulas

Crime

Crime Deaths = (Crime Rate/10)*(Infrastructure*100)-25

Disease

Disease Deaths = Disease Rate * Base Population

Food Production Formula

The basic formula for food production per turn in a city is:

Food Production = Farm Count * (Land Area / 500)

Modifiers to this basic formula include:

  • If the Mass Irrigation Nation Project is built the formula is changed to Farms * (Land Area / 400)
  • If the season is Summer the production is changed to Food * 1.2
  • If the season is Winter the production is changed to Food * .8

Radiation Formula Effect

Final Food Prod = Food Production * (nation+continent+global rad index)/1000

Misc

NOTE: These are things to be moved out but I wanna use somewhere else and need somewhere to store it temporarily.

Land

From the two above formulas, it is made evident that, since the price of new land depends on the level of your current land, it is more profitable to buy land in bulks. In other words, it is more profitable to get land from 500 to 1,000 than from 500 to 750 and then to 1,000.

However, there is one limitation: the game identifies several levels of land, meaning that they are bought in steps. The levels are 500, 1k, 1.5k, 2k land, etc. and each step is 500 Land (except for the first step which is 250, since your city gets 250 land when it is first built). This means that, if you decide to get for example from 250 to 1k land and buy that much land, the game will automatically calculate two transactions instead of one: one from 250 Land to 500 and one from 500 to 1,000. The game calculates the optimized cost for the land you decide to purchase.

Note that the Tutorial will make you buy 500 Land at your first city and as such, your first city will have 750 Land at some point. Going to the next step and buying 250 Land to reach 1,000 will set you back to course of the optimized land purchases.

Advertisement