private static void addRequestToDictionary(Dictionary <System.Drawing.Point, LocationRequests> locationsInvolved, Request request, System.Drawing.Point moveLoc) { //Add Current Location and Set it to occupied if (!locationsInvolved.ContainsKey(request.curLoc)) { LocationRequests locRequest = new LocationRequests(true); locationsInvolved.Add(request.curLoc, locRequest); } else { LocationRequests locRequest = locationsInvolved[request.curLoc]; locRequest.occupied = true; } //Add new location and add request to move there if (!locationsInvolved.ContainsKey(moveLoc)) { LocationRequests locRequest = new LocationRequests(false); locRequest.requestsToMove.Add(request); locationsInvolved.Add(moveLoc, locRequest); } else { if (locationsInvolved[moveLoc].completed == false)//Check if already moved to { LocationRequests locRequest = locationsInvolved[moveLoc]; locRequest.requestsToMove.Add(request); } else { LocationRequests locRequest = locationsInvolved[request.curLoc]; if (moveLoc == request.altLoc) { locRequest.completed = true;//Occupier cannot be moved from current location so abort all attempts to move here reverseRequest(locRequest, locationsInvolved); } else { addRequestToDictionary(locationsInvolved, request, request.altLoc);//Not sure if this will happen, better to be safe than sorry } } } }
//Reverse in the opposite direction private static void reverseRequest(LocationRequests locRequest, Dictionary <System.Drawing.Point, LocationRequests> locationsInvolved) { for (int i = locRequest.requestsToMove.Count - 1; i >= 0; i--) { Request request = locRequest.requestsToMove[i]; locRequest.requestsToMove.Remove(request); if (request.reversed == false) { addRequestToDictionary(locationsInvolved, request, request.altLoc); request.reversed = true; } else { if (locationsInvolved.ContainsKey(request.curLoc)) { LocationRequests newLocRequest = locationsInvolved[request.curLoc]; newLocRequest.completed = true;///Cannot be moved from current location so abort all attempts to move here reverseRequest(newLocRequest, locationsInvolved); } } } }
public static void handleAllRequests() { //Exit if there is only one request if (requests.Count == 0) { requests = new List <Request>(); return; } //Use simpler code for single request if (requests.Count <= 1) { if (levelHandler.currentLevelSurfaceArray[requests[0].newLoc.X, requests[0].newLoc.Y].isWalkable) { requests[0].callback(false); } else if (levelHandler.currentLevelSurfaceArray[requests[0].altLoc.X, requests[0].altLoc.Y].isWalkable) { requests[0].callback(true); } requests = new List <Request>(); return; //By not responding permission is assumed to be refused and current state is maintained } ////////////If it goes past here, your computer my seize up in revulsion. Its screwed. All of it. (Also I have forgotten how it works and didn't comment it enough...) //List of requests that have valid moves List <Request> toCallBack = new List <Request>(); //Dictionary containing all the requests to move and their relative location Dictionary <System.Drawing.Point, LocationRequests> locationsInvolved = new Dictionary <System.Drawing.Point, LocationRequests>(); //Add all the requests to the Location request dictionary foreach (Request request in requests) { addRequestToDictionary(locationsInvolved, request, request.newLoc); } int incomplete = locationsInvolved.Count; //Iterate through each request in the dictionary do { incomplete = 0; foreach (KeyValuePair <System.Drawing.Point, LocationRequests> dictionaryEntry in locationsInvolved) { LocationRequests curLocRequest = dictionaryEntry.Value; //There are multiple request to move to this location if (curLocRequest.requestsToMove.Count > 1) { int priority = curLocRequest.requestsToMove[0].priority; bool priorityDiff = false; for (int i = curLocRequest.requestsToMove.Count - 1; i >= 0; i--) { Request request = curLocRequest.requestsToMove[i]; if (request.reversed == true)//Override if it has been reversed. Includes hostile animals - though they will kill it if it moves there later { curLocRequest.requestsToMove.Remove(request); } if (priority != request.priority) { priorityDiff = true; priority = Math.Max(priority, request.priority); } } if (priorityDiff) { for (int i = curLocRequest.requestsToMove.Count - 1; i >= 0; i--) { Request request = curLocRequest.requestsToMove[i]; if (priority > request.priority) { request.die();//kills animal //Remove it from location curLocRequest.requestsToMove.Remove(request); if (locationsInvolved.ContainsKey(request.curLoc)) { LocationRequests locRequest = locationsInvolved[request.curLoc]; locRequest.occupied = false; } } } if (curLocRequest.requestsToMove.Count > 1) { //Turn the remaining animals around reverseRequest(curLocRequest, locationsInvolved); } else { if (curLocRequest.occupied == false && curLocRequest.requestsToMove.Count > 0) { toCallBack.Add(curLocRequest.requestsToMove[0]); curLocRequest.completed = true; } } } else { //If they have same priority, reject them all reverseRequest(curLocRequest, locationsInvolved); curLocRequest.completed = true;//Will not accept any other movement requests. Animals have escaped if predator alternate position } } //There is a single request to move to this location else if (curLocRequest.requestsToMove.Count == 1) { if (curLocRequest.occupied == false) { toCallBack.Add(curLocRequest.requestsToMove[0]); curLocRequest.occupied = true; curLocRequest.completed = true; System.Drawing.Point originalLoc = curLocRequest.requestsToMove[0].curLoc; LocationRequests originalRequest = locationsInvolved[originalLoc]; originalRequest.occupied = false; originalRequest.completed = true; } } else { if (curLocRequest.occupied == false) { curLocRequest.completed = true; //May cause issues but is neccesary } } if (curLocRequest.completed == false) { incomplete++; } } } while (incomplete > 0); //Clean slate for requests requests = new List <Request>(); }