Skip to content

Commit

Permalink
Merge pull request #2549 from Windchild292/dev_Windchild_WeightedMap
Browse files Browse the repository at this point in the history
Weighted Map: MekHQ-side Changes
  • Loading branch information
Windchild292 authored May 5, 2021
2 parents 0c50c97 + 75e9431 commit d476807
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 81 deletions.
54 changes: 26 additions & 28 deletions MekHQ/src/mekhq/campaign/mission/AtBContract.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,37 +21,24 @@
*/
package mekhq.campaign.mission;

import java.io.PrintWriter;
import java.io.Serializable;
import java.text.ParseException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Objects;
import java.util.UUID;

import megamek.client.ui.swing.util.PlayerColour;
import megamek.common.icons.Camouflage;
import mekhq.campaign.againstTheBot.enums.AtBLanceRole;
import mekhq.campaign.finances.Money;
import mekhq.campaign.market.enums.UnitMarketType;
import mekhq.campaign.mission.enums.MissionStatus;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import megamek.client.generator.RandomSkillsGenerator;
import megamek.client.generator.RandomUnitGenerator;
import megamek.client.ui.swing.util.PlayerColour;
import megamek.common.Compute;
import megamek.common.Entity;
import megamek.common.MechFileParser;
import megamek.common.MechSummary;
import megamek.common.UnitType;
import megamek.common.icons.Camouflage;
import megamek.common.loaders.EntityLoadingException;
import megamek.common.util.WeightedMap;
import mekhq.MekHQ;
import mekhq.MekHqXmlUtil;
import mekhq.campaign.Campaign;
import mekhq.campaign.againstTheBot.enums.AtBLanceRole;
import mekhq.campaign.finances.Money;
import mekhq.campaign.market.enums.UnitMarketType;
import mekhq.campaign.mission.atb.AtBScenarioFactory;
import mekhq.campaign.mission.enums.MissionStatus;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.rating.IUnitRating;
Expand All @@ -62,6 +49,17 @@
import mekhq.campaign.universe.Faction;
import mekhq.campaign.universe.Factions;
import mekhq.campaign.universe.RandomFactionGenerator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.io.PrintWriter;
import java.io.Serializable;
import java.text.ParseException;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Objects;
import java.util.UUID;

/**
* Contract class for use with Against the Bot rules
Expand Down Expand Up @@ -167,7 +165,7 @@ public class AtBContract extends Contract implements Serializable {
protected int battleTypeMod;
/* Only applies to next week */
protected int nextWeekBattleTypeMod;

private StratconCampaignState stratconCampaignState;

protected AtBContract() {
Expand Down Expand Up @@ -554,18 +552,18 @@ else if (roll >= 13) {
}

/**
* Changes the enemy to a randomly selected faction that's an enemy of
* Changes the enemy to a randomly selected faction that's an enemy of
* the current employer
*/
private void updateEnemy(LocalDate today) {
String enemyCode = RandomFactionGenerator.getInstance().getEnemy(
Factions.getInstance().getFaction(employerCode), false, true);
setEnemyCode(enemyCode);

Faction enemyFaction = Factions.getInstance().getFaction(enemyCode);
setEnemyBotName(enemyFaction.getFullName(today.getYear()));
}

public int getRepairLocation(int dragoonRating) {
int retval = Unit.SITE_BAY;
if ((missionType == MT_GUERRILLAWARFARE) ||
Expand Down Expand Up @@ -1212,7 +1210,7 @@ protected void writeToXmlBegin(PrintWriter pw1, int indent) {
MekHqXmlUtil.saveFormattedDate(specialEventScenarioDate));
MekHqXmlUtil.writeSimpleXmlTag(pw1, indent + 1, "specialEventScenarioType", specialEventScenarioType);
}

if(stratconCampaignState != null) {
stratconCampaignState.Serialize(pw1);
}
Expand Down Expand Up @@ -1524,23 +1522,23 @@ public void useBonusPart() {
public int getBattleTypeMod() {
return battleTypeMod + nextWeekBattleTypeMod;
}

public StratconCampaignState getStratconCampaignState() {
return stratconCampaignState;
}

public void setStratconCampaignState(StratconCampaignState state) {
stratconCampaignState = state;
}

@Override
public void acceptContract(Campaign campaign) {
if (campaign.getCampaignOptions().getUseStratCon()) {
StratconContractInitializer.initializeCampaignState(this, campaign,
StratconContractInitializer.initializeCampaignState(this, campaign,
StratconContractDefinition.getContractDefinition(getMissionType()));
}
}

public AtBContract(Contract c, Campaign campaign) {
this(c.getName());

Expand Down
52 changes: 25 additions & 27 deletions MekHQ/src/mekhq/campaign/personnel/SpecialAbility.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,14 @@
*/
package mekhq.campaign.personnel;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;

import megamek.common.Mounted;
import megamek.common.annotations.Nullable;
import megamek.common.util.WeightedMap;
import mekhq.campaign.CampaignOptions;
import mekhq.campaign.personnel.enums.PersonnelRole;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import megamek.common.EquipmentType;
import megamek.common.Mounted;
import megamek.common.TechConstants;
import megamek.common.WeaponType;
import megamek.common.annotations.Nullable;
import megamek.common.options.IOption;
import megamek.common.options.PilotOptions;
import megamek.common.util.weightedMaps.WeightedIntMap;
import megamek.common.weapons.InfantryAttack;
import megamek.common.weapons.autocannons.ACWeapon;
import megamek.common.weapons.autocannons.LBXACWeapon;
Expand All @@ -60,6 +39,25 @@
import mekhq.MekHqXmlUtil;
import mekhq.Utilities;
import mekhq.Version;
import mekhq.campaign.CampaignOptions;
import mekhq.campaign.personnel.enums.PersonnelRole;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Vector;

/**
* This object will serve as a wrapper for a specific pilot special ability. In the actual
Expand Down Expand Up @@ -586,7 +584,7 @@ public static SpecialAbility getOption(String name) {
*/
public static @Nullable String chooseWeaponSpecialization(final Person person, final int techLevel,
final int year, final boolean clusterOnly) {
final WeightedMap<EquipmentType> weapons = new WeightedMap<>();
final WeightedIntMap<EquipmentType> weapons = new WeightedIntMap<>();
// First try to generate based on the person's unit
if ((person.getUnit() != null) && (person.getUnit().getEntity() != null)) {
for (final Mounted mounted : person.getUnit().getEntity().getEquipment()) {
Expand Down Expand Up @@ -618,7 +616,7 @@ public static SpecialAbility getOption(String name) {
private static void addValidWeaponryToMap(final EquipmentType equipmentType,
final Person person, final int techLevel,
final int year, final boolean clusterOnly,
final WeightedMap<EquipmentType> weapons) {
final WeightedIntMap<EquipmentType> weapons) {
// Ensure it is a weapon eligible for the SPA in question, and the tech level is IS for
// IS personnel and Clan for Clan personnel
if (!isWeaponEligibleForSPA(equipmentType, person.getPrimaryRole(), clusterOnly)
Expand Down Expand Up @@ -701,7 +699,7 @@ public String getAllPrereqDesc() {
toReturn += getDisplayName(prereq) + "<br>";
}
for (SkillPrereq skPr : prereqSkills) {
toReturn += skPr.toString() + "<br>";
toReturn += skPr + "<br>";
}
for (String pr : prereqMisc.keySet()) {
toReturn += pr + ": " + prereqMisc.get(pr) + "<br/>";
Expand Down
8 changes: 4 additions & 4 deletions MekHQ/src/mekhq/campaign/personnel/enums/Marriage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

import megamek.common.util.EncodeControl;
import megamek.common.util.StringUtil;
import megamek.common.util.WeightedMap;
import megamek.common.util.weightedMaps.WeightedIntMap;
import mekhq.MekHQ;
import mekhq.campaign.Campaign;
import mekhq.campaign.event.PersonChangedEvent;
Expand Down Expand Up @@ -82,7 +82,7 @@ public void marry(final Campaign campaign, final Person origin, final Person spo
Marriage surnameStyle = this;

if (surnameStyle == WEIGHTED) {
WeightedMap<Marriage> map = createWeightedSurnameMap(campaign);
WeightedIntMap<Marriage> map = createWeightedSurnameMap(campaign);
surnameStyle = map.randomItem();
}

Expand Down Expand Up @@ -213,8 +213,8 @@ public void marry(final Campaign campaign, final Person origin, final Person spo
}


private WeightedMap<Marriage> createWeightedSurnameMap(final Campaign campaign) {
final WeightedMap<Marriage> map = new WeightedMap<>();
private WeightedIntMap<Marriage> createWeightedSurnameMap(final Campaign campaign) {
final WeightedIntMap<Marriage> map = new WeightedIntMap<>();
final int[] weights = campaign.getCampaignOptions().getMarriageSurnameWeights();
final Marriage[] styles = Marriage.values();
for (int i = 0; i < (styles.length - 1); i++) {
Expand Down
48 changes: 26 additions & 22 deletions MekHQ/src/mekhq/campaign/universe/RandomFactionGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,25 @@
*/
package mekhq.campaign.universe;

import java.time.LocalDate;
import java.time.Month;
import java.util.*;
import java.util.stream.Collectors;

import megamek.common.util.WeightedMap;

import megamek.common.Compute;
import megamek.common.annotations.Nullable;
import megamek.common.event.Subscribe;
import megamek.common.util.weightedMaps.WeightedIntMap;
import mekhq.MekHQ;
import mekhq.Utilities;
import mekhq.campaign.Campaign;
import mekhq.campaign.event.OptionsChangedEvent;

import java.time.LocalDate;
import java.time.Month;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
* @author Neoancient
*
Expand Down Expand Up @@ -173,8 +177,8 @@ public Set<String> getCurrentFactions() {
*
* @return Map used to select employer
*/
protected WeightedMap<Faction> buildEmployerMap() {
WeightedMap<Faction> retVal = new WeightedMap<>();
protected WeightedIntMap<Faction> buildEmployerMap() {
WeightedIntMap<Faction> retVal = new WeightedIntMap<>();
for (Faction f : borderTracker.getFactionsInRegion()) {

if (f.isClan() || FactionHints.isEmptyFaction(f)) {
Expand Down Expand Up @@ -208,7 +212,7 @@ protected WeightedMap<Faction> buildEmployerMap() {
* @return A faction to use as the employer for a contract.
*/
public String getEmployer() {
WeightedMap<Faction> employers = buildEmployerMap();
WeightedIntMap<Faction> employers = buildEmployerMap();
Faction f = employers.randomItem();
if (null != f) {
return f.getShortName();
Expand Down Expand Up @@ -242,7 +246,7 @@ public String getEnemy(String employer, boolean useRebels) {
public String getEnemy(Faction employer, boolean useRebels) {
return getEnemy(employer, useRebels, false);
}

/**
* Selects an enemy faction for the given employer, weighted by length of shared border and
* diplomatic relations. Factions at war or designated as rivals are twice as likely (cumulative)
Expand All @@ -269,44 +273,44 @@ public String getEnemy(Faction employer, boolean useRebels, boolean useMercs) {
}
if (null != employer) {
employerName = employer.getShortName();
WeightedMap<Faction> enemyMap = buildEnemyMap(employer);
WeightedIntMap<Faction> enemyMap = buildEnemyMap(employer);

if (useMercs) {
appendMercsToEnemyMap(enemyMap);
}

enemy = enemyMap.randomItem();
}
if (null != enemy) {
return enemy.getShortName();
}

MekHQ.getLogger().error("Could not find enemy for " + employerName); //$NON-NLS-1$

// Fallback; there are always pirates.
return "PIR";
}

/**
* Appends MERC faction to the given enemy map, with approximately a 10% probability
*/
protected void appendMercsToEnemyMap(WeightedMap<Faction> enemyMap) {
protected void appendMercsToEnemyMap(WeightedIntMap<Faction> enemyMap) {
int mercWeight = 0;
for (int key : enemyMap.keySet()) {
mercWeight += key;
}
enemyMap.add((int) Math.max(1, (mercWeight / 10)), Factions.getInstance().getFaction("MERC"));

enemyMap.add(Math.max(1, (mercWeight / 10)), Factions.getInstance().getFaction("MERC"));
}

/**
* Builds a map of potential enemies keyed to cumulative weight
*
* @param employer The employer faction
* @return The weight map of potential enemies
*/
protected WeightedMap<Faction> buildEnemyMap(Faction employer) {
WeightedMap<Faction> enemyMap = new WeightedMap<>();
protected WeightedIntMap<Faction> buildEnemyMap(Faction employer) {
WeightedIntMap<Faction> enemyMap = new WeightedIntMap<>();
for (Faction enemy : borderTracker.getFactionsInRegion()) {
if (FactionHints.isEmptyFaction(enemy)
|| enemy.getShortName().equals("CLAN")) {
Expand Down

0 comments on commit d476807

Please sign in to comment.