From 919eee67f83cd67906113adfca36485658029436 Mon Sep 17 00:00:00 2001 From: Daeva Date: Tue, 21 Mar 2023 20:58:00 +0400 Subject: [PATCH 1/6] name change --- .idea/modules.xml | 2 +- ...d.iml => evolutionary-altruism-simulation.iml | 0 .../Simulation/Main.class | Bin 0 -> 686 bytes .../Simulation/Simulation$Altruist.class | Bin 0 -> 853 bytes .../Simulation/Simulation$Coward.class | Bin 0 -> 756 bytes .../Simulation/Simulation$Entity.class | Bin 0 -> 555 bytes .../Simulation/Simulation.class | Bin 0 -> 3031 bytes .../Simulation/Utils.class | Bin 0 -> 539 bytes 8 files changed, 1 insertion(+), 1 deletion(-) rename JavaPlayground.iml => evolutionary-altruism-simulation.iml (100%) create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Main.class create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Altruist.class create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Coward.class create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Entity.class create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation.class create mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Utils.class diff --git a/.idea/modules.xml b/.idea/modules.xml index 425ed52..5a06d60 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/JavaPlayground.iml b/evolutionary-altruism-simulation.iml similarity index 100% rename from JavaPlayground.iml rename to evolutionary-altruism-simulation.iml diff --git a/out/production/evolutionary-altruism-simulation/Simulation/Main.class b/out/production/evolutionary-altruism-simulation/Simulation/Main.class new file mode 100644 index 0000000000000000000000000000000000000000..7e78fc6fe8ab6e3fcc91bcf775cfd7e3e304ecfb GIT binary patch literal 686 zcmZva-EPxB5QWbsPMjFGaT6zn{*llYoEEUeZ7Ob%P%EV^Qc$F-SDVyIxAG5i91xEM z7p(*m55Pkq&N`JsQG7ApnKSdv%-X;I{P+c+hgTK~D4H;Alu#CMZscd_hcce{=cAio zoC%bVRIIYM0!6PotfGRd3CqSK*bmYNU#D3RF)Nv|sM*g!D)B$0D$WL38px)oCRl)RIZ?odZIZERs%pfa7;1OkRf&BRlI+M?P&m5N=BcgYn~YJC+4XR~M& zq#xxdWTf6t#xfkrRB8V{Xk^!FDzMi7kJBS4%6TpCa@iWxWjbMLV~H$a-4DwJ1=jzi zFB-9jHArUZIC!u0fK|P~YkjHcV27VtKLzkEP^N9u^Z6Ehmk#bAzU6Xfgc5Ph3CwwoFf(ob3_1wxy&0(uV=p{Ny>LJv(T=WVhgi=1_3uOsEcFG5Hh z5Qqam0HuEkF&kUNio#_+cHX?1otfW%e*OZ`!u}EpC_1n_lwdRLbmcG!xR#-MJ~QjD z105wY)(o~D$hdyQu+f>tbI?{9E|wgWJuJgxxVI2hKT%rhG10w{O6p^Vt;T=&nwQqg z$>hd5?o4jVsN#-;nuisvGE{Ti@3ahJhRqK`pL5j@hiA#~N<_Zu1xYMNf}zy#{ie@g zwZlHSm5x**1zqr~fL>~yu*ZW-9!cY8kCyo_!|vkl{tc#;mhL9eNRD`L&b4?y5UM)} z6B=5v(L80?rrzcOCrS**Zv|miP3Ph|3j0aVjK3WwDov%H%iS=Edg4@?J}a|tKl{i> zoWVU4v3?WA+QDOnwOKs37zWQ*N<{5|$FZO%c=g2AA%FRjcM4$g;r99!ai| z_ln{L(#r>j-@pzIzr*=TZUO5gZ2|!iHb}0gFl^#3d6Y1vV}#hkc1HG;w8<#eZhaw@ zC(%<9Qfgc5PcIncA6RzLcb`bv@}RbE1>tFa)?@CDfG}lId78{-O5=bdmYp(5*L08 zLgIix9QXkU{t{v~wupu3W#7)udv9iEe*FIS9Y7EF7f^xY!wpb{N7xvuNfrsCV*O}- zZTI6hA{i4rbFR|%K4En*&z6Y2I%-((Q4g?);7YqgZIroWyT?i^b3j<{T;bO}bq@wV zf7Q`I)5nbfE!-qDOT}Lp6{Uo=SJIpaJ&q^G+2l+np&mt9s-}`q?Sx@BB)I)}%wc1o zw9HA*#aYBJtwB5z(Wyw3jf+RuewDEK|Hg`m^a!`P@GwiJYAT`=VdTqmsSmZBTt1VA z;B>l2geBXYe4WJOY-C5`gdS=I>%G!TQ50$gD|+6>MOV^|B%4D2g#X2Z2p;?a z{wQ(M3h|(qnVor$$J;lbU+*6P+Sr{(0YwLvhdJ1U?SUGlp)e}at^8R((MFjG!8Q*n zsUH!ly&U~TY`Z97-hu030Up7B6l2i}g}!fH4j*M;SmIb|WjcgnWB-OwYy6{>fmS!V zlZ0|lY1vOlLm6L-VaS`6UKEJ%M#L(cf0kBejuOf)UT;#gMQ-|>acei=)3TnQ= zdEu#mGFO{9z%zWV>oXRXvBDGcr)p#oR#5@CuQ4Z6uW~J51Dn%c!}gR-ysKfyqHjI! BfTsWe literal 0 HcmV?d00001 diff --git a/out/production/evolutionary-altruism-simulation/Simulation/Simulation.class b/out/production/evolutionary-altruism-simulation/Simulation/Simulation.class new file mode 100644 index 0000000000000000000000000000000000000000..6c468551f28f3fe1367e1c6b3ba44bb4a463bdc7 GIT binary patch literal 3031 zcmaJ@+jA4w8UGzw*2-c5#Wpy`#yGBVWVu9yBqT;$3IZ1s+er|$W1tDg(qgSG?<%`1 z6Xl+kCQWZiFKK~?W~QBvpLj?In-)5~JT`Cn2l|$ozV)#!li>W$t`x~Z$!KQJIp6ut zclmuceRTKMUjd|XErt+UG=z1uA|eo9kjpYvl-7LesksFs=Ltj(nwIGu7HCNfPq!h8 zHVrWyo1hD9%bH8&qV!DLO4YXlo$84xi${x|Q#M^MW0x(8665Oq79CsFK73^8;zh-Czm9I~5ZGi`#!@9ykXFv1 z{xJ=`0v*1SWzQ_8jyjI4Owhs@deEX??$XhZ2Lz&2O&<)GUQRT5kk;@Gfxf!e4FC+* zY>r_7yA`xU0y`2DO_|ff(@J?l$1svaS?2RpnFw??L?S(WR>L<1dYeia3{Z$+1iO{E zl#ac4SRm}0FVSRaAV?Q3>5bA8j^^7HQ*=0tl>aJ<0o_0*j%X*F>m(uOb zmr)%DkQV4#l8Z*hwsO*&F}(tJt|u)|L6sOEZm^thO=~_K!yz2ja74$qaI}X1M)?9- zNogxuUvj=GA^<6)uskl%U4_SwVa6^NnW@adDwJb7zKxR%q3Icp^lV39d!lNV|6;sK zPjA90JgH$q$0Vkhk@Yy&SZG&4x>LrB1co4X1d=5vL$)R zs&#@czq%{;pg_EW8fWf*~uAWrh;N?y}}<-S;00oWw_p?q2Qv__%Yk|T+fjuM!aC>-K`N^j^PJ* zOT*i$M1LqSSWhR@TDBLBR8UAk)sD#=%Yt@ZY3wsq#z5#vW?#{82PbTMv0O^uThtAd z4G+)I%O>pS8u)|Jl5Xr2RS_9kEM{4@=_r20mKm!f(QjCJBj0aZ{e-q(MDY`W&6!|C z)JQ*L$<;`;7VP%>>D_O->d|`?T8$IwYVI`NGp6H~WjL9lbY0c?qcthai-4V*AgeX} zT447*C^rL7!xg5}*RxV?fHWT95DKx`MmPpJWVvfs^O9>w4Mu^yOIm z4$u~$3t`-kHcr$nY%Cq<yRyiE8(0+jALX?H zqTF(*H+civ@6gSq?=}WzY2)A;9-O%x5-aPU1oxZ2xF1pXd+PV$L%lt}7kky?H9T|; z@jqf;?=3t5tl{8?${}@i6UU|kmJ&=V!WG|ACRKgl_f*I>LG4x3Yd+5eKfW|3MMsiWpy6 zzoPi(_G>NsquZj}=;W#D)17;6qwYx{=Yo=hfj|y+kfV-8Ae0>O%Tc1Ty0U&Kxrbp2 zoHcxBxu^BVBpeLuw+ z`Y`9*J`SBn@Erd$ED+dta1`(281Xxf4{!q4ISy~&N&E#9_$P7w5%(7-AF`#bFf0DVSmw3!;EUVId_vrmae<5|b#zH1qrf z8u()O0gj+di#7b4+SF~7HmzWpvMlk#WJ95zJLvojZ9*ja z)~T~qLsW=>1-OII{|RguuTx+MZ{SU?Q7Xt1@Bw^}ryacgK9#@Ye}C+Mf9ikV#m{*^ bzei2t<6r zkZUx1Iy4ki=mxf6Fl_(JZ+Sc-am0f`=x5?<9os0WC>z*8h1gx;CmxSQ7+6oS@FonU zp&LJB9e0V}cOwR+VcSicLB0wHE(tm!a2K^l-uEa|>4XmVdOQ+oyiCgRND!{l*&NZL zO?(kBFk{>o6>m}v)&mrTTz*m^fiBFDWE=^#DZ@jU$@PU$BS9Sq2Uc0``+E=3l- zj9%sJ6YPT=343JIaw^>?Yb*q);(($;dJ4*<&6kifXmJj;ZVqNI=FE9}r@}f!$spB* s5H%c99Vo&ij}flE!nJ8&x}#>+<>xtyo20@TNn4S$C5hpPdL Date: Wed, 22 Mar 2023 00:18:59 +0400 Subject: [PATCH 2/6] refactored entity system and simulation --- src/Simulation/Entity.java | 16 ++ src/Simulation/Main.java | 8 +- src/Simulation/Simulation.java | 284 +++++++++++++++++++++------------ 3 files changed, 201 insertions(+), 107 deletions(-) create mode 100644 src/Simulation/Entity.java diff --git a/src/Simulation/Entity.java b/src/Simulation/Entity.java new file mode 100644 index 0000000..b1c6378 --- /dev/null +++ b/src/Simulation/Entity.java @@ -0,0 +1,16 @@ +package Simulation; + +public class Entity { + // survival rate when enemy met + public float survivalRate; + + // petition to notify danger when enemy met + public float dangerNotifyChance; + + // number of entities born on reproduction + public int reproductionCountMin; + public int reproductionCountMax; + + public int nutrientsNecessaryForReproduction; + public int currentNutrients; +} \ No newline at end of file diff --git a/src/Simulation/Main.java b/src/Simulation/Main.java index e5ea5b5..74324a5 100644 --- a/src/Simulation/Main.java +++ b/src/Simulation/Main.java @@ -2,9 +2,9 @@ public class Main { public static void main(String[] args) { - System.out.println("Hello world!"); - - final Simulation simulation = new Simulation(20, 20); - simulation.simulate(50); + final Simulation simulation = new Simulation(); + simulation.setData(20, 20, 20); + simulation.simulate(); + simulation.printData(); } } diff --git a/src/Simulation/Simulation.java b/src/Simulation/Simulation.java index ffae595..ceb083f 100644 --- a/src/Simulation/Simulation.java +++ b/src/Simulation/Simulation.java @@ -1,147 +1,225 @@ package Simulation; import java.util.ArrayList; +import java.util.Collections; +/* + * Evolutionary Biological Altruism Simulation + * created by Daeva + */ public class Simulation { - // Basic Biological Altruism simulation - // Initial distribution - private final int initialAltruistCount; - private final int initialCowardCount; + // world properties + private final float enemyMeetingChance = 0.7f; + private ArrayList entities; - // Current distribution - private int currentAltruistCount; - private int currentCowardCount; + // statistics + private int initialAltruistCount; + private int initialCowardCount; + private int[] altruistCountDailyData; + private int[] cowardCountDailyData; - // World properties - private final float enemyChance; + // day counters + private int days; + private int currentDay; + private int simulationEndDay; - private ArrayList entities; + // current milestones + // TODO: 3/22/2023 make entity variables change by next generation + // TODO: 3/22/2023 entities have something like perception, altruist should deduce if "opponent" is altruist or coward + // TODO: 3/22/2023 fully implement nutrients parameter for entities + + private void resetData () { + this.currentDay = 0; + this.entities = new ArrayList<>(); - // TODO: 21.03.23 keep data in arrays so we could plot it + // initialise data containers + this.altruistCountDailyData = new int[days + 1]; + this.cowardCountDailyData = new int[days + 1]; + } - public Simulation (int initialAltruistCount, int initialCowardCount) { + public void setData (int initialAltruistCount, int initialCowardCount, int days) { this.initialAltruistCount = initialAltruistCount; this.initialCowardCount = initialCowardCount; + this.days = days; - this.currentAltruistCount = initialAltruistCount; - this.currentCowardCount = initialCowardCount; - - // TODO: 06.03.23 add as arg - this.enemyChance = 0.65f; - - this.entities = new ArrayList<>(); + resetData(); } - public void simulate (int days) { - // Initialise entities + public void simulate () { + System.out.println("\nStarting simulation for " + days + " days\n"); + + // initialise entities for (int i = 0; i < initialAltruistCount; i++) { - this.entities.add(new Altruist()); + summonAltruist(); } for (int i = 0; i < initialCowardCount; i++) { - this.entities.add(new Coward()); + summonCoward(); } - // Simulate + // simulate for (int currentDay = 1; currentDay <= days; currentDay++) { - // If no entities left end the simulation - if (entities.size() == 0) { - System.out.println("\nSimulation ended on day " + currentDay); - return; - } + // update current date + this.currentDay = currentDay; + final int previousDay = currentDay - 1; + this.altruistCountDailyData[currentDay] = this.altruistCountDailyData[previousDay]; + this.cowardCountDailyData[currentDay] = this.cowardCountDailyData[previousDay]; + + // copy entities array to modify further final ArrayList entitiesCopy = new ArrayList<>(entities); - // TODO: 21.03.23 loop over entity couples - for ( Entity entity : entities) { - // Approach to food source - // TODO: 06.03.23 later - - // TODO: 21.03.23 random one from couple is altruist other has 1 survival rate - // TODO: 21.03.23 perception changes this 1, - // like if perception is 0.2 if opponent is not altruist there is a 0.2 that it will not shout out - - // Handle event - final float enemySpawnChance = (float) Math.random(); - if (enemyChance > enemySpawnChance) { - // Enemy spawned - final float survivalRate = (float) Math.random(); - if (entity.getSurvivalRateWhenEnemyMet() > survivalRate) { - // Survived - // TODO: 06.03.23 - } else { - // Died - entitiesCopy.remove(entity); - if (entity instanceof Coward) { - currentCowardCount--; - } else if (entity instanceof Altruist) { - currentAltruistCount--; - } + + // shuffle entities to make couples + Collections.shuffle(entitiesCopy); + + // loop over entities with couples + for (int i = 0; i < entitiesCopy.size() - 1; i += 2) { + // get a couple + final Entity firstEntity = entitiesCopy.get(i); + final Entity secondEntity = entitiesCopy.get(i + 1); + + // handle event + if (metDanger(enemyMeetingChance)) { + if (shouldNotify(firstEntity)) { + // second entity survived + + // check if first survives + handleDanger(firstEntity); + + // call it a day continue; } - } else { - // No enemy - // TODO: 06.03.23 - } - // Try getting food - - // Return - // Repopulate - final int entityReproductionCount = entity.getReproductionCount(); - for (int i = 0; i < entityReproductionCount; i++) { - if (entity instanceof Coward) { - entitiesCopy.add(new Coward()); - currentCowardCount++; - } else if (entity instanceof Altruist) { - entitiesCopy.add(new Altruist()); - currentAltruistCount++; - } + // first entity didn't notify + // TODO: 3/21/2023 figure out whether second entity should notify if first didn't + handleDanger(firstEntity); + handleDanger(secondEntity); + + // call it a day + continue; } + + // no danger met -> get food, return to repopulate + firstEntity.currentNutrients++; + secondEntity.currentNutrients++; + + // check reproduction + handleReproduction(firstEntity); + handleReproduction(secondEntity); } - entities = entitiesCopy; - System.out.println("Current day " + currentDay); - System.out.println("Current Altruists Count is " + currentAltruistCount); - System.out.println("current Cowards Count is " + currentCowardCount); - System.out.println(); + System.out.println("Day " + currentDay + " passed"); + + // if no entities left end the simulation + if (entities.size() == 0) { + System.out.println("\nSimulation ended on day " + currentDay + "\n"); + simulationEndDay = currentDay; + return; + } } + + simulationEndDay = days; + + System.out.println("\nSimulation ended\n"); } - // TODO: 21.03.23 if make variables change by next generation - // TODO: 21.03.23 like if random didn't shout out - // TODO: 21.03.23 perception like something, like altruist should deduce if "opponent" is altruist or coward - public class Altruist extends Entity { - public float getSurvivalRateWhenShout () { - return 0.1f; - } + // handling events + public void handleReproduction (Entity entity) { + final int reproductionCount = getReproductionCount(entity); - @Override - public float getSurvivalRateWhenEnemyMet() { - return 0.2f; - } + if (reproductionCount <= 0) return; + + final boolean isAltruist = isAltruist(entity); + + for (int i = 0; i < reproductionCount; i++) { + if (isAltruist) + summonAltruist(); + else summonCoward(); - @Override - public int getReproductionCount() { - return Utils.getRandomNumberInclusive(1, 2); } + entity.currentNutrients -= entity.nutrientsNecessaryForReproduction; } - public class Coward extends Entity { - @Override - public float getSurvivalRateWhenEnemyMet() { - return 0.2f; - } + public void handleDanger (Entity entity) { + if (survivedDanger(entity)) return; - @Override - public int getReproductionCount() { - return Utils.getRandomNumberInclusive(1, 2); - } + killEntity(entity); } - public abstract class Entity { - public abstract float getSurvivalRateWhenEnemyMet(); - // Number of entities born on reproduction - public abstract int getReproductionCount(); + // creating or destroying entities + public void summonAltruist () { + // create entity + final Entity entity = new Entity(); + entity.survivalRate = 0.1f; + entity.dangerNotifyChance = 1.0f; + entity.reproductionCountMin = 1; + entity.reproductionCountMax = 1; + + // update data + this.altruistCountDailyData[currentDay] = this.altruistCountDailyData[currentDay] + 1; + this.entities.add(entity); + } + + public void summonCoward () { + // create entity + final Entity entity = new Entity(); + entity.survivalRate = 0.2f; + entity.dangerNotifyChance = 0.0f; + entity.reproductionCountMin = 1; + entity.reproductionCountMax = 1; + + // update data + this.cowardCountDailyData[currentDay] = this.cowardCountDailyData[currentDay] + 1; + this.entities.add(entity); + } + + public void killEntity (Entity entity) { + // remove from entities + this.entities.remove(entity); + + // update data + if (isAltruist(entity)) + this.altruistCountDailyData[currentDay] = this.altruistCountDailyData[currentDay] - 1; + else this.cowardCountDailyData[currentDay] = this.cowardCountDailyData[currentDay] - 1; + } + + // checking events + public boolean shouldNotify (Entity entity) { + // TODO: 3/21/2023 somehow check if "opponent" is altruist or not and add perception parameter respectively + return eventHappened(entity.dangerNotifyChance); + } + + public boolean metDanger (float dangerChance) { + return eventHappened(dangerChance); + } + + public boolean survivedDanger (Entity entity) { + return eventHappened(entity.survivalRate); + } + + private boolean eventHappened (float chance) { + final float random = (float) Math.random(); + return random <= chance; + } + + // entity utils + public int getReproductionCount (Entity entity) { + if (entity.nutrientsNecessaryForReproduction > entity.currentNutrients) return 0; + return Utils.getRandomNumberInclusive(entity.reproductionCountMin, entity.reproductionCountMax); + } + + public boolean isAltruist (Entity entity) { + return entity.dangerNotifyChance == 1.0f; + } + + // simulation utils + public void printData () { + for (int currentDay = 0; currentDay <= simulationEndDay; currentDay++) { + System.out.println("Current day " + currentDay); + System.out.println("Current Altruists Count is " + this.altruistCountDailyData[currentDay]); + System.out.println("current Cowards Count is " + this.cowardCountDailyData[currentDay]); + System.out.println(); + } } } From 9c51482e8d9ac86d85cae6c0c26003de147218dd Mon Sep 17 00:00:00 2001 From: Daeva Date: Wed, 22 Mar 2023 00:19:22 +0400 Subject: [PATCH 3/6] added gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a3417b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/out/ From 2fcdba01d7c417efc5447a43458c9596a220c10f Mon Sep 17 00:00:00 2001 From: Daeva Date: Wed, 22 Mar 2023 00:20:38 +0400 Subject: [PATCH 4/6] classes --- .../JavaPlayground/Simulation/Main.class | Bin 686 -> 0 bytes .../Simulation/Simulation$Altruist.class | Bin 853 -> 0 bytes .../Simulation/Simulation$Coward.class | Bin 756 -> 0 bytes .../Simulation/Simulation$Entity.class | Bin 555 -> 0 bytes .../JavaPlayground/Simulation/Simulation.class | Bin 3031 -> 0 bytes .../JavaPlayground/Simulation/Utils.class | Bin 539 -> 0 bytes .../Simulation/Main.class | Bin 686 -> 0 bytes .../Simulation/Simulation$Altruist.class | Bin 853 -> 0 bytes .../Simulation/Simulation$Coward.class | Bin 756 -> 0 bytes .../Simulation/Simulation$Entity.class | Bin 555 -> 0 bytes .../Simulation/Simulation.class | Bin 3031 -> 0 bytes .../Simulation/Utils.class | Bin 539 -> 0 bytes 12 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 out/production/JavaPlayground/Simulation/Main.class delete mode 100644 out/production/JavaPlayground/Simulation/Simulation$Altruist.class delete mode 100644 out/production/JavaPlayground/Simulation/Simulation$Coward.class delete mode 100644 out/production/JavaPlayground/Simulation/Simulation$Entity.class delete mode 100644 out/production/JavaPlayground/Simulation/Simulation.class delete mode 100644 out/production/JavaPlayground/Simulation/Utils.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Main.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Altruist.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Coward.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation$Entity.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Simulation.class delete mode 100644 out/production/evolutionary-altruism-simulation/Simulation/Utils.class diff --git a/out/production/JavaPlayground/Simulation/Main.class b/out/production/JavaPlayground/Simulation/Main.class deleted file mode 100644 index 7e78fc6fe8ab6e3fcc91bcf775cfd7e3e304ecfb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 686 zcmZva-EPxB5QWbsPMjFGaT6zn{*llYoEEUeZ7Ob%P%EV^Qc$F-SDVyIxAG5i91xEM z7p(*m55Pkq&N`JsQG7ApnKSdv%-X;I{P+c+hgTK~D4H;Alu#CMZscd_hcce{=cAio zoC%bVRIIYM0!6PotfGRd3CqSK*bmYNU#D3RF)Nv|sM*g!D)B$0D$WL38px)oCRl)RIZ?odZIZERs%pfa7;1OkRf&BRlI+M?P&m5N=BcgYn~YJC+4XR~M& zq#xxdWTf6t#xfkrRB8V{Xk^!FDzMi7kJBS4%6TpCa@iWxWjbMLV~H$a-4DwJ1=jzi zFB-9jHArUZIC!u0fK|P~YkjHcV27VtKLzkEP^N9u^Z6Ehmk#bAzU6Xfgc5Ph3CwwoFf(ob3_1wxy&0(uV=p{Ny>LJv(T=WVhgi=1_3uOsEcFG5Hh z5Qqam0HuEkF&kUNio#_+cHX?1otfW%e*OZ`!u}EpC_1n_lwdRLbmcG!xR#-MJ~QjD z105wY)(o~D$hdyQu+f>tbI?{9E|wgWJuJgxxVI2hKT%rhG10w{O6p^Vt;T=&nwQqg z$>hd5?o4jVsN#-;nuisvGE{Ti@3ahJhRqK`pL5j@hiA#~N<_Zu1xYMNf}zy#{ie@g zwZlHSm5x**1zqr~fL>~yu*ZW-9!cY8kCyo_!|vkl{tc#;mhL9eNRD`L&b4?y5UM)} z6B=5v(L80?rrzcOCrS**Zv|miP3Ph|3j0aVjK3WwDov%H%iS=Edg4@?J}a|tKl{i> zoWVU4v3?WA+QDOnwOKs37zWQ*N<{5|$FZO%c=g2AA%FRjcM4$g;r99!ai| z_ln{L(#r>j-@pzIzr*=TZUO5gZ2|!iHb}0gFl^#3d6Y1vV}#hkc1HG;w8<#eZhaw@ zC(%<9Qfgc5PcIncA6RzLcb`bv@}RbE1>tFa)?@CDfG}lId78{-O5=bdmYp(5*L08 zLgIix9QXkU{t{v~wupu3W#7)udv9iEe*FIS9Y7EF7f^xY!wpb{N7xvuNfrsCV*O}- zZTI6hA{i4rbFR|%K4En*&z6Y2I%-((Q4g?);7YqgZIroWyT?i^b3j<{T;bO}bq@wV zf7Q`I)5nbfE!-qDOT}Lp6{Uo=SJIpaJ&q^G+2l+np&mt9s-}`q?Sx@BB)I)}%wc1o zw9HA*#aYBJtwB5z(Wyw3jf+RuewDEK|Hg`m^a!`P@GwiJYAT`=VdTqmsSmZBTt1VA z;B>l2geBXYe4WJOY-C5`gdS=I>%G!TQ50$gD|+6>MOV^|B%4D2g#X2Z2p;?a z{wQ(M3h|(qnVor$$J;lbU+*6P+Sr{(0YwLvhdJ1U?SUGlp)e}at^8R((MFjG!8Q*n zsUH!ly&U~TY`Z97-hu030Up7B6l2i}g}!fH4j*M;SmIb|WjcgnWB-OwYy6{>fmS!V zlZ0|lY1vOlLm6L-VaS`6UKEJ%M#L(cf0kBejuOf)UT;#gMQ-|>acei=)3TnQ= zdEu#mGFO{9z%zWV>oXRXvBDGcr)p#oR#5@CuQ4Z6uW~J51Dn%c!}gR-ysKfyqHjI! BfTsWe diff --git a/out/production/JavaPlayground/Simulation/Simulation.class b/out/production/JavaPlayground/Simulation/Simulation.class deleted file mode 100644 index 6c468551f28f3fe1367e1c6b3ba44bb4a463bdc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3031 zcmaJ@+jA4w8UGzw*2-c5#Wpy`#yGBVWVu9yBqT;$3IZ1s+er|$W1tDg(qgSG?<%`1 z6Xl+kCQWZiFKK~?W~QBvpLj?In-)5~JT`Cn2l|$ozV)#!li>W$t`x~Z$!KQJIp6ut zclmuceRTKMUjd|XErt+UG=z1uA|eo9kjpYvl-7LesksFs=Ltj(nwIGu7HCNfPq!h8 zHVrWyo1hD9%bH8&qV!DLO4YXlo$84xi${x|Q#M^MW0x(8665Oq79CsFK73^8;zh-Czm9I~5ZGi`#!@9ykXFv1 z{xJ=`0v*1SWzQ_8jyjI4Owhs@deEX??$XhZ2Lz&2O&<)GUQRT5kk;@Gfxf!e4FC+* zY>r_7yA`xU0y`2DO_|ff(@J?l$1svaS?2RpnFw??L?S(WR>L<1dYeia3{Z$+1iO{E zl#ac4SRm}0FVSRaAV?Q3>5bA8j^^7HQ*=0tl>aJ<0o_0*j%X*F>m(uOb zmr)%DkQV4#l8Z*hwsO*&F}(tJt|u)|L6sOEZm^thO=~_K!yz2ja74$qaI}X1M)?9- zNogxuUvj=GA^<6)uskl%U4_SwVa6^NnW@adDwJb7zKxR%q3Icp^lV39d!lNV|6;sK zPjA90JgH$q$0Vkhk@Yy&SZG&4x>LrB1co4X1d=5vL$)R zs&#@czq%{;pg_EW8fWf*~uAWrh;N?y}}<-S;00oWw_p?q2Qv__%Yk|T+fjuM!aC>-K`N^j^PJ* zOT*i$M1LqSSWhR@TDBLBR8UAk)sD#=%Yt@ZY3wsq#z5#vW?#{82PbTMv0O^uThtAd z4G+)I%O>pS8u)|Jl5Xr2RS_9kEM{4@=_r20mKm!f(QjCJBj0aZ{e-q(MDY`W&6!|C z)JQ*L$<;`;7VP%>>D_O->d|`?T8$IwYVI`NGp6H~WjL9lbY0c?qcthai-4V*AgeX} zT447*C^rL7!xg5}*RxV?fHWT95DKx`MmPpJWVvfs^O9>w4Mu^yOIm z4$u~$3t`-kHcr$nY%Cq<yRyiE8(0+jALX?H zqTF(*H+civ@6gSq?=}WzY2)A;9-O%x5-aPU1oxZ2xF1pXd+PV$L%lt}7kky?H9T|; z@jqf;?=3t5tl{8?${}@i6UU|kmJ&=V!WG|ACRKgl_f*I>LG4x3Yd+5eKfW|3MMsiWpy6 zzoPi(_G>NsquZj}=;W#D)17;6qwYx{=Yo=hfj|y+kfV-8Ae0>O%Tc1Ty0U&Kxrbp2 zoHcxBxu^BVBpeLuw+ z`Y`9*J`SBn@Erd$ED+dta1`(281Xxf4{!q4ISy~&N&E#9_$P7w5%(7-AF`#bFf0DVSmw3!;EUVId_vrmae<5|b#zH1qrf z8u()O0gj+di#7b4+SF~7HmzWpvMlk#WJ95zJLvojZ9*ja z)~T~qLsW=>1-OII{|RguuTx+MZ{SU?Q7Xt1@Bw^}ryacgK9#@Ye}C+Mf9ikV#m{*^ bzei2t<6r zkZUx1Iy4ki=mxf6Fl_(JZ+Sc-am0f`=x5?<9os0WC>z*8h1gx;CmxSQ7+6oS@FonU zp&LJB9e0V}cOwR+VcSicLB0wHE(tm!a2K^l-uEa|>4XmVdOQ+oyiCgRND!{l*&NZL zO?(kBFk{>o6>m}v)&mrTTz*m^fiBFDWE=^#DZ@jU$@PU$BS9Sq2Uc0``+E=3l- zj9%sJ6YPT=343JIaw^>?Yb*q);(($;dJ4*<&6kifXmJj;ZVqNI=FE9}r@}f!$spB* s5H%c99Vo&ij}flE!nJ8&x}#>+<>xtyo20@TNn4S$C5hpPdL)oCRl)RIZ?odZIZERs%pfa7;1OkRf&BRlI+M?P&m5N=BcgYn~YJC+4XR~M& zq#xxdWTf6t#xfkrRB8V{Xk^!FDzMi7kJBS4%6TpCa@iWxWjbMLV~H$a-4DwJ1=jzi zFB-9jHArUZIC!u0fK|P~YkjHcV27VtKLzkEP^N9u^Z6Ehmk#bAzU6Xfgc5Ph3CwwoFf(ob3_1wxy&0(uV=p{Ny>LJv(T=WVhgi=1_3uOsEcFG5Hh z5Qqam0HuEkF&kUNio#_+cHX?1otfW%e*OZ`!u}EpC_1n_lwdRLbmcG!xR#-MJ~QjD z105wY)(o~D$hdyQu+f>tbI?{9E|wgWJuJgxxVI2hKT%rhG10w{O6p^Vt;T=&nwQqg z$>hd5?o4jVsN#-;nuisvGE{Ti@3ahJhRqK`pL5j@hiA#~N<_Zu1xYMNf}zy#{ie@g zwZlHSm5x**1zqr~fL>~yu*ZW-9!cY8kCyo_!|vkl{tc#;mhL9eNRD`L&b4?y5UM)} z6B=5v(L80?rrzcOCrS**Zv|miP3Ph|3j0aVjK3WwDov%H%iS=Edg4@?J}a|tKl{i> zoWVU4v3?WA+QDOnwOKs37zWQ*N<{5|$FZO%c=g2AA%FRjcM4$g;r99!ai| z_ln{L(#r>j-@pzIzr*=TZUO5gZ2|!iHb}0gFl^#3d6Y1vV}#hkc1HG;w8<#eZhaw@ zC(%<9Qfgc5PcIncA6RzLcb`bv@}RbE1>tFa)?@CDfG}lId78{-O5=bdmYp(5*L08 zLgIix9QXkU{t{v~wupu3W#7)udv9iEe*FIS9Y7EF7f^xY!wpb{N7xvuNfrsCV*O}- zZTI6hA{i4rbFR|%K4En*&z6Y2I%-((Q4g?);7YqgZIroWyT?i^b3j<{T;bO}bq@wV zf7Q`I)5nbfE!-qDOT}Lp6{Uo=SJIpaJ&q^G+2l+np&mt9s-}`q?Sx@BB)I)}%wc1o zw9HA*#aYBJtwB5z(Wyw3jf+RuewDEK|Hg`m^a!`P@GwiJYAT`=VdTqmsSmZBTt1VA z;B>l2geBXYe4WJOY-C5`gdS=I>%G!TQ50$gD|+6>MOV^|B%4D2g#X2Z2p;?a z{wQ(M3h|(qnVor$$J;lbU+*6P+Sr{(0YwLvhdJ1U?SUGlp)e}at^8R((MFjG!8Q*n zsUH!ly&U~TY`Z97-hu030Up7B6l2i}g}!fH4j*M;SmIb|WjcgnWB-OwYy6{>fmS!V zlZ0|lY1vOlLm6L-VaS`6UKEJ%M#L(cf0kBejuOf)UT;#gMQ-|>acei=)3TnQ= zdEu#mGFO{9z%zWV>oXRXvBDGcr)p#oR#5@CuQ4Z6uW~J51Dn%c!}gR-ysKfyqHjI! BfTsWe diff --git a/out/production/evolutionary-altruism-simulation/Simulation/Simulation.class b/out/production/evolutionary-altruism-simulation/Simulation/Simulation.class deleted file mode 100644 index 6c468551f28f3fe1367e1c6b3ba44bb4a463bdc7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3031 zcmaJ@+jA4w8UGzw*2-c5#Wpy`#yGBVWVu9yBqT;$3IZ1s+er|$W1tDg(qgSG?<%`1 z6Xl+kCQWZiFKK~?W~QBvpLj?In-)5~JT`Cn2l|$ozV)#!li>W$t`x~Z$!KQJIp6ut zclmuceRTKMUjd|XErt+UG=z1uA|eo9kjpYvl-7LesksFs=Ltj(nwIGu7HCNfPq!h8 zHVrWyo1hD9%bH8&qV!DLO4YXlo$84xi${x|Q#M^MW0x(8665Oq79CsFK73^8;zh-Czm9I~5ZGi`#!@9ykXFv1 z{xJ=`0v*1SWzQ_8jyjI4Owhs@deEX??$XhZ2Lz&2O&<)GUQRT5kk;@Gfxf!e4FC+* zY>r_7yA`xU0y`2DO_|ff(@J?l$1svaS?2RpnFw??L?S(WR>L<1dYeia3{Z$+1iO{E zl#ac4SRm}0FVSRaAV?Q3>5bA8j^^7HQ*=0tl>aJ<0o_0*j%X*F>m(uOb zmr)%DkQV4#l8Z*hwsO*&F}(tJt|u)|L6sOEZm^thO=~_K!yz2ja74$qaI}X1M)?9- zNogxuUvj=GA^<6)uskl%U4_SwVa6^NnW@adDwJb7zKxR%q3Icp^lV39d!lNV|6;sK zPjA90JgH$q$0Vkhk@Yy&SZG&4x>LrB1co4X1d=5vL$)R zs&#@czq%{;pg_EW8fWf*~uAWrh;N?y}}<-S;00oWw_p?q2Qv__%Yk|T+fjuM!aC>-K`N^j^PJ* zOT*i$M1LqSSWhR@TDBLBR8UAk)sD#=%Yt@ZY3wsq#z5#vW?#{82PbTMv0O^uThtAd z4G+)I%O>pS8u)|Jl5Xr2RS_9kEM{4@=_r20mKm!f(QjCJBj0aZ{e-q(MDY`W&6!|C z)JQ*L$<;`;7VP%>>D_O->d|`?T8$IwYVI`NGp6H~WjL9lbY0c?qcthai-4V*AgeX} zT447*C^rL7!xg5}*RxV?fHWT95DKx`MmPpJWVvfs^O9>w4Mu^yOIm z4$u~$3t`-kHcr$nY%Cq<yRyiE8(0+jALX?H zqTF(*H+civ@6gSq?=}WzY2)A;9-O%x5-aPU1oxZ2xF1pXd+PV$L%lt}7kky?H9T|; z@jqf;?=3t5tl{8?${}@i6UU|kmJ&=V!WG|ACRKgl_f*I>LG4x3Yd+5eKfW|3MMsiWpy6 zzoPi(_G>NsquZj}=;W#D)17;6qwYx{=Yo=hfj|y+kfV-8Ae0>O%Tc1Ty0U&Kxrbp2 zoHcxBxu^BVBpeLuw+ z`Y`9*J`SBn@Erd$ED+dta1`(281Xxf4{!q4ISy~&N&E#9_$P7w5%(7-AF`#bFf0DVSmw3!;EUVId_vrmae<5|b#zH1qrf z8u()O0gj+di#7b4+SF~7HmzWpvMlk#WJ95zJLvojZ9*ja z)~T~qLsW=>1-OII{|RguuTx+MZ{SU?Q7Xt1@Bw^}ryacgK9#@Ye}C+Mf9ikV#m{*^ bzei2t<6r zkZUx1Iy4ki=mxf6Fl_(JZ+Sc-am0f`=x5?<9os0WC>z*8h1gx;CmxSQ7+6oS@FonU zp&LJB9e0V}cOwR+VcSicLB0wHE(tm!a2K^l-uEa|>4XmVdOQ+oyiCgRND!{l*&NZL zO?(kBFk{>o6>m}v)&mrTTz*m^fiBFDWE=^#DZ@jU$@PU$BS9Sq2Uc0``+E=3l- zj9%sJ6YPT=343JIaw^>?Yb*q);(($;dJ4*<&6kifXmJj;ZVqNI=FE9}r@}f!$spB* s5H%c99Vo&ij}flE!nJ8&x}#>+<>xtyo20@TNn4S$C5hpPdL Date: Wed, 22 Mar 2023 01:13:48 +0400 Subject: [PATCH 5/6] added draft threads --- src/Simulation/Simulation.java | 87 ++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 25 deletions(-) diff --git a/src/Simulation/Simulation.java b/src/Simulation/Simulation.java index ceb083f..6cbe1c3 100644 --- a/src/Simulation/Simulation.java +++ b/src/Simulation/Simulation.java @@ -73,40 +73,77 @@ public void simulate () { // shuffle entities to make couples Collections.shuffle(entitiesCopy); - // loop over entities with couples - for (int i = 0; i < entitiesCopy.size() - 1; i += 2) { - // get a couple - final Entity firstEntity = entitiesCopy.get(i); - final Entity secondEntity = entitiesCopy.get(i + 1); - - // handle event - if (metDanger(enemyMeetingChance)) { - if (shouldNotify(firstEntity)) { - // second entity survived + // create and start threads + final int numThreads = (int) Math.ceil(entitiesCopy.size() / 2.0f); + final Thread[] threads = new Thread[numThreads]; + final boolean enemyWithNotCoupleExists = entitiesCopy.size() % 2 != 0; - // check if first survives + // loop over entities with couples + for (int coupleIndex = 0; coupleIndex < numThreads - (enemyWithNotCoupleExists ? 1 : 0); coupleIndex++) { + final int firstEntityIndex = coupleIndex * 2; + final int secondEntityIndex = coupleIndex * 2 + 1; + + int finalCoupleIndex = coupleIndex; // TODO: 3/22/2023 remove this line + threads[coupleIndex] = new Thread(() -> { + System.out.println("thread " + finalCoupleIndex + " finished"); + // get a couple + final Entity firstEntity = entitiesCopy.get(firstEntityIndex); + final Entity secondEntity = entitiesCopy.get(secondEntityIndex); + + // handle event + if (metDanger(enemyMeetingChance)) { + if (shouldNotify(firstEntity)) { + // second entity survived + + // check if first survives + handleDanger(firstEntity); + + // call it a day + return; + } + + // first entity didn't notify + // TODO: 3/21/2023 figure out whether second entity should notify if first didn't handleDanger(firstEntity); + handleDanger(secondEntity); // call it a day - continue; + return; } - // first entity didn't notify - // TODO: 3/21/2023 figure out whether second entity should notify if first didn't - handleDanger(firstEntity); - handleDanger(secondEntity); + // no danger met -> get food, return to repopulate + firstEntity.currentNutrients++; + secondEntity.currentNutrients++; - // call it a day - continue; - } + // check reproduction + handleReproduction(firstEntity); + handleReproduction(secondEntity); + }); + threads[coupleIndex].start(); + } - // no danger met -> get food, return to repopulate - firstEntity.currentNutrients++; - secondEntity.currentNutrients++; + // case if there is an enemy with no couple + if (enemyWithNotCoupleExists) { + threads[numThreads - 1] = new Thread(() -> { + System.out.println("thread " + (numThreads - 1) + " finished"); + final Entity entity = entitiesCopy.get(entitiesCopy.size() - 1); - // check reproduction - handleReproduction(firstEntity); - handleReproduction(secondEntity); + if (metDanger(enemyMeetingChance)) { + handleDanger(entity); + } else { + handleReproduction(entity); + } + }); + threads[numThreads - 1].start(); + } + + // wait for threads to finish + for (Thread thread : threads) { + try { + thread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } System.out.println("Day " + currentDay + " passed"); From d47832acb3c4a46dd7d9ab2f581221633d753ba3 Mon Sep 17 00:00:00 2001 From: DaevaStep Date: Fri, 24 Mar 2023 11:10:01 +0400 Subject: [PATCH 6/6] latest thread impl changes --- src/Simulation/Main.java | 52 ++++++++++++++++++++++-- src/Simulation/Simulation.java | 72 +++++++++++++++++++++------------- src/Simulation/Utils.java | 15 ++++++- 3 files changed, 107 insertions(+), 32 deletions(-) diff --git a/src/Simulation/Main.java b/src/Simulation/Main.java index 74324a5..36aa4e8 100644 --- a/src/Simulation/Main.java +++ b/src/Simulation/Main.java @@ -1,10 +1,56 @@ package Simulation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicReferenceArray; + public class Main { - public static void main(String[] args) { + + + public static void main(String[] args) throws InterruptedException { final Simulation simulation = new Simulation(); - simulation.setData(20, 20, 20); - simulation.simulate(); + simulation.setData(20, 20, 10); + simulation.simulate(10); simulation.printData(); + + // fix seed +// final ThreadLocal random = ThreadLocal.withInitial(Random::new); +// random.get().setSeed(50); +// final ThreadLocalRandom random = ThreadLocalRandom.current(); +// random.setSeed(50); + +// final Random random = Utils.random; +// random.setSeed(500); +// final ArrayList objects = new ArrayList<>(); +// final ArrayList threads = new ArrayList<>(); +// +// for (int i = 0; i < 10; i++) { +// objects.add(i); +// } +// +// for (int i = 0; i < 10; i++) { +// final ArrayList clone = new ArrayList<>(objects); +// +// for (Object object : clone) { +// final Thread thread = new Thread(() -> { +// final float randomFloat = random.nextFloat(); +// if (randomFloat > 0.5f) { +// objects.remove(object); +// } +// }); +// threads.add(thread); +// thread.start(); +// } +// +// for (Thread thread : threads) { +// thread.join(); +// } +// +// Collections.sort(objects); +// System.out.println("objects = " + objects); +// } } } diff --git a/src/Simulation/Simulation.java b/src/Simulation/Simulation.java index 6cbe1c3..e403218 100644 --- a/src/Simulation/Simulation.java +++ b/src/Simulation/Simulation.java @@ -1,7 +1,14 @@ package Simulation; +import com.sun.source.tree.SynchronizedTree; +import jdk.jshell.execution.Util; + import java.util.ArrayList; import java.util.Collections; +import java.util.Comparator; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; /* * Evolutionary Biological Altruism Simulation @@ -46,6 +53,11 @@ public void setData (int initialAltruistCount, int initialCowardCount, int days) resetData(); } + public void simulate (long seed) { +// Utils.random.get().setSeed(seed); + simulate(); + } + public void simulate () { System.out.println("\nStarting simulation for " + days + " days\n"); @@ -59,6 +71,8 @@ public void simulate () { } // simulate + long startTime = System.currentTimeMillis(); + for (int currentDay = 1; currentDay <= days; currentDay++) { // update current date this.currentDay = currentDay; @@ -71,21 +85,21 @@ public void simulate () { final ArrayList entitiesCopy = new ArrayList<>(entities); // shuffle entities to make couples - Collections.shuffle(entitiesCopy); + Collections.shuffle(entitiesCopy, Utils.random.get()); // create and start threads - final int numThreads = (int) Math.ceil(entitiesCopy.size() / 2.0f); - final Thread[] threads = new Thread[numThreads]; - final boolean enemyWithNotCoupleExists = entitiesCopy.size() % 2 != 0; + final int couples = (int) Math.ceil(entitiesCopy.size() / 2.0f); + final int leftEnemyCount = entitiesCopy.size() % 2; + final ExecutorService executorService = Executors.newFixedThreadPool(couples + leftEnemyCount); + + System.out.println("couples " + (couples + leftEnemyCount)); // loop over entities with couples - for (int coupleIndex = 0; coupleIndex < numThreads - (enemyWithNotCoupleExists ? 1 : 0); coupleIndex++) { + for (int coupleIndex = 0; coupleIndex < couples - leftEnemyCount; coupleIndex++) { final int firstEntityIndex = coupleIndex * 2; final int secondEntityIndex = coupleIndex * 2 + 1; - int finalCoupleIndex = coupleIndex; // TODO: 3/22/2023 remove this line - threads[coupleIndex] = new Thread(() -> { - System.out.println("thread " + finalCoupleIndex + " finished"); + executorService.execute(() -> { // get a couple final Entity firstEntity = entitiesCopy.get(firstEntityIndex); final Entity secondEntity = entitiesCopy.get(secondEntityIndex); @@ -111,21 +125,20 @@ public void simulate () { return; } - // no danger met -> get food, return to repopulate + // no danger met -> get food firstEntity.currentNutrients++; secondEntity.currentNutrients++; - // check reproduction + // try to reproduce handleReproduction(firstEntity); handleReproduction(secondEntity); + System.out.print(" | "); }); - threads[coupleIndex].start(); } // case if there is an enemy with no couple - if (enemyWithNotCoupleExists) { - threads[numThreads - 1] = new Thread(() -> { - System.out.println("thread " + (numThreads - 1) + " finished"); + if (leftEnemyCount > 0) { + executorService.submit(() -> { final Entity entity = entitiesCopy.get(entitiesCopy.size() - 1); if (metDanger(enemyMeetingChance)) { @@ -133,32 +146,35 @@ public void simulate () { } else { handleReproduction(entity); } + System.out.print(" | "); }); - threads[numThreads - 1].start(); } - // wait for threads to finish - for (Thread thread : threads) { - try { - thread.join(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } + executorService.shutdown(); + +// this.entities.sort(Utils.entityComparator); + System.out.println(); System.out.println("Day " + currentDay + " passed"); // if no entities left end the simulation if (entities.size() == 0) { - System.out.println("\nSimulation ended on day " + currentDay + "\n"); - simulationEndDay = currentDay; + endSimulation(startTime, days); return; } } - simulationEndDay = days; + endSimulation(startTime, days); + } + + public void endSimulation (long startTime, int simulationEndDay) { + final long endTime = System.currentTimeMillis(); + this.simulationEndDay = simulationEndDay; - System.out.println("\nSimulation ended\n"); + System.out.println(); + System.out.println("Simulation ended on day " + currentDay ); + System.out.println("Elapsed time is " + (endTime - startTime) + " mills"); + System.out.println(); } // handling events @@ -236,7 +252,7 @@ public boolean survivedDanger (Entity entity) { } private boolean eventHappened (float chance) { - final float random = (float) Math.random(); + final float random = Utils.random.get().nextFloat(); return random <= chance; } diff --git a/src/Simulation/Utils.java b/src/Simulation/Utils.java index 2a2b590..299752e 100644 --- a/src/Simulation/Utils.java +++ b/src/Simulation/Utils.java @@ -1,11 +1,24 @@ package Simulation; +import java.util.Comparator; +import java.util.Random; + public class Utils { +// public static final Random random = new Random(); + public static final ThreadLocal random = ThreadLocal.withInitial(() -> new Random(50L)); + public static int getRandomNumber(int min, int max) { - return (int) ((Math.random() * (max - min)) + min); + return random.get().nextInt(max - min) + min; } public static int getRandomNumberInclusive(int min, int max) { return getRandomNumber(min, max + 1); } + + public static Comparator entityComparator = new Comparator() { + @Override + public int compare(Entity o1, Entity o2) { + return Float.compare(o1.dangerNotifyChance, o2.dangerNotifyChance); + } + }; }