// rdk import java.util.Random; // look for subsections of phrase starting from largest looking to smallest (award small point bonus and then break if one is found) public class Organism { public StringBuffer DNA; public StringBuffer aminoAcidChain; public double survivalValue; public double myLengthBonus; public double myMatchingBonus; public double myContainsBonus; public static double maxSurvivalValue = 0; public int yearsToLive; public static String idealPhrase; public static double probabilityForMutation; public String parent1DNA; public String parent2DNA; public int numOfMuts; // the number of genetic mutations taken place on the DNA of the organism private static double maxLengthBonus = 2.4; private static double lengthGrowthFunc = 1.45; // higher the number the more extreme curve private static double maxValueBonus = 3; private static double valueGrowthFunc = 1.35; private static double containsBonusDivider = 7; public Organism(){ // create single-letter organism numOfMuts = 0; DNA = new StringBuffer(); aminoAcidChain = new StringBuffer(); // start out with 3 DNA bases DNA.append(getRandomChar()); DNA.append(getRandomChar()); DNA.append(getRandomChar()); giveAminoAcidChain(); parent1DNA = "origin of life"; parent2DNA = "origin of life"; survivalValue = survivalRating(aminoAcidChain); yearsToLive = giveYearsToLive(survivalValue); // run through the survival rating function // run through the yearsToLive function (converts survival rating into a year value) } public Organism(Organism parent){ parent1DNA = parent.DNA.toString(); parent2DNA = parent.DNA.toString(); DNA = new StringBuffer(parent.DNA.toString()); aminoAcidChain = new StringBuffer(); // randomly pick between the two parents' DNA // genetic mutations (number determined by some probability) int numOfMutations = 0; for(int i = 0; i < DNA.length(); i++){ if(isYes(probabilityForMutation)) numOfMutations++; } numOfMuts = numOfMutations; for(int i = 0; i< numOfMutations; i++){ randomlyAlterString(DNA); } giveAminoAcidChain(); survivalValue = survivalRating(aminoAcidChain); yearsToLive = giveYearsToLive(survivalValue); } public Organism(Organism parent1, Organism parent2){ parent1DNA = parent1.DNA.toString(); parent2DNA = parent2.DNA.toString(); DNA = new StringBuffer(); aminoAcidChain = new StringBuffer(); // randomly pick between the two parents' DNA int pickParent = getRandomNumber(1); // pick which parent's DNA length to match int lengthOfDNA = 0; if(pickParent == 0) lengthOfDNA = parent1.DNA.length(); else lengthOfDNA = parent2.DNA.length(); int choice = 0; boolean done = false; for(int i = 0; (i*3) < lengthOfDNA ; i++){ if(parent1.DNA.length() >= (i*3)+3 && parent2.DNA.length() >= (i*3)+3){ choice = getRandomNumber(1); if(choice == 0) DNA.append(parent1.DNA.substring((i*3), (i*3) + 3)); else DNA.append(parent2.DNA.substring((i*3), (i*3) + 3)); } else{ if(pickParent == 0) DNA.append(parent1.DNA.substring((i*3), lengthOfDNA)); else DNA.append(parent2.DNA.substring((i*3), lengthOfDNA)); done = true; } if(done == true) break; } // genetic mutations (number determined by some probability) int numOfMutations = 0; for(int i = 0; i < DNA.length(); i++){ if(isYes(probabilityForMutation)) numOfMutations++; } numOfMuts = numOfMutations; for(int i = 0; i< numOfMutations; i++){ randomlyAlterString(DNA); } giveAminoAcidChain(); survivalValue = survivalRating(aminoAcidChain); yearsToLive = giveYearsToLive(survivalValue); } private char getRandomChar(){ Random r = new Random(); int randLetterNum = Math.abs(r.nextInt()) % 4; char randChar = "augc".charAt(randLetterNum); // get random lower-case letter return randChar; } private void giveAminoAcidChain(){ // basic first, add more complex rules later int possibleNumberOfAminoAcidsInChain = (int)Math.floor(DNA.length() / 3); String threeBases = null; char theAminoAcid = ' '; for(int i = 0; i < possibleNumberOfAminoAcidsInChain; i++){ threeBases = DNA.substring(i*3, (i*3) + 3); theAminoAcid = getAminoAcid(threeBases); if(theAminoAcid == 'Z') // if stop code break; aminoAcidChain.append(theAminoAcid); } } private char getAminoAcid(String threeBases){ if(threeBases.equals("uuu") || threeBases.equals("uuc")) // phenylalanine return 'F'; else if(threeBases.equals("uua") || threeBases.equals("uug") || threeBases.equals("cuu") || threeBases.equals("cuc") || threeBases.equals("cua") || threeBases.equals("cug")) // leucine return 'L'; else if(threeBases.equals("auu") || threeBases.equals("auc") || threeBases.equals("aua")) // isoleucine return 'I'; else if(threeBases.equals("aug")) // methionine return 'M'; else if(threeBases.equals("guu") || threeBases.equals("guc") || threeBases.equals("gua") || threeBases.equals("gug")) // valine return 'V'; else if(threeBases.equals("ucu") || threeBases.equals("ucc") || threeBases.equals("uca") || threeBases.equals("ucg") || threeBases.equals("agu") || threeBases.equals("agc")) // serine return 'S'; else if(threeBases.equals("ccu") || threeBases.equals("ccc") || threeBases.equals("cca") || threeBases.equals("ccg")) // proline return 'P'; else if(threeBases.equals("acu") || threeBases.equals("acc") || threeBases.equals("aca") || threeBases.equals("acg")) // threonine return 'T'; else if(threeBases.equals("gcu") || threeBases.equals("gcc") || threeBases.equals("gca") || threeBases.equals("gcg")) // alanine return 'A'; else if(threeBases.equals("uau") || threeBases.equals("uac")) // tyrosine return 'Y'; else if(threeBases.equals("uaa") || threeBases.equals("uag") || threeBases.equals("uga")) return 'Z'; // stop signal else if(threeBases.equals("cau") || threeBases.equals("cac")) // histidine return 'H'; else if(threeBases.equals("caa") || threeBases.equals("cag")) // glutamine return 'Q'; else if(threeBases.equals("aau") || threeBases.equals("aac")) // asparagine return 'N'; else if(threeBases.equals("aaa") || threeBases.equals("aag")) // lysine return 'K'; else if(threeBases.equals("gau") || threeBases.equals("gac")) // aspartic acid return 'D'; else if(threeBases.equals("gaa") || threeBases.equals("gag")) // glutamic acid return 'E'; else if(threeBases.equals("ugu") || threeBases.equals("ugc")) // cysteine return 'C'; else if(threeBases.equals("ugg")) // trptophan return 'W'; else if(threeBases.equals("cgu") || threeBases.equals("cgc") || threeBases.equals("cga") || threeBases.equals("cgg") || threeBases.equals("aga") || threeBases.equals("agg")) // arginine return 'R'; else if(threeBases.equals("ggu") || threeBases.equals("ggc") || threeBases.equals("gga") || threeBases.equals("ggg")) // glycine return 'G'; else return '!'; // error! // list of all base triplets for amino acids } public void updateOrganism(){ survivalValue = survivalRating(aminoAcidChain); yearsToLive = giveYearsToLive(survivalValue); } private void randomlyAlterString(StringBuffer workingString){ int numberOfOptions = (3 * workingString.length()) + 1; Random r = new Random(); int randInt = Math.abs(r.nextInt()) % numberOfOptions; // get operation to perform (insertion or value change) int randLetterNum = Math.abs(r.nextInt()) % 4; char randLetter = "augc".charAt(randLetterNum); // get random lower-case letter if(randInt <= workingString.length()){ // insert/ append letter // insert (remember case of insert after the end if(randInt < workingString.length()) workingString.insert(randInt, randLetter); else workingString.append(randLetter); } else if (randInt > workingString.length() && randInt < (2 * workingString.length()) +1){ // modify existing letter // alter existing letter ( letter at position randInt - 2 ) workingString.setCharAt(randInt - workingString.length() -1, randLetter); } else{ if(workingString.length() >= 1) workingString.deleteCharAt(randInt - (2 * workingString.length()) - 1); } } // compare the workingString to idealPhrase and return a value based on how well they match up private double survivalRating(StringBuffer workingString){ double theScore = 0; if(workingString.length() == 0 && idealPhrase.length() != 0){ return 0; } // environment favors the workingString to be the same length as idealPhrase int numberOfLetters = 0; if(workingString.length() <= idealPhrase.length()) numberOfLetters = workingString.length(); else numberOfLetters = (2 * idealPhrase.length()) - workingString.length(); if(numberOfLetters < 0) numberOfLetters = 0; double lengthBonus = (Math.pow(lengthGrowthFunc, (double)numberOfLetters + (10 - idealPhrase.length()))); lengthBonus = (lengthBonus/ Math.pow(lengthGrowthFunc, 10)) * maxLengthBonus; // max of maxLengthBonus points added to the score if the length of workingString is the same as idealPhrase if(numberOfLetters == 0) lengthBonus = 0; myLengthBonus = lengthBonus; theScore += lengthBonus; // environment favors the workingString to have the same values as idealPhrase double numberMatch = 0; for(int i = 0; i < workingString.length(); i++){ if((idealPhrase.length() - 1) >= i){ if(workingString.charAt(i) == idealPhrase.charAt(i)) numberMatch++; } } double matchingBonus = (Math.pow(valueGrowthFunc, (double)numberMatch + (10 - idealPhrase.length()))); matchingBonus = (matchingBonus / Math.pow(valueGrowthFunc, 10)) * maxValueBonus; if(numberMatch == 0) matchingBonus = 0; myMatchingBonus = matchingBonus; theScore += matchingBonus; //environment has some favortism towards the workingString that contains values of the idealPhrase double containsBonus = 0; if(idealPhrase.contains(workingString)){ containsBonus = (Math.pow(valueGrowthFunc, 1 + (10 - idealPhrase.length()))); containsBonus = (containsBonus / Math.pow(valueGrowthFunc, 10)) * (maxValueBonus / containsBonusDivider); if(workingString.length() == 0) containsBonus = 0; } myContainsBonus = containsBonus; theScore += containsBonus; return theScore; } private int giveYearsToLive(double survivalValue){ // max survival rating double maxContainsBonus = 0; maxContainsBonus = (Math.pow(1.5, 1 + (10 - idealPhrase.length()))); maxContainsBonus = (maxContainsBonus / 57.665039) * (maxValueBonus / 3); maxSurvivalValue = maxLengthBonus + maxValueBonus + maxContainsBonus; double probabilityOfLiving = (survivalValue / maxSurvivalValue) * .95; // .95: not all "perfect" organisms live (5% die) boolean live = isYes((probabilityOfLiving)); if(live){ if(survivalValue >= 1) return (int)Math.round(survivalValue); else return 1; } else return -1; } private int getRandomNumber(int max){ Random r = new Random(); int randNum = Math.abs(r.nextInt()) % (max + 1); return randNum; } private boolean isYes(double probability){ Random r = new Random(); int randNum = (Math.abs(r.nextInt()) % 1000) + 1; if(randNum >= 0 && randNum<= (probability * 1000)){ return true; } return false; } }