private void GetPossibleMovesForUnit(Unit unit, Dictionary<Unit, List<UnitOrderMetaData>> allOrders) { List<UnitOrderMetaData> orders = allOrders[unit]; //The hold order! orders.Add(new UnitOrderMetaData(new HoldOrder(unit))); //All possible move orders foreach( Location location in unit.Location.AdjacentLocations ) { orders.Add(new UnitOrderMetaData(new MoveOrder(unit, location))); } //Support orders PopulateSupportOrders(unit, allOrders); //Convoy orders PopulateMoveByConvoyOrders(unit, allOrders); }
private void PopulateMoveByConvoyOrders(Unit unit, Dictionary<Unit, List<UnitOrderMetaData>> allOrders) { List<UnitOrderMetaData> orders = allOrders[unit]; if( unit.UnitType != UnitType.Army || !unit.Province.IsCoastal ) { return; } //We've found an army that is placed in a coastal territory! //Find all sea-provinces that have fleets in them Route route = new Route(unit.Province); Queue<Route> routesToSearch = new Queue<Route>(); foreach( Province province in unit.Location.AdjacentProvinces ) { routesToSearch.Enqueue(new Route(route, province)); } while( routesToSearch.Count > 0 ) { Route aRoute = (Route)routesToSearch.Dequeue(); if( aRoute.End.IsSea //It's a sea province && aRoute.End.Unit != null ) //There's a fleet there { foreach( Province adjacentProvince in aRoute.End.AdjacentProvinces ) { //Make sure that we do not end up in a never-ending loop. if( !aRoute.Provinces.Contains(adjacentProvince) ) { routesToSearch.Enqueue(new Route(aRoute, adjacentProvince)); } } } else if( aRoute.End.IsCoastal //A coastal territory && aRoute.Provinces.Count >= 3 ) //We've gone at least one step on water! { UnitOrderMetaData orderMeta = new UnitOrderMetaData( new MoveByConvoyOrder(unit, aRoute)); Route via = aRoute.Via; List<UnitOrderMetaData> conveyOrders = new List<UnitOrderMetaData>(); for( int index = 0; index < via.Provinces.Count; ++index ) { Unit convoyingUnit = via.Provinces[index].Unit; UnitOrderMetaData conveyMeta = new UnitOrderMetaData( new ConveyOrder(convoyingUnit, unit, aRoute.End)); //Schedule the convoy order for updates regarding it's dependent orders. conveyOrders.Add(conveyMeta); //Add the convoy order to the conveying unit. //This means that we do not have to look at fleet to add their //convoy orders, since they've been added for all convoyed armies! List<UnitOrderMetaData> convoyUnitOrders = allOrders[convoyingUnit]; convoyUnitOrders.Add(conveyMeta); orderMeta.RequiredOrders.Add(conveyMeta); } //Finalize the convey orders. foreach( UnitOrderMetaData conveyOrder in conveyOrders ) { conveyOrder.RequiredOrders.Add(orderMeta); conveyOrder.RequiredOrders.AddRange(conveyOrders); conveyOrder.RequiredOrders.Remove(conveyOrder); //Remove yourself from the list! } orders.Add(orderMeta); } } }
private void PopulateSupportOrders(Unit unit, Dictionary<Unit, List<UnitOrderMetaData>> allOrders) { List<UnitOrderMetaData> orders = allOrders[unit]; foreach( Location adjacentLocation in unit.Location.AdjacentLocations ) { //Support of a unit one step away Unit adjUnit = adjacentLocation.Province.Unit; if( adjUnit != null && adjUnit.Power == this.Power ) { //Support for the adjacent unit's Hold order { // Work out the value of the move. // Hold supports are only needed if double costOfSupport = 0; double orderValue = getLocationWeight(adjUnit.Location); foreach (Location loc in unit.Location.AdjacentLocations) { double tempValue = getLocationWeight(loc) - getLocationWeight(unit.Location); if (loc != adjUnit.Location && tempValue > costOfSupport) costOfSupport = tempValue; } if (getCompetition(adjUnit.Location) > 1) // We actually need todo this orderValue *= param.SUPPORT_BONUS; orderValue -= costOfSupport; orderValue = randomMoveValue(orderValue); UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportHoldOrder(unit, adjUnit), orderValue, unit.Location); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new HoldOrder(adjUnit), orderValue, adjUnit.Location)); orders.Add(orderMeta); } //Support for the adjacent unit's Move orders foreach( Location targetLocation in adjUnit.Location.AdjacentLocations ) { if( targetLocation.Province != unit.Province && unit.CanMoveTo(targetLocation.Province) ) { double costOfSupport = 0; double orderValue = getLocationWeight(targetLocation); foreach (Location loc in unit.Location.AdjacentLocations) { double tempValue = getLocationWeight(loc) - getLocationWeight(unit.Location); if (loc != targetLocation && tempValue > costOfSupport) costOfSupport = tempValue; } if (getCompetition(targetLocation) > 1) // We're meeting an equal force orderValue *= param.SUPPORT_BONUS; else if (getCompetition(targetLocation) == 1) // We can overwhelm them orderValue *= param.SUPPORT_BONUS * param.SUPPORT_BONUS; orderValue -= costOfSupport; orderValue = randomMoveValue(orderValue); /* End of support evaluation */ UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportMoveOrder(unit, adjUnit, targetLocation.Province), orderValue, targetLocation); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new MoveOrder(adjUnit, targetLocation))); orders.Add(orderMeta); } } } //Support of a unit two steps away foreach( Province farProvince in adjacentLocation.AdjacentProvinces ) { if( unit.Location.AdjacentProvinces.Contains(farProvince) //It is an adjacent province. || farProvince == unit.Province ) //It is this province { continue; } Unit farUnit = farProvince.Unit; if( farUnit != null //There is a unit there && farUnit.CanMoveTo(adjacentLocation.Province) ) { //Now, it might be possible for the farUnit to be able to move //to the adjacentProvince in more than one way! foreach( Location closeLocation in farUnit.Location.AdjacentLocations ) { if( closeLocation.Province == adjacentLocation.Province ) { UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportMoveOrder(unit, farUnit, adjacentLocation.Province)); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new MoveOrder(farUnit, closeLocation))); orders.Add(orderMeta); } } } } } }
private void PopulateSupportOrders(Unit unit, Dictionary<Unit, List<UnitOrderMetaData>> allOrders) { List<UnitOrderMetaData> orders = allOrders[unit]; foreach( Location adjacentLocation in unit.Location.AdjacentLocations ) { //Support of a unit one step away Unit adjUnit = adjacentLocation.Province.Unit; if( adjUnit != null && adjUnit.Power == this.Power ) { //Support for the adjacent unit's Hold order { UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportHoldOrder(unit, adjUnit)); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new HoldOrder(adjUnit))); orders.Add(orderMeta); } //Support for the adjacent unit's Move orders foreach( Location targetLocation in adjUnit.Location.AdjacentLocations ) { if( targetLocation.Province != unit.Province && unit.CanMoveTo(targetLocation.Province) ) { UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportMoveOrder(unit, adjUnit, targetLocation.Province)); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new MoveOrder(adjUnit, targetLocation))); orders.Add(orderMeta); } } } //Support of a unit two steps away foreach( Province farProvince in adjacentLocation.AdjacentProvinces ) { if( unit.Location.AdjacentProvinces.Contains(farProvince) //It is an adjacent province. || farProvince == unit.Province ) //It is this province { continue; } Unit farUnit = farProvince.Unit; if( farUnit != null //There is a unit there && farUnit.CanMoveTo(adjacentLocation.Province) ) { //Now, it might be possible for the farUnit to be able to move //to the adjacentProvince in more than one way! foreach( Location closeLocation in farUnit.Location.AdjacentLocations ) { if( closeLocation.Province == adjacentLocation.Province ) { UnitOrderMetaData orderMeta = new UnitOrderMetaData( new SupportMoveOrder(unit, farUnit, adjacentLocation.Province)); orderMeta.RequiredOrders.Add(new UnitOrderMetaData( new MoveOrder(farUnit, closeLocation))); orders.Add(orderMeta); } } } } } }