combine robson code

main
Brett 2023-03-24 14:45:43 -04:00
parent fdb6a98b13
commit 9d8a06386a
16 changed files with 654 additions and 10 deletions

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

View File

@ -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<Double,Double> challenger, ChallengeEntitySet<Double,Double> challengee ) {
ChallengeResult challengeResult = new ChallengeResult( false );
int i = 0, j = 0, challengerSize, challengeeSize;
FightResult fr;
ChallengeEntity tempCE;
Boolean challengerTurn = true;
double challengerPower = 0;
List<ChallengeResource<Double,Double>> 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;
}
}

View File

@ -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 <T>
*/
public class ChallengeAttack <T extends Number, V extends Number> extends ChallengeEntity<T,V> {
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<T,V> ce ) {
Boolean fightOutcome = false;
ChallengeEntity<Double,Double> 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 );
}
}

View File

@ -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 <T>
*/
public class ChallengeDefense <T extends Number, V extends Number> extends ChallengeEntity<T,V> {
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<T, V> ce) {
return new FightResult( false, new ChallengeDefense( 0 ) );
}
}

View File

@ -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<T extends Number, V extends Number> {
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<T,V> ce );
public abstract double checkDifference( ChallengeEntity ce );
}

View File

@ -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 <T extends Number, V extends Number> {
List<ChallengeAttack<T,V>> entityAttackList;
List<ChallengeDefense<T,V>> entityDefenseList;
List<ChallengeResource<T,V>> entityResourceList;
public ChallengeEntitySet( List<ChallengeAttack<T,V>> entityAttackList, List<ChallengeDefense<T,V>> entityDefenseList, List<ChallengeResource<T,V>> 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<ChallengeAttack<T,V>> entityAttackList ) {
this.entityAttackList = entityAttackList;
}
public void setEntityDefenseList( List<ChallengeDefense<T,V>> entityDefenseList ) {
this.entityDefenseList = entityDefenseList;
}
public void setEntityResourceList( List<ChallengeResource<T,V>> entityResourceList ) {
this.entityResourceList = entityResourceList;
}
public List<ChallengeAttack<T,V>> getEntityAttackList(){
return this.entityAttackList;
}
public List<ChallengeDefense<T,V>> getEntityDefenseList(){
return this.entityDefenseList;
}
public List<ChallengeResource<T,V>> getEntityResourceList(){
return this.entityResourceList;
}
}

View File

@ -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 <T>
*/
public class ChallengeResource <T extends Number, V extends Number> extends ChallengeEntity<T,V> {
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<T, V> ce) {
return new FightResult( false, new ChallengeDefense( 0 ) );
}
public void print() {
System.out.println( "Resource: " + resource + " / Hit: " + hit );
}
}

View File

@ -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<ChallengeResource<Double,Double>> loot;
public ChallengeResult( Boolean won, List<ChallengeResource<Double,Double>> loot ) {
challengeWon = won;
this.loot = loot;
}
public ChallengeResult( Boolean won ) {
challengeWon = won;
loot = new ArrayList<>();
}
public Boolean getChallengeWon() {
return challengeWon;
}
public List<ChallengeResource<Double,Double>> getLoot() {
return loot;
}
public void print() {
System.out.println( "Result: " + challengeWon );
for ( ChallengeResource e : loot ) {
e.print();
}
}
}

View File

@ -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<Double, Double> ce;
public FightResult( Boolean result, ChallengeEntity ce ) {
this.result = result;
this.ce = ce;
}
public Boolean getResult() {
return this.result;
}
public ChallengeEntity<Double, Double> getChallengeEntity() {
return ce;
}
}

View File

@ -15,4 +15,8 @@ public abstract class DefenseBuilding extends Building {
} }
public int getDamage(){
return damage;
}
} }

View File

@ -16,6 +16,11 @@ public class Farm extends ResourceBuilding {
return hall -> {}; return hall -> {};
} }
@Override
public String getResource() {
return "UNUSED";
}
@Override @Override
public Stage getUpgradeStage() { public Stage getUpgradeStage() {
return ResourceStages.goldStages[getLevel()+1]; return ResourceStages.goldStages[getLevel()+1];

View File

@ -13,6 +13,11 @@ public class IronMine extends ResourceBuilding {
return hall -> hall.addIron(getHarvestRate()); return hall -> hall.addIron(getHarvestRate());
} }
@Override
public String getResource() {
return resource;
}
@Override @Override
public Stage getUpgradeStage() { public Stage getUpgradeStage() {
return ResourceStages.ironStages[getLevel()+1]; return ResourceStages.ironStages[getLevel()+1];

View File

@ -13,6 +13,11 @@ public class LumberMine extends ResourceBuilding {
return hall -> hall.addWood(getHarvestRate()); return hall -> hall.addWood(getHarvestRate());
} }
@Override
public String getResource() {
return resource;
}
@Override @Override
public Stage getUpgradeStage() { public Stage getUpgradeStage() {
return ResourceStages.woodStages[getLevel()+1]; return ResourceStages.woodStages[getLevel()+1];

View File

@ -37,4 +37,6 @@ public abstract class ResourceBuilding extends Building {
return harvest_rate; return harvest_rate;
} }
public abstract String getResource();
} }

View File

@ -13,6 +13,11 @@ public class SaulGoodMine extends ResourceBuilding {
return hall -> hall.addGold(getHarvestRate()); return hall -> hall.addGold(getHarvestRate());
} }
@Override
public String getResource() {
return resource;
}
@Override @Override
public Stage getUpgradeStage() { public Stage getUpgradeStage() {
return ResourceStages.goldStages[getLevel()+1]; return ResourceStages.goldStages[getLevel()+1];

View File

@ -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<ChallengeAttack<Double,Double>> getAttackers(){
List<ChallengeAttack<Double,Double>> 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<ChallengeDefense<Double,Double>> getDefenders(){
List<ChallengeDefense<Double,Double>> 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<ChallengeResource<Double,Double>> getResources(String type){
List<ChallengeResource<Double,Double>> 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<ChallengeAttack<Double,Double>> ourAttackers = ourMap.getAttackers();
// not needed
List<ChallengeDefense<Double, Double>> ourDefenders = ourMap.getDefenders();
ChallengeEntitySet<Double,Double> ourSet = new ChallengeEntitySet<>();
ourSet.setEntityAttackList(ourAttackers);
ourSet.setEntityDefenseList(ourDefenders);
List<ChallengeDefense<Double,Double>> enemyDefenders = enemyMap.getDefenders();
List<ChallengeResource<Double,Double>> enemyGold = enemyMap.getResources(SaulGoodMine.resource);
List<ChallengeResource<Double,Double>> enemyIron = enemyMap.getResources(IronMine.resource);
List<ChallengeResource<Double,Double>> enemyWood = enemyMap.getResources(LumberMine.resource);
// split is required because challengeResource lacks any resource specifier
ChallengeEntitySet<Double,Double> enemyGoldSet = new ChallengeEntitySet<>();
ChallengeEntitySet<Double,Double> enemyIronSet = new ChallengeEntitySet<>();
ChallengeEntitySet<Double,Double> 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());
});
}
}