Restricting movement to a specific section - simulation

I am currently trying to working with restricting the agents to on 1/4 of the whole Manhattan map. The idea is simple and as follows;
Let us say we have 10 agents, their names being v1, v2 ... v10. I want them to move only in a specific section. Currently the method in whcih the MapBasedMovement has been made is such that it moves in all the place, but I need it to move in only specified coordinates.
Thanks,
I tried picking a specific set of coordinates i.e. (0, 0) and (700, 700). Tried to find all the MapNode that are between them and then ask the DTNNode to select only the MapNode in these coordinates. But this does not give me the correct results.
Adding code below
public Path getPath() {
Path p = new Path(generateSpeed());
MapNode curNode = lastMapNode;
MapNode prevNode = lastMapNode;
MapNode nextNode = null;
List<MapNode> neighbors;
Coord nextCoord;
assert lastMapNode != null: "Tried to get a path before placement";
// start paths from current node
p.addWaypoint(curNode.getLocation());
int pathLength = rng.nextInt(maxPathLength-minPathLength) +
minPathLength;
for (int i=0; i<pathLength; i++)
{
// neighbors = curNode.getNeighbors();
neighbors = host.possibleNodes;
Vector<MapNode> n2 = new Vector<MapNode>(neighbors);
if (!this.backAllowed)
{
n2.remove(prevNode); // to prevent going back
}
if (okMapNodeTypes != null) { //remove neighbor nodes that aren't ok
for (int j=0; j < n2.size(); ){
if (!n2.get(j).isType(okMapNodeTypes)) {
n2.remove(j);
}
else {
j++;
}
}
}
if (n2.size() == 0) { // only option is to go back
nextNode = prevNode;
}
else
{
// choose a random node from remaining neighbors
//nextNode = n2.get(rng.nextInt(n2.size()));
nextNode = host.possibleNodes.get(rng.nextInt(host.possibleNodes.size()));
System.out.println(lastMapNode);
List<MapNode> nodePath = pathFinder.getShortestPath(lastMapNode, nextNode);
for (MapNode node : nodePath)
{ // create a Path from the shortest path
p.addWaypoint(node.getLocation());
}
lastMapNode = nextNode;
prevNode = curNode;
nextCoord = nextNode.getLocation();
curNode = nextNode;
return p;
}
prevNode = curNode;
nextCoord = nextNode.getLocation();
curNode = nextNode;
p.addWaypoint(nextCoord);
}
lastMapNode = curNode;
return p;
}
Here, the parts where the host.possibleNodes have been mentioned are a method that I have made which basically tries to get the coordinates of each node and bins to a specific region. I can add that method as well if needed.

Related

How to print only unique names here in photon network unity

I did this but it prints one name multiple times. How do I make sure it prints one name only one at a time:
foreach(Player player in PhotonNetwork.PlayerList)
{
if(race_entered)
{
for(int i = 0; i <= PhotonNetwork.PlayerList.Length; i++)
{
player_name[i].text = player.NickName;
}
}
}
You are currently iterating exponentially. For every player you again iterate all players and overwrite all UI texts with the current player.
What you want is iterating only once
if(race_entered)
{
// cache since property access might be expensive
var players = PhotonNetwork.PlayerList;
// Note btw for iterating collections you always want an index
// "< Length" instead of "<= Length"
for(int i = 0; i < players.Length; i++)
{
var player = players[i];
player_name[i].text = player.NickName;
}
}

Google/OR-Tools Get Duration And Distance

I'm trying to understand the solution call in the MVRP examples
I have two matrixes, duration and distance that have been returned via calls to google
My solution is based on distance but given that i have the data already returned i want to find the index associated with the duration.
unfortunately I'm not sure completely what is going on under the hood of the the Routing Calls so hoping for a simple fast answer for look up and what index to use
for simplicity sake I will show the google example rather than my code and highlight what im looking for:
public string PrintSolution()
{
// Inspect solution.
string ret = "";
long maxRouteDistance = 0;
for (int i = 0; i < _data.Drivers; ++i)
{
ret += $"Route for Vehicle {i}:";
ret += Environment.NewLine;
long routeDistance = 0;
var index = _routing.Start(i);
while (_routing.IsEnd(index) == false)
{
ret += $"{_manager.IndexToNode((int) index)} -> ";
var previousIndex = index;
index = _solution.Value(_routing.NextVar(index));
long legDistance = _routing.GetArcCostForVehicle(previousIndex, index, i);
//LOOKING FOR
//long legDuration = ??? what index am is using here to find in my duration matrix which is built the same as indexes as distance
ret += " leg distance: " + legDistance;
routeDistance += legDistance;
}
ret += $"{_manager.IndexToNode((int) index)}";
ret += Environment.NewLine;
ret += $"Distance of the route: {routeDistance}m";
ret += Environment.NewLine;
ret += Environment.NewLine;
maxRouteDistance = Math.Max(routeDistance, maxRouteDistance);
}
ret += $"Maximum distance of the routes: {maxRouteDistance}m";
ret += Environment.NewLine;
return ret;
}
#Mizux
disclaimer: This is a simplification but should help you to understand.
In OR-Tools Routing there is a primal "hidden" dimension without name but you can retrieve the cost using RoutingModel::GetArcCostForVehicle()
For any "regular" dimension you can get inspect the CumulVar at each node.
e.g. supposing you have created two dimensions using RoutingModel::AddDimension() whose name were "Distance" and "Duration".
note: CumulVar is an accumulator so if you want the "arc cost" you'll need something like this dim.CumulVar(next_index) - dim.CumulVar(index)
Then in you PrintFunction you can use:
public string PrintSolution()
{
...
RoutingDimension distanceDimension = routing.GetMutableDimension("Distance");
RoutingDimension durationDimension = routing.GetMutableDimension("Duration");
for (int i = 0; i < _manager.getNumberOfVehicles(); ++i)
{
while (_routing.IsEnd(index) == false)
{
...
IntVar distanceVar = distanceDimension.CumulVar(index);
IntVar durationVar = durationDimension.CumulVar(index);
long distance = _solution.Value(distanceVar);
long duration = _solution.Value(durationVar);
...
}
}
}

Linked List Parameterized constructor

I tried to do a Parameterized constructor for a linked list my program is about to implement a queue by using a liked list so i want to do a parameterized constructor like Queue(int value , int size) and it dose not run or doing a list
this is my code for this problem
Queue(int value,int _size)
{
for(int i = 0; i < _size; ++i)
{
Node* temp = new Node;
temp->data = value;
temp->next = nullptr;
if(head == nullptr)
{
head = tail = temp;
}
else
{
tail->next = temp;
tail = temp;
}
}
}
i expected that the result is to fill the lest by value times size like if i run this function Queue x(20,3) the linked list should be
20 20 20
Since that this is a constructor, The head and tail are not properly initialized to use them. I would suggest adding head = tail = nullptr just before the loop and see what happens.
Follow this code after your node creation. I hope this will work. And do use i++ instead of ++i, as the later will make the loop for size-1 times.
if(head == NULL)
head = temp;
else{
Node *x;
x= head;
while(x->next != NULL)
x = x->next;
x->next = temp;
}

Unity / Search closes Object from a List by tag

I have a Problem to find the closest Object in my List.
There are three types with the tags (Food, Stone and Wood).
I spawn them at the beginning , some for each type, if i found some Resources, they're not hidden anymore, and i add them to the List that a Worker goes to them and harvests them.
So Later in the Game, for expample
i found 3 Stone Resources, then worker should harvest the closest one first everytime....
but i don't know how to iterate throw a Loop only to search for the Tags and how to get the position of the closest one.
Here is some code of the Method that i wrote:
void FindNearestFoodRessource()
{
for (int i = 0; i < gameController.discoveredRessources.Count; i++)
{
//float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
GameObject nearestFoodRessource = GameObject.FindGameObjectWithTag("Food");
}
}
First thing first - don't use FindGameObject**** in frequently called methods, it is very expensive.
About your problem - just check tag and distance of all the resources:
float minDist = Vector3.Distance(gameController.discoveredRessources[0].transform.position, transform.position);
int minDistIndex = 0;
for (int i = 1; i < gameController.discoveredRessources.Count; i++)
{
if (gameController.discoveredRessources[i].gameObject.CompareTag("Food"))
{
float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
if (dist < minDist)
{
minDist = dist;
minDistIndex = i;
}
}
}
//Now you can move to gameController.discoveredRessources[minDistIndex]
Also you can store all the food/stones/wood in the separate lists when you find it
Using Linq Where and this usefull extension method MinBy
using System;
using System.Collections.Generic;
using System.Linq;
public static class Linqextensions
{
public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
}
}
(simply copy that code somwhere into your project) you could do it in "one" line
var closestItem = gameController.discoveredRessources
// this is a filter only selecting the ones with tag = "Food"
.Where(obj => obj.CompareTag("Food"))
// this returns you the item from the list with the lowest distance
.MinBy(obj => Vector3.Distance(obj.transform.position, transform.position));

Comparing consecutive elements in a queue

I have a queue of elements, sorted by date. I need to extract the first n elements, which have the same date and add them to a temporary ArrayList, from which I choose one of them and scrap the others. After that I need to continue doing the same thing for the next n elements of the queue with the same date (extract them to the temp list and so on) until I have no more items in the queue.
// some notes to help you understand the code
PriorityQueue<Results> r, size(4), elementsEqualByTime(1=2,3=4);
List<Comments> c, size(2);
ArrayList temp;
if (c.size() != r.size() && resultIter.hasNext()) {
//first iteration will compare element 0 to itself -> 100% true
ResultObject r2 = resultIter.next();
ResultObject r1 = r2;
while (resultIter.hasNext() && r1.getTime().equals(r2.getTime())) {
temp.add(r1);
//we add the matching elements before we continue
r1 = r2;
temp.add(r1);
if (resultIter.hasNext()) {
//after we add the 2 matching elements we continue
r2 = resultIter.next();
}
}
//use the items in temp
temp.clear();
}
Right now it works for the 1st set of elements, but on the 2nd iteration it adds no elements to the temp ArrayList. I'd appreciate help with this solution, but am also open to different suggestions.
boolean Check (List<Element> elements,Element element)
{
for(Element element1:elements)
if(element1.equals(element))
return true;
return false;
}
void Stuff()
{
// some notes to help you understand the code
PriorityQueue<Element> r = new PriorityQueue<Element>();
List<Element> c;
List<Element> temp = new ArrayList<Element>();
for(Element element:r)
{
if(!Check(temp, element))
{
// do stuff with temp
temp = new ArrayList<Element>();
}
temp.add(element);
}
}
while (commentIter.hasNext()) {
Comment c1 = null;
temp.add(arrayQueue[0]);
for (int i = 1; i < arrayQueue.length; i++) {
if (!arrayQueue[i].getTime().equals(arrayQueue[i - 1].getTime())) {
c1 = commentIter.next();
//do stuff with the results
temp = new HashSet<ResultObject>();
}
temp.add(arrayQueue[i]);
}
if (!temp.isEmpty()) {
c1 = commentIter.next();
//do stuff with the results
}
temp = new HashSet<ResultObject>();
}
That's a tested solution which works.