diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 797acea..0000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Assignment 3/src/ChallengeDecision/Arbitrer.java b/Assignment 3/src/ChallengeDecision/Arbitrer.java new file mode 100644 index 0000000..91c265a --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/Arbitrer.java @@ -0,0 +1,84 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +/** + * + * @author robson + */ +public class Arbitrer { + + public static ChallengeResult challengeDecide( ChallengeEntitySet challenger, ChallengeEntitySet challengee ) { + ChallengeResult challengeResult = new ChallengeResult( false ); + int i = 0, j = 0, challengerSize, challengeeSize; + FightResult fr; + ChallengeEntity tempCE; + Boolean challengerTurn = true; + double challengerPower = 0; + List> resultingResources = new ArrayList<>(); + + challengerSize = challenger.getEntityAttackList().size(); + challengeeSize = challengee.getEntityDefenseList().size(); + + for ( ChallengeAttack ce : challenger.getEntityAttackList() ) + challengerPower += ce.getProperty().doubleValue(); + + if ( challengerSize > 0 ) { + tempCE = challenger.getEntityAttackList().get( i++ ); + + while ( i < challengerSize && j < challengeeSize ) { + if ( challengerTurn ) { //tempCE is the challenger + fr = tempCE.fight( challengee.entityDefenseList.get( j ) ); + challengerTurn = fr.getResult(); + tempCE = fr.getChallengeEntity(); + if ( challengerTurn ) + j++; + else i++; + } else { //tempCE is the challengee + fr = challenger.getEntityAttackList().get( i ).fight( tempCE ); + challengerTurn = fr.getResult(); + tempCE = fr.getChallengeEntity(); + if ( challengerTurn ) + j++; + else i++; + } + } + + // check what is remaining + + if ( i < challengerSize ) { // 1 - there are still reamaining challengers + double sum = 0; + double proportion; + + while ( i < challengerSize ) { + sum += challenger.getEntityAttackList().get( i++ ).getProperty().doubleValue(); + } + + proportion = sum / challengerPower; + + challengee.getEntityResourceList().forEach((ce) -> { + resultingResources.add( new ChallengeResource( ce.getProperty().doubleValue() * ( proportion * getLootChance() ) ) ); + }); + + challengeResult = new ChallengeResult( true, resultingResources ); + } else if ( j < challengerSize ) { // 2 - there are still reamaining challengees + // no resources got back from attack + challengeResult = new ChallengeResult( false ); + } + + } + + return challengeResult; + } + + private static double getLootChance() { + return ( ThreadLocalRandom.current().nextInt(1, 10 ) + 10 ) / 20.0; + } +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeAttack.java b/Assignment 3/src/ChallengeDecision/ChallengeAttack.java new file mode 100644 index 0000000..53c22c0 --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeAttack.java @@ -0,0 +1,104 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +import java.util.concurrent.ThreadLocalRandom; + +/** + * + * @author robson + * @param + */ +public class ChallengeAttack extends ChallengeEntity { + T attack; + V hit; + + public ChallengeAttack( T attack, V hit ) { + this.attack = attack; + this.hit = hit; + } + + public ChallengeAttack( T attack ) { + this.attack = attack; + } + + @Override + public T getProperty() { + return this.attack; + } + + @Override + public void setProperty( T attack ) { + this.attack = attack; + } + + @Override + public V getHitPoints() { + return hit; + } + + @Override + public void setHitPoints( V value ) { + hit = value; + } + + + @Override + public int compare( ChallengeEntity ce ) { + double result; + result = this.attack.doubleValue() - ce.getProperty().doubleValue(); + + if ( result == 0 ) + return 0; + else if ( result > 0 ) + return 1; + else return -1; + } + + @Override + public double checkDifference( ChallengeEntity ce ) { + return this.attack.doubleValue() - ce.getProperty().doubleValue(); + } + + public FightResult fight( ChallengeEntity ce ) { + Boolean fightOutcome = false; + ChallengeEntity re; + + double result; + result = ( attack.doubleValue() + hit.doubleValue() ) - ( ce.getProperty().doubleValue() + ce.getHitPoints().doubleValue() ); + + if ( result > 0 ) { + if ( result / ( attack.doubleValue() + hit.doubleValue() ) > 0.2 ) { // it won by a large difference + fightOutcome = ThreadLocalRandom.current().nextInt(1, 100) > 10; //attack success + if ( fightOutcome ) { //attack success -> attacker remains + re = new ChallengeAttack<>( attack.doubleValue() ); + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.75 ); + } else { //attack fail -> defense remains + re = new ChallengeDefense<>( ce.getProperty().doubleValue() ); + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.3 ); + } + } else { // it won by a small difference + fightOutcome = ThreadLocalRandom.current().nextInt(1, 100) > 50; //attack success + if ( fightOutcome ) { //attack success -> attacker remains + re = new ChallengeAttack<>( attack.doubleValue() ); + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.5 ); + } else { //attack fail -> defense remains + re = new ChallengeDefense<>( ce.getProperty().doubleValue() ); + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.5 ); + } + } + } else { // attack fail + re = new ChallengeDefense<>( ce.getProperty().doubleValue() ); + if ( ( result * -1 ) / ( ce.getProperty().doubleValue() + ce.getHitPoints().doubleValue() ) > 0.5 ) { // it defended by a large difference -> it keeps 80% of health + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.75 ); + } else { // it defended by a small difference -> it keeps 505 of health + re.setHitPoints( ce.getHitPoints().doubleValue() * 0.5 ); + } + } + + return new FightResult( fightOutcome, re ); + } +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeDefense.java b/Assignment 3/src/ChallengeDecision/ChallengeDefense.java new file mode 100644 index 0000000..bc02c6a --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeDefense.java @@ -0,0 +1,68 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +/** + * + * @author robson + * @param + */ +public class ChallengeDefense extends ChallengeEntity { + T defense; + V hit; + + public ChallengeDefense( T defense ) { + this.defense = defense; + } + + public ChallengeDefense( T defense, V hit ) { + this.defense = defense; + this.hit = hit; + } + + @Override + public T getProperty() { + return this.defense; + } + + @Override + public void setProperty( T defense ) { + this.defense = defense; + } + + @Override + public V getHitPoints() { + return hit; + } + + @Override + public void setHitPoints( V value ) { + hit = value; + } + + @Override + public int compare( ChallengeEntity ce ) { + double result; + result = this.defense.doubleValue() - ce.getProperty().doubleValue(); + + if ( result == 0 ) + return 0; + else if ( result > 0 ) + return 1; + else return -1; + } + + @Override + public double checkDifference( ChallengeEntity ce ) { + return this.defense.doubleValue() - ce.getProperty().doubleValue(); + } + + @Override + public FightResult fight(ChallengeEntity ce) { + return new FightResult( false, new ChallengeDefense( 0 ) ); + } + +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeEntity.java b/Assignment 3/src/ChallengeDecision/ChallengeEntity.java new file mode 100644 index 0000000..16d3b41 --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeEntity.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +/** + * + * @author robson + */ +public abstract class ChallengeEntity { + + public abstract T getProperty(); + + public abstract void setProperty( T property ); + + public abstract V getHitPoints(); + + public abstract void setHitPoints( V value ); + + public abstract int compare( ChallengeEntity ce ); + + public abstract FightResult fight( ChallengeEntity ce ); + + public abstract double checkDifference( ChallengeEntity ce ); +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeEntitySet.java b/Assignment 3/src/ChallengeDecision/ChallengeEntitySet.java new file mode 100644 index 0000000..9752248 --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeEntitySet.java @@ -0,0 +1,56 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author robson + */ +public class ChallengeEntitySet { + List> entityAttackList; + List> entityDefenseList; + List> entityResourceList; + + public ChallengeEntitySet( List> entityAttackList, List> entityDefenseList, List> entityResourceList ) { + this.entityAttackList = entityAttackList; + this.entityDefenseList = entityDefenseList; + this.entityResourceList = entityResourceList; + } + + public ChallengeEntitySet() { + entityAttackList = new ArrayList(); + entityDefenseList = new ArrayList(); + entityResourceList = new ArrayList(); + } + + public void setEntityAttackList( List> entityAttackList ) { + this.entityAttackList = entityAttackList; + + } + + public void setEntityDefenseList( List> entityDefenseList ) { + this.entityDefenseList = entityDefenseList; + } + + public void setEntityResourceList( List> entityResourceList ) { + this.entityResourceList = entityResourceList; + } + + public List> getEntityAttackList(){ + return this.entityAttackList; + } + + public List> getEntityDefenseList(){ + return this.entityDefenseList; + } + + public List> getEntityResourceList(){ + return this.entityResourceList; + } +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeResource.java b/Assignment 3/src/ChallengeDecision/ChallengeResource.java new file mode 100644 index 0000000..9556efc --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeResource.java @@ -0,0 +1,75 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +/** + * + * @author robson + * @param + */ +public class ChallengeResource extends ChallengeEntity { + T resource; + V hit; + + public ChallengeResource() { + } + + public ChallengeResource( T resource ) { + this.resource = resource; + } + + public ChallengeResource( T resource, V hit ) { + this.resource = resource; + this.hit = hit; + } + + @Override + public T getProperty() { + return this.resource; + } + + @Override + public void setProperty( T resource ) { + this.resource = resource; + } + + @Override + public V getHitPoints() { + return hit; + } + + @Override + public void setHitPoints( V value ) { + hit = value; + } + + + @Override + public int compare( ChallengeEntity ce ) { + double result; + result = this.resource.doubleValue() - ce.getProperty().doubleValue(); + + if ( result == 0 ) + return 0; + else if ( result > 0 ) + return 1; + else return -1; + } + + @Override + public double checkDifference( ChallengeEntity ce ) { + return this.resource.doubleValue() - ce.getProperty().doubleValue(); + } + + @Override + public FightResult fight(ChallengeEntity ce) { + return new FightResult( false, new ChallengeDefense( 0 ) ); + } + + public void print() { + System.out.println( "Resource: " + resource + " / Hit: " + hit ); + } +} diff --git a/Assignment 3/src/ChallengeDecision/ChallengeResult.java b/Assignment 3/src/ChallengeDecision/ChallengeResult.java new file mode 100644 index 0000000..1c7b7ff --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/ChallengeResult.java @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author robson + */ +public class ChallengeResult { + Boolean challengeWon; + List> loot; + + public ChallengeResult( Boolean won, List> loot ) { + challengeWon = won; + this.loot = loot; + } + + public ChallengeResult( Boolean won ) { + challengeWon = won; + loot = new ArrayList<>(); + } + + public Boolean getChallengeWon() { + return challengeWon; + } + + public List> getLoot() { + return loot; + } + + public void print() { + System.out.println( "Result: " + challengeWon ); + for ( ChallengeResource e : loot ) { + e.print(); + } + } +} diff --git a/Assignment 3/src/ChallengeDecision/FightResult.java b/Assignment 3/src/ChallengeDecision/FightResult.java new file mode 100644 index 0000000..0ea9187 --- /dev/null +++ b/Assignment 3/src/ChallengeDecision/FightResult.java @@ -0,0 +1,28 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package ChallengeDecision; + +/** + * + * @author robson + */ +class FightResult { + Boolean result; + ChallengeEntity ce; + + public FightResult( Boolean result, ChallengeEntity ce ) { + this.result = result; + this.ce = ce; + } + + public Boolean getResult() { + return this.result; + } + + public ChallengeEntity getChallengeEntity() { + return ce; + } +} diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/DefenseBuilding.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/DefenseBuilding.java index c6a8d84..08f60c8 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/DefenseBuilding.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/DefenseBuilding.java @@ -15,4 +15,8 @@ public abstract class DefenseBuilding extends Building { } + public int getDamage(){ + return damage; + } + } diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/Farm.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/Farm.java index 4eacb1c..4812852 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/Farm.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/Farm.java @@ -16,6 +16,11 @@ public class Farm extends ResourceBuilding { return hall -> {}; } + @Override + public String getResource() { + return "UNUSED"; + } + @Override public Stage getUpgradeStage() { return ResourceStages.goldStages[getLevel()+1]; diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/IronMine.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/IronMine.java index b949894..edf28ab 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/IronMine.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/IronMine.java @@ -13,6 +13,11 @@ public class IronMine extends ResourceBuilding { return hall -> hall.addIron(getHarvestRate()); } + @Override + public String getResource() { + return resource; + } + @Override public Stage getUpgradeStage() { return ResourceStages.ironStages[getLevel()+1]; diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/LumberMine.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/LumberMine.java index 514621b..a35e204 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/LumberMine.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/LumberMine.java @@ -13,6 +13,11 @@ public class LumberMine extends ResourceBuilding { return hall -> hall.addWood(getHarvestRate()); } + @Override + public String getResource() { + return resource; + } + @Override public Stage getUpgradeStage() { return ResourceStages.woodStages[getLevel()+1]; diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/ResourceBuilding.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/ResourceBuilding.java index 400446e..fb9918e 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/ResourceBuilding.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/ResourceBuilding.java @@ -37,4 +37,6 @@ public abstract class ResourceBuilding extends Building { return harvest_rate; } + public abstract String getResource(); + } diff --git a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/SaulGoodMine.java b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/SaulGoodMine.java index 2c3cbff..fcc1dbe 100644 --- a/Assignment 3/src/ca/cosc3p91/a2/gameobjects/SaulGoodMine.java +++ b/Assignment 3/src/ca/cosc3p91/a2/gameobjects/SaulGoodMine.java @@ -13,6 +13,11 @@ public class SaulGoodMine extends ResourceBuilding { return hall -> hall.addGold(getHarvestRate()); } + @Override + public String getResource() { + return resource; + } + @Override public Stage getUpgradeStage() { return ResourceStages.goldStages[getLevel()+1]; diff --git a/Assignment 3/src/ca/cosc3p91/a2/util/ChallengeAdapter.java b/Assignment 3/src/ca/cosc3p91/a2/util/ChallengeAdapter.java new file mode 100644 index 0000000..ea88c19 --- /dev/null +++ b/Assignment 3/src/ca/cosc3p91/a2/util/ChallengeAdapter.java @@ -0,0 +1,143 @@ +package ca.cosc3p91.a2.util; + +import ChallengeDecision.*; +import ca.cosc3p91.a2.game.Map; +import ca.cosc3p91.a2.gameobjects.*; + +import java.util.ArrayList; +import java.util.List; + +public class ChallengeAdapter { + + private static class MapChallengeConverter { + private final Map map; + public MapChallengeConverter(Map map){ + this.map = map; + } + + public List> getAttackers(){ + List> entityAttackList = new ArrayList<>(); + + map.inhabitants.stream() + .filter(i -> i instanceof Infantry) + .map(i -> (Infantry) i) + .forEach(i -> { + entityAttackList.add(new ChallengeAttack<>((double) i.getDamage(), (double) i.getHealth())); + }); + + return entityAttackList; + } + + public List> getDefenders(){ + List> entityDefenseList = new ArrayList<>(); + + map.contains.stream() + .filter(b -> b instanceof DefenseBuilding) + .map(b -> (DefenseBuilding) b) + .forEach(d -> { + entityDefenseList.add(new ChallengeDefense<>((double) d.getDamage(), (double) b.getHealth())); + }); + + return entityDefenseList; + } + + public List> getResources(String type){ + List> entityResourceList = new ArrayList<>(); + + CasaDeNarino th = map.getTownHall(); + + int resourceCount; + int thResourceCount = + type.equals(SaulGoodMine.resource) ? th.getCurrentGold() + : type.equals(IronMine.resource) + ? th.getCurrentIron() : th.getCurrentWood(); + + resourceCount = (int) map.contains.stream() + .filter(b -> b instanceof ResourceBuilding).map(b -> (ResourceBuilding) b) + .filter(r -> r.getResource().equals(type)) + .count(); + + map.contains.stream() + .filter(b -> b instanceof ResourceBuilding) + .map(b -> (ResourceBuilding) b) + .filter(r -> r.getResource().equals(type)) + .forEach((r) -> { + entityResourceList.add( + new ChallengeResource<>( + (double) thResourceCount / (double) resourceCount, + (double) r.getHealth()) + ); + }); + + return entityResourceList; + } + } + + private final Map map; + + public ChallengeAdapter(Map map){ + this.map = map; + } + + public void attack(Map enemy){ + MapChallengeConverter enemyMap = new MapChallengeConverter(enemy); + MapChallengeConverter ourMap = new MapChallengeConverter(this.map); + + List> ourAttackers = ourMap.getAttackers(); + // not needed + List> ourDefenders = ourMap.getDefenders(); + + ChallengeEntitySet ourSet = new ChallengeEntitySet<>(); + ourSet.setEntityAttackList(ourAttackers); + ourSet.setEntityDefenseList(ourDefenders); + + List> enemyDefenders = enemyMap.getDefenders(); + + List> enemyGold = enemyMap.getResources(SaulGoodMine.resource); + List> enemyIron = enemyMap.getResources(IronMine.resource); + List> enemyWood = enemyMap.getResources(LumberMine.resource); + + // split is required because challengeResource lacks any resource specifier + ChallengeEntitySet enemyGoldSet = new ChallengeEntitySet<>(); + ChallengeEntitySet enemyIronSet = new ChallengeEntitySet<>(); + ChallengeEntitySet enemyWoodSet = new ChallengeEntitySet<>(); + + enemyGoldSet.setEntityDefenseList(enemyDefenders); + enemyIronSet.setEntityDefenseList(enemyDefenders); + enemyWoodSet.setEntityDefenseList(enemyDefenders); + + enemyGoldSet.setEntityResourceList(enemyGold); + enemyIronSet.setEntityResourceList(enemyIron); + enemyWoodSet.setEntityResourceList(enemyWood); + + ChallengeResult goldResults = Arbitrer.challengeDecide(ourSet, enemyGoldSet); + ChallengeResult ironResults = Arbitrer.challengeDecide(ourSet, enemyIronSet); + ChallengeResult woodResults = Arbitrer.challengeDecide(ourSet, enemyWoodSet); + + // if any fail to attack we need to pretend like it was one big attack that failed + if (!goldResults.getChallengeWon() || !ironResults.getChallengeWon() || !woodResults.getChallengeWon()) + return; + + System.out.println("We won gold: "); + goldResults.print(); + System.out.println("We won iron: "); + ironResults.print(); + System.out.println("We won wood: "); + woodResults.print(); + + CasaDeNarino th = map.getTownHall(); + + goldResults.getLoot().forEach(r -> { + th.addGold((int)r.getProperty().doubleValue()); + }); + + ironResults.getLoot().forEach(r -> { + th.addIron((int)r.getProperty().doubleValue()); + }); + + woodResults.getLoot().forEach(r -> { + th.addWood((int)r.getProperty().doubleValue()); + }); + } + +}