private void createProductionTable() { productionTable = new List <IDWithList>(); List <bUUDataObject> unitList = pairObjectLibrary.Where(x => !x.isBuilding).ToList(); foreach (bUUDataObject thisObject in pairObjectLibrary) { if (thisObject.isBuilding && thisObject.supplyProvided == 0)//don't include nexus { //find all units produced out of this List <int> unitIDs = new List <int>(); foreach (bUUDataObject thisUnit in unitList) { if (thisUnit.producedOutOf.Equals(thisObject.name) && thisUnit.mineralCost > 0) //dont include WG { unitIDs.Add(thisUnit.bUUDataID); } } if (unitIDs.Count() > 0) { IDWithList newEntry = new IDWithList(thisObject.bUUDataID, unitIDs); productionTable.Add(newEntry); } } } }
private List <IDWithList> convertBoolRepBack(List <IDWithList> boolRepresentation, List <int> thisBasketCount) { List <IDWithList> listToReturn = new List <IDWithList>(); for (int a = 0; a < boolRepresentation.Count(); a++) { int thisID = boolRepresentation[a].ID; List <int> thisSplit = new List <int>(); //first add default members thisSplit.Add(1); //(add two to first bucket if have the units) if (productionTable[a].IDList.Count() > thisBasketCount[a]) { thisSplit[0]++; } for (int i = 1; i < thisBasketCount[a]; i++) { thisSplit.Add(1); } //next add members as determined by bool int currentBasket = 0; for (int c = 0; c < boolRepresentation[a].IDList.Count(); c++) { if (boolRepresentation[a].IDList[c] == 1) { currentBasket++; } thisSplit[currentBasket]++; } IDWithList newEntry = new IDWithList(thisID, thisSplit); listToReturn.Add(newEntry); } return(listToReturn); }
private void createPrecedenceRelations() { //need a dataObject: [thisEventID] List[all units that have precedence on thisEventID, or building that is child] //pairList is sorted in technological order, precedenceRelations should be sorted in same manner precedenceRelations = new List <IDWithList>(); //go through eventList and make entry for each event foreach (bUUEvent thisEvent in eventList) { //make sure this event is a building if (pairObjectLibrary[thisEvent.bUUDataID].isBuilding) { List <int> newList = new List <int>(); IDWithList newEntry = new IDWithList(thisEvent.bUUEventID, newList); //add all children of this event List <PairsTable> children = pairList.Where(x => x.parentBUUEventID == thisEvent.bUUEventID).ToList(); foreach (PairsTable thisChild in children) { //add the child eventID if nonnegative number (negatives correspond to no child) if (thisChild.childBUUEventID >= 0) { newEntry.IDList.Add(thisChild.childBUUEventID); } } //only add to list if has precedence relations precedenceRelations.Add(newEntry); } } //now add precedence for each unit //go through pairObjectLibrary, and consider the tech reqs of each unit foreach (bUUDataObject thisObject in pairObjectLibrary) { if (!thisObject.isBuilding && thisObject.mineralCost > 0) //dont consider warpgate { int thisEventID = thisObject.bUUEventIDForPrimaryBuilding; foreach (string thisTechReq in thisObject.buildingReqList) { //find eventID of the tech req. add thisEventID to that row in precedenceRelations int techReqEventID = pairObjectLibrary.First(x => x.name.Equals(thisTechReq)).bUUEventIDForPrimaryBuilding; //techreqEventID may be for an earlier upgrade, in which case it wont exist in precendence relations if (precedenceRelations.Where(x => x.ID == techReqEventID).Any()) { precedenceRelations.First(x => x.ID == techReqEventID).IDList.Add(thisEventID); } } } } }
private List <IDWithList> convertSplitToBool(List <IDWithList> lastSplit) { //create rows of 1s and 0s based on when split was made //0= stay in this basket, 1= move to next basket //Example a split of (5,4,2) -> free choices (3,3,2) -> bools are (0,0,0,1,0,0,1,0), where some of the bools are forced into 1 option (like last 1) List <IDWithList> boolRepresentation = new List <IDWithList>(); //go through each production building split directions for (int j = 0; j < lastSplit.Count(); j++) { //create a new row int thisID = lastSplit[j].ID; List <int> thisBinaryRow = new List <int>(); //only add elements if there are multiple baskets in this row and numElements>numbaskets+1 if (lastSplit[j].IDList.Count() > 1 && productionTable[j].IDList.Count > lastSplit[j].IDList.Count() + 1) { for (int i = 0; i < lastSplit[j].IDList.Count(); i++) { //first basket has 2 defaults, all other baskets have 1 default if (i == 0) { int numberDecisionsToStay = lastSplit[j].IDList[i] - 2; for (int c = 0; c < numberDecisionsToStay; c++) { thisBinaryRow.Add(0); } } else { //if going to add zeroes for a basket, add a 1 for first element that swapped over int numberDecisionsToStay = lastSplit[j].IDList[i] - 1; if (numberDecisionsToStay > 0) { thisBinaryRow.Add(1); } for (int c = 1; c < numberDecisionsToStay; c++) //start at 1 because first element is added as a 1 { thisBinaryRow.Add(0); } } } } IDWithList newEntry = new IDWithList(thisID, thisBinaryRow); boolRepresentation.Add(newEntry); } return(boolRepresentation); }
private List <IDWithList> findEvenSplit(List <int> thisBasketCount) { //consider even split List <IDWithList> evenSplit = new List <IDWithList>(); for (int i = 0; i < thisBasketCount.Count(); i++) { //create new row in evenSplit int rowID = productionTable[i].ID; List <int> evenList = buildEventList(thisBasketCount[i], productionTable[i].IDList.Count()); IDWithList newEntry = new IDWithList(rowID, evenList); evenSplit.Add(newEntry); } return(evenSplit); }
private List <IDWithList> createBasketSplitTable(List <bool> basketSplitDirections) { List <IDWithList> basketSplitTable = new List <IDWithList>(); //foreach element in productionTable, consider its list //foreach element in its list, consider option to (add another production building) int totalElementsChecked = 0; int previousAddedElements = 0; foreach (IDWithList thisRow in productionTable) { List <int> splitForThisRow = new List <int>(); //split elements in this Row based on basketSplitDirections for (int i = 0; i < thisRow.IDList.Count() - 1; i++) { //check boolean at this spot if (basketSplitDirections[totalElementsChecked]) { //create a new basket splitForThisRow.Add(totalElementsChecked + 1 - previousAddedElements); previousAddedElements = totalElementsChecked + 1; } totalElementsChecked++; } //add final split element. add up all other splits and make last one reach max int sum = 0; foreach (int thisInt in splitForThisRow) { sum = sum + thisInt; } int amountLeft = thisRow.IDList.Count() - sum; splitForThisRow.Add(amountLeft); //update previous Added Elements previousAddedElements = totalElementsChecked; IDWithList newRow = new IDWithList(thisRow.ID, splitForThisRow); basketSplitTable.Add(newRow); //add row to listToREturn } return(basketSplitTable); }
private List <IDWithList> findNextSplit(List <int> thisBasketCount, List <IDWithList> lastSplit, bool firstTime) { if (firstTime) { //return max amount in first column List <IDWithList> firstSplit = new List <IDWithList>(); List <int> itemsToAddToFirstBuilding = new List <int>(); for (int i = 0; i < productionTable.Count(); i++) { int numItems = productionTable[i].IDList.Count() - thisBasketCount[i] + 1; List <int> splitForThisRow = new List <int>(); splitForThisRow.Add(numItems); //add 1 to every other basket for (int g = 1; g < thisBasketCount[i]; g++) { splitForThisRow.Add(1); } IDWithList newEntry = new IDWithList(productionTable[i].ID, splitForThisRow); firstSplit.Add(newEntry); } return(firstSplit); } //at least one unit must go into each basket //next unit after that is defaulted to first basket //each production building has (#units-#baskets-1) booleans //boolean is comprised of X digits, where X represents sum of all production building booleans //when checking a digit, find which Row it belongs to, compare rules against properties of this row //convert lastSplit into boolean representation List <IDWithList> boolRepresentation = convertSplitToBool(lastSplit); List <int> boolsPerRow = new List <int>(); for (int i = 0; i < productionTable.Count(); i++) { int numBools = productionTable[i].IDList.Count() - thisBasketCount[i] - 1; boolsPerRow.Add(numBools); } //work backwards through each element, find first 0 that can be made 1 //default all elements after to 0 bool nextSplitFound = false; for (int i = lastSplit.Count() - 1; i >= 0; i--) { for (int c = boolRepresentation[i].IDList.Count() - 1; c >= 0; c--) { if (checkCanChangeBasket(i, c, boolRepresentation, thisBasketCount)) { boolRepresentation = incrementSplitHere(i, c, boolRepresentation, thisBasketCount); nextSplitFound = true; break; } } if (nextSplitFound) { break; } } if (!nextSplitFound) //if this is final split, let parent function know { lastSplit[0].ID = -1; return(lastSplit); } //convert boolRepresentation back List <IDWithList> nextSplit = convertBoolRepBack(boolRepresentation, thisBasketCount); return(nextSplit); }
private void createUUEventsAndPairs(List <IDWithList> productionTable, List <IDWithList> basketSplitTable) { lastBasketEntries = new List <IDWithList>(); // Split each row in productionTable according to basketSplitTable for (int i = 0; i < productionTable.Count(); i++) { //make sure upgrades always added to predecesors basket if (pairObjectLibrary[productionTable[i].ID].name == "forge" && productionTable[i].IDList.Count() > 1 && basketSplitTable[i].IDList.Count() > 1) { productionTable[i].IDList = sortForgeList(productionTable[i].IDList, basketSplitTable[i].IDList); if (discardBuild) { return; } } else if (pairObjectLibrary[productionTable[i].ID].name == "cyberCore" && productionTable[i].IDList.Count() > 1) { //productionTable[i].IDList = sortCyberList(productionTable[i].IDList, basketSplitTable[i].IDList); } List <int> IDOfLastBasketEntry = new List <int>(); IDWithList thisItem = new IDWithList(productionTable[i].ID, IDOfLastBasketEntry); lastBasketEntries.Add(thisItem); int nextBasket = 0; int numBaskets = basketSplitTable[i].IDList.Count(); List <int> basketSpots = new List <int>(basketSplitTable[i].IDList); //need to keep a running total of last unit added to each bucket //go through every id in the row to fill baskets //go through list backwards to have higher tech units be added later bool noBasketsEmpty = false; for (int g = productionTable[i].IDList.Count() - 1; g >= 0; g--) { //add this unit to next available basket (reduce basketSpots) basketSpots[nextBasket]--; int parentBUUID = productionTable[i].IDList[g]; int parentEventID = pairObjectLibrary[parentBUUID].bUUEventIDForPrimaryBuilding; if (parentEventID == 0) { int pause = 0; } double endTime; if (noBasketsEmpty) { //find child int childEventID = lastBasketEntries[i].IDList[nextBasket]; //update event properties (endTime = startTime of child) endTime = eventList[childEventID].startTime; eventList[parentEventID].pairAsParentID = pairList.Count(); //add pair as parent (find child ID from IDOfLastBasketEntry) PairsTable newPair = new PairsTable(pairList.Count(), parentEventID, childEventID); pairList.Add(newPair); //update child pair to account for new pair eventList[childEventID].pairAsChildID = pairList.Count() - 1; } else { //first unit into basket (need to add spot in lastBasketEntries) endTime = 0; lastBasketEntries[i].IDList.Add(-1); //add -1 as placeholder } double duration = pairObjectLibrary[parentBUUID].duration; eventList[parentEventID].startTime = endTime - duration; eventList[parentEventID].endTime = endTime; //update last item in bucket lastBasketEntries[i].IDList[nextBasket] = parentEventID; //update nextBasket int currentBasket = nextBasket; nextBasket = findNextBasket(nextBasket, basketSpots, numBaskets); if (nextBasket <= currentBasket) { noBasketsEmpty = true; } } } }