How to assign importance levels to ints? - java

I'm having to make a program that allows a gerbil to go mining for four metals and the four metals have different levels of value. The gerbil can only carry 10 ounces at a time. The gerbil will prioritize carrying metals of higher value. I am just beginning classes, methods, and constructors, so the code I'm doing can't have anything too advanced. Any help? Here is what I have so far.
public class Gerbil {
private int totalRhodium;
private int totalPlatinum;
private int totalGold;
private int totalIron;
private int totals;
private int limit=10;
public Gerbil() {
}
public int printTotals() {
totals=totalRhodium+totalPlatinum+totalGold+totalIron;
return totals;
}
public void goMining(int rhodium, int platinum, int gold, int iron) {
System.out.println("Rhodium: "+rhodium);
System.out.println("Platinum: "+platinum);
System.out.println("Gold: "+gold);
System.out.println("Iron: "+iron);
}
}

You could try like this:
...
int totals = 0;
int totalsRhodium = 0;
int totalsPlatinum = 0;
int totalsGold = 0;
int totalsIron = 0;
int limit = 10;
public void goMining(int rhodium, int platinum, int gold, int iron) {
if(rhodium >= limit) {
this.totalsRhodium = limit;
return;
} else {
this.totalsRhodium = rhodium;
limit = limit - rhodium;
}
if(platinum >= limit) {
this.totalsPlatinum = limit;
return;
} else {
this.totalsPlatinum = platinum;
limit = limit - platinum;
}
//go on with the other metals
}

Related

Escaping inner loop and go to the outer loop after action is done

There is a code for the BigestCountries class.
It consists of 2 arrays:
private String[][] biggestCountries; - holds country name and the continent, e.g. biggestCountries[CHINA][COUNTRY_NAME] = "China"; biggestCountries[CHINA][COUNTRY_CONTINENT] = "Asia";
private int[][] countryData; - holds populations and year founded, e.g. countryData[CHINA][COUNTRY_POPULATION] = 1433783686; countryData[CHINA][COUNTRY_AGE_FOUNDED] = 1949;
public String[] getCountriesFoundedBetween(int min, int max){
int countriesMatched;
countriesMatched = 0;
String[] countriesFoundedBetween;
if(biggestCountries == null || biggestCountries.length == 0){
return null;
}
for(int i = 0; i < biggestCountries.length; i++){
if(countryData[i][COUNTRY_AGE_FOUNDED] >= min && countryData[i][COUNTRY_AGE_FOUNDED] <= max){
System.out.println(String.format("%d %s", countryData[i][COUNTRY_AGE_FOUNDED], biggestCountries[i][COUNTRY_NAME]));
countriesMatched++;
}
}
if(countriesMatched > 0){
countriesFoundedBetween = new String[countriesMatched];
} else {
return null;
}
for(int i = 0; i < biggestCountries.length; i++) { // outer loop for countries array length of NUMBER_OF_COUNTRIES
String countryMatched = null;
System.out.println("biggestCountries[i] " + biggestCountries[i][COUNTRY_NAME]);
if(countryData[i][COUNTRY_AGE_FOUNDED] >= min && countryData[i][COUNTRY_AGE_FOUNDED] <= max){
for(int j = 0; j < countriesFoundedBetween.length; j++){ // how to escape inner loop?
countryMatched = biggestCountries[i][COUNTRY_NAME];
countriesFoundedBetween[j] = countryMatched;
System.out.println("countriesFoundedBetween: " + countriesFoundedBetween[j] + "; biggestCountries[i][COUNTRY_NAME]: " + biggestCountries[i][COUNTRY_NAME]);
}
}
}
return countriesFoundedBetween;
}
Unfortunately, It cannot escape from the inner loop and re-writes the matched country to all rows of the newly-generated array.
The method getCountriesFoundedBetween() can be implemented differently, without the need for nested loops, as follows.
private static String[] getCountriesFoundedBetween(int min, int max) {
if (max < min) {
throw new IllegalArgumentException("'max' less than 'min'");
}
String[] countriesFoundedBetween;
int countriesMatched = 0;
int[] indexes = new int[biggestCountries.length];
if (biggestCountries != null && biggestCountries.length > 0) {
for (int i = 0; i < biggestCountries.length; i++) {
if(countryData[i][COUNTRY_AGE_FOUNDED] >= min &&
countryData[i][COUNTRY_AGE_FOUNDED] <= max) {
indexes[countriesMatched++] = i;
}
}
countriesFoundedBetween = new String[countriesMatched];
for (int i = 0; i < countriesMatched; i++) {
countriesFoundedBetween[i] = biggestCountries[indexes[i]][COUNTRY_NAME];
}
}
else {
countriesFoundedBetween = new String[0];
}
return countriesFoundedBetween;
}
The above code also returns an empty array rather than null which is preferable for methods that return arrays.
Here is a complete example using population to determine the biggest countries.
public class Countrys {
private static final int CHINA = 0;
private static final int INDIA = 1;
private static final int U_S_A = 2;
private static final int INDONESIA = 3;
private static final int PAKISTAN = 4;
private static final int BRAZIL = 5;
private static final int NIGERIA = 6;
private static final int BANGLADESH = 7;
private static final int RUSSIA = 8;
private static final int MEXICO = 9;
private static final int COUNTRY_NAME = 0;
private static final int COUNTRY_CONTINENT = 1;
private static final int COUNTRY_POPULATION = 0;
private static final int COUNTRY_AGE_FOUNDED = 1;
private static int[][] countryData = new int[][]{{1_427_647_786, 1949},
{1_352_642_280, 1950},
{ 328_239_523, 1776},
{ 273_523_615, 1945},
{ 220_892_340, 1947},
{ 210_147_125, 1889},
{ 206_139_589, 1960},
{ 164_689_383, 1971},
{ 144_384_244, 1991},
{ 128_932_753, 1810}};
private static String[][] biggestCountries = new String[][]{{"China" , "Asia"},
{"India" , "Asia"},
{"U.S.A." , "North America"},
{"Indonesia" , "Asia"},
{"Pakistan" , "Asia"},
{"Brazil" , "South America"},
{"Nigeria" , "Africa"},
{"Bangladesh", "Asia"},
{"Russia" , "Europe"},
{"Mexico" , "North America"}};
private static String[] getCountriesFoundedBetween(int min, int max) {
if (max < min) {
throw new IllegalArgumentException("'max' less than 'min'");
}
String[] countriesFoundedBetween;
int countriesMatched = 0;
int[] indexes = new int[biggestCountries.length];
if (biggestCountries != null && biggestCountries.length > 0) {
for (int i = 0; i < biggestCountries.length; i++) {
if(countryData[i][COUNTRY_AGE_FOUNDED] >= min &&
countryData[i][COUNTRY_AGE_FOUNDED] <= max) {
indexes[countriesMatched++] = i;
}
}
countriesFoundedBetween = new String[countriesMatched];
for (int i = 0; i < countriesMatched; i++) {
countriesFoundedBetween[i] = biggestCountries[indexes[i]][COUNTRY_NAME];
}
}
else {
countriesFoundedBetween = new String[0];
}
return countriesFoundedBetween;
}
public static void main(String[] args) {
String[] result = getCountriesFoundedBetween(1950, 1980);
System.out.println(Arrays.toString(result));
}
}
Running the above code produces the following output:
[India, Nigeria, Bangladesh]
If you name a Class BigestCountries still it has an attribute biggestCountries which is an array, holds information about biggest countries, I think you are not utilizing the potential of OO.
You can use Class to represent the data of a Country. With data encapsulation, you can get rid of nested array thus nested loop and control flow statement (break, continue etc), lookup index constant, keep sync-ing the index between biggestCountries and countryData etc.
Your code doing the same task twice. The first loop count the matched country and initialize a array. The second loop actually put the matched country name to the array.
Java collection framework provide data structure with dynamic size. I use ArrayList here
I think ageFound should be named yearFound?
Refactored Your code
Country.java
public class Country {
private String name;
private int population;
private int yearFound;
private String continent;
public Country(String name, String continent, int year, int population) {
this.name = name;
this.population = population;
this.continent = continent;
this.yearFound = year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
public String getContinent() {
return continent;
}
public void setContinent(String continent) {
this.continent = continent;
}
public int getYearFound() {
return yearFound;
}
public void setYearFound(int yearFound) {
this.yearFound = yearFound;
}
#Override
public String toString() {
return "Country [name=" + name + ", population=" + population + ", yearFound=" + yearFound + ", continent="
+ continent + "]";
}
}
BiggestCountries.java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class BiggestCountries {
private List<Country> countries = new ArrayList<Country>() {
{
add(new Country("China", "Asia", 1949, 1433783686));
add(new Country("Canada", "North America", 1867, 37590000));
add(new Country("United States", "North America", 1776, 328200000));
}
};
public List<Country> getCountriesFoundedBetween(int min, int max) {
List<Country> matchedCountry = new ArrayList<Country>();
Iterator<Country> itrCoutnry = countries.iterator();
while (itrCoutnry.hasNext()) {
Country country = itrCoutnry.next();
int yearFound = country.getYearFound();
if (min < yearFound && max > yearFound) {
matchedCountry.add(country);
}
}
return matchedCountry;
}
}
Test Run
public static void main(String[] args) {
List<Country> matchedCountries = new BiggestCountries().getCountriesFoundedBetween(1700, 1899);
System.out.println(matchedCountries);
}
Result
[Country [name=Canada, population=37590000, yearFound=1867, continent=North America], Country [name=United States, population=328200000, yearFound=1776, continent=North America]]

Method that checks if the method was already executed with that input

public class CatalanNumbers {
private int howManyVariaties;
private int catalanNumber;
private int catalanNumber;
public int catalan(int a) {
if (Method was never executed with that input) {
howManyVariaties++;
int catalanNumber = 0;
for (int i= 0; i < n; i++) {
catalanNumber += catalan(i) * catalan( n- 1 -i);
return catalanNumber
To sum it up I only want to check how the maximum stack depth is.
Can someone help me?
Add a Set to your class that keeps track of what input was used and check that set inside the method
public class CatalanNumbers {
private int howManyVariaties;
private int catalanNumber;
private int catalanNumber;
private Set<Integer> alreadyHandled = new HashSet<>();
public int catalan(int a) {
if (alreadyHandled.add(a)) {
//rest of code
}
}
//...
}

Transferring a changed value from one method to another

so what I am trying to do it take the Value that I am allowing my BargainCustomer to spend, and get him/her to buy the first car they see in the list under that price. Then take the remaining money and buy whatever features they can. However, I do not remember how to call my value for the remaining money from my other method. Here is my code:
import java.util.ArrayList;
public class BargainCustomer implements Customer
{
public Car purchase(ArrayList<Car> listOfCars)
{
int moneyToSpend = 35000;
int moneyLeft = 0;
int indexLocation = 0;
for (int i = 0; i < listOfCars.size(); i++)
{
if (listOfCars.get(i).getBasePrice()<moneyToSpend)
{
moneyLeft=moneyToSpend-listOfCars.get(i).getBasePrice();
indexLocation = i;
}
}
return listOfCars.get(indexLocation);
}
public void upgrade(Car g)
{
int featuresMoney = moneyLeft;
for (int i = 0; i < g.getFeatures().size(); i++)
{
moneyLeft-=g.getFeatures().get(i).getCost();
if (moneyLeft>=0)
{
g.getFeatures().get(i).purchase();
}
}
}
}
Ideally the buyer should only buy what they can afford with the remaining money.
depending on your logic, it would be best to just chain the calls:
import java.util.ArrayList;
public class BargainCustomer implements Customer
{
public Car purchase(ArrayList<Car> listOfCars)
{
int moneyToSpend = 35000;
int moneyLeft = 0;
int indexLocation = 0;
for (int i = 0; i < listOfCars.size(); i++)
{
if (listOfCars.get(i).getBasePrice()<moneyToSpend)
{
moneyLeft=moneyToSpend-listOfCars.get(i).getBasePrice();
indexLocation = i;
}
}
return upgrade(listOfCars.get(indexLocation), moneyLeft);
}
public void upgrade(Car g, int moneyLeft)
{
int featuresMoney = moneyLeft;
for (int i = 0; i < g.getFeatures().size(); i++)
{
moneyLeft-=g.getFeatures().get(i).getCost();
if (moneyLeft>=0)
{
g.getFeatures().get(i).purchase();
}
}
}
}
This will just give you the car with all the features right away, if you need steps in between, you can just use a class variable, or calculate it again. Since you return the car, you can just substract the car price from the moneyToSpend
P.S. are you sure, int is the right choose for money in your case ? it will not handle comma values. Depending on currency, prices are rarly ever without fractions.

Different variable output from same method JAVA genetic algorithm

So i am trying to build a genetic algorithm on java i stuck on getting
fitness of my population here 3 classes from my project:
Class Individu
public class Individu {
int Popsize=4;
int Health[]= new int[Popsize];
int Attack[]= new int[Popsize];
int Atspeed[]= new int[Popsize];
int Move[]= new int[Popsize];
int health,attack,lifetime,dmgdone,attspeed,range,move;
double fitness;
double Pitness[]= new double[20];
Random random = new Random();
public int setHealth(){
health = random.nextInt(150 - 75) + 75;
return health;
}
public int setAttack(){
attack = random.nextInt(10 - 5) + 10;
return attack;
}
public int setAttspeed(){
attspeed = random.nextInt(3 - 1) + 3;
return attspeed;
}
public int setMoveSpeed(){
move = random.nextInt(8 - 4) + 1;
return move;
}
public int getGeneHealth(int index) {
return Health[index];
}
public int getGeneAttack(int index) {
return Attack[index];
}
public int getGeneAtspedd(int index) {
return Atspeed[index];
}
public int getGeneMove(int index) {
return Move[index];
}
public void setGene(int index, int value) {
Health[index]=value;
Attack[index]=value;
Atspeed[index]=value;
Move[index]=value;
fitness = 0;
}
public int size() {
return Popsize;
}
public double[] GenerateIndividual(){
for (int i = 0; i <Popsize; i++) {
Health[i]=setHealth();
Attack[i]=setAttack();
Atspeed[i]=setAttspeed();
Move[i]=setMoveSpeed();
}
return Pitness;
}
Class Fitness
public class Fitness {
Individu individu= new Individu();
double fitness;
double Pitness[]= new double[20];
public double getFitness(){
individu.GenerateIndividual();
for (int i = 0; i <=3; i++) {
fitness=
individu.getGeneHealth(i)+individu.getGeneAtspedd(i)+
individu.getGeneAttack(i)+
individu.getGeneMove(i));
fitness=fitness/171;
Pitness[i]=fitness;
System.out.println("Health from class
fitness"+individu.Health[i]);
}
return fitness;
}
}
Main Class
public class main {
public static void main(String[] args) {
Individu aaa=new Individu();
Fitness bbb= new Fitness();
bbb.getFitness();
aaa.GenerateIndividual();
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(3);
for (int i=0; i<=3; i++){
//System.out.println("Fitness ");
System.out.println("Generasi ke :"+i+1);
System.out.println("Health "+aaa.getGeneHealth(i));
System.out.println("Attackspeed "+aaa.getGeneAtspedd(i));
System.out.println("Attack "+aaa.getGeneAttack(i));
System.out.println("movementSpeed "+aaa.getGeneMove(i));
}
}
}
What i struggle is when i run this script i got 2 double value from 1 variable first value is from Fitness class as i printed here
System.out.println("Health from class fitness"+individu.Health[i]);
and second variable i printed here from Main Class
System.out.println("Health "+aaa.getGeneHealth(i));
that 2 variable is always have different value causing my fitness and my generation is not correlated each other.
My question is how to make this 2 variable print same value?
Well, aside from the many problems I can detect about the essentials of Genetic Algorithms, I see 'individu' and 'aaa' are two different Java objects.
Individu aaa=new Individu();
aaa.GenerateIndividual();
and
Individu individu= new Individu();
individu.GenerateIndividual();
Since your Health and Fitness are randomly generated on GenerateIndividual(), both 'aaa' and 'individu' will get different Health values.
I strongly recommend you to review GA essentials, since I can see many conception errors in your system.

How to sort an array when it is filled with numbers from a get method

Arrays.sort() gives and error of:
FiveDice.java:19: error: no suitable method found for sort(int)
Arrays.sort(compNums);
If I take anything out of the for loop, it thinks thee is only 1 number or gives an error. What other sorting options would be usable?
import java.util.*;
public class FiveDice {
public static void main(String[] args) {
int x;
int compNums = 0;
int playerNums;
Die[] comp = new Die[5];
Die[] player = new Die[5];
System.out.print("The highest combination wins! \n5 of a kind, 4 of a kind, 3 of a kind, or a pair\n");
//computer
System.out.print("Computer rolled: ");
for(x = 0; x < comp.length; ++x) {
comp[x] = new Die();
compNums = comp[x].getRoll();
//Arrays.sort(compNums); <--does not work
System.out.print(compNums + " ");
}
//player
System.out.print("\nYou rolled: \t ");
for(x = 0; x < player.length; ++x) {
player[x] = new Die();
playerNums = player[x].getRoll();
System.out.print(playerNums + " ");
}
}
}
die class
public class Die {
int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die()
{ }
public int getRoll() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
return roll; }
public void setRoll()
{ this.roll = roll; }
}
Easiest way is to implement Comparable to Die class , set value of roll in constructor of Die not in the getter method and your problem is solved.
public class Die implements Comparable<Die> {
private int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
}
public int getRoll() {
return roll;
}
public void setRoll(int roll) {
this.roll = roll;
}
public int compareTo(Die d) {
return new Integer(d.getRoll()).compareTo(new Integer(this.getRoll()));
}
}
now Arrays.sort(Die[]) will sort the array of Die.
You don't have to use 2 arrays for the sorting. If you implement the Comparable<T> interface, your classes can be sorted by Java Collections API. In your case, Die class can implement Comparable<T> and provide a way for the Java framework to compare dice values.
Take a look at the Java API:
http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
In your case:
public class Die implements Comparable<Die>{
int roll;
final int HIGHEST_DIE_VALUE = 6;
final int LOWEST_DIE_VALUE = 1;
public Die() { }
public int computeRoll() {
roll = ((int)(Math.random() * 100) % HIGHEST_DIE_VALUE + LOWEST_DIE_VALUE);
return roll;
}
// I also changed this to store the value
public int getRoll() {
return roll;
}
public void setRoll() { this.roll = roll; }
// This is the method you have to implement
public int compareTo(Die d) {
if(getRoll() < d.getRoll()) return -1;
if(getRoll() > d.getRoll()) return +1;
if(getRoll() == d.getRoll()) return 0;
}
}
Whenever you have a Collection of Dies, like an ArrayList or LinkedList, you simply sort the collection itself. Below is a sample code.
ArrayList<Die> myCollection = new ArrayList<Die>();
myCollection.add(die1);
// more array population code
// ...
Collections.sort(myCollection);
You can't perform sort() on compNums because it is a single value. You declare it as an int value, rather than as an array of integers.
Instead, you should make compNums an array, populate it with the Die roll values, and then perform a sort operation on the resultant array. I believe the following will achieve what you are after.
int[] compNums = new int[5];
...
for(x = 0; x < comp.length; ++x) {
comp[x] = new Die();
compNums[x] = comp[x].getRoll();
}
Arrays.sort(compNums);
// print results
you must pass an array to the Array.Sort(arr) not parameter you must do something like this Array.Sort(int[]compNums);
and if you are using a anonymous type like comp[]compNums you must do it like this
java.util.Arrays.sort(comp[]compNums, new java.util.Comparator<Object[]>() {
public int compare(Object a[], Object b[]) {
if(something)
return 1;
return 0;
}
});

Categories