Unit uNodeClass
The code of unit uNodeClass
unit uNodeClass; { Copyright (c) 2011 Christopher Winward Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License, as described at http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/ } {$mode objfpc}{$H+} interface uses Classes, SysUtils; type tNode = class(TObject) public x, y : double; Name : string; adjacentNodes : TList; //This holds pointers to all other tNodes this particular node can access. previousNode: tNode; constructor Create(xx, yy : double; nameX : string); function costToOtherNode(otherNode : tNode) : double; function costFromPrevNode : double; function heuristicCost(targetNode : tNode) : double; function pathCost : double; function totalCost(targetNode : tNode) : double; function pathNodeNames : string; procedure addLink(newNode : tNode); function updateNode : boolean; end; implementation uses uInput, uGlobalVariables; constructor tNode.Create(xx, yy : double; nameX : string); begin x := xx; y := yy; Name := nameX; adjacentNodes := tList.Create; previousNode := nil; end; function tNode.costToOtherNode(otherNode : tNode): double; begin exit(round(sqrt(((self.x - otherNode.x) * (self.x - otherNode.x)) + ((self.y - otherNode.y) * (self.y - otherNode.y))))); //Pythagoras theorem end; function tNode.costFromPrevNode(): double; begin exit(sqrt(((self.x - self.previousNode.x) * (self.x - self.previousNode.x)) + ((self.y - self.previousNode.y) * (self.y - self.previousNode.y)))); //Pythagoras theorem end; function tNode.heuristicCost(targetNode: tNode): double; begin exit(sqrt(((self.x - targetNode.x) * (self.x - targetNode.x)) + ((self.y - targetNode.y) * (self.y - targetNode.y)))); //Pythagoras, this time to target node. end; function tNode.pathCost(): double; var returnCost: double; tempNode: tNode; begin returnCost := 0; tempNode := self; //Pop backwards through previous nodes and add their costs to the pathcost. while tempNode.previousNode <> nil do begin returnCost += tempNode.costFromPrevNode; tempNode := tempNode.previousNode; end; exit(returnCost); end; function tNode.totalCost(targetNode: tNode): double; begin exit(self.pathCost + self.heuristicCost(targetNode)); end; function tNode.pathNodeNames : string; //Output the name of this node and all nodes before it. var tempNode : tNode; count : integer; outString, outString2 : string; begin tempNode := self; outString := ''; outString2 := ''; while (true) do begin outString += tempNode.Name; tempNode := tempNode.previousNode; if(tempNode = nil) then break; end; for count := length(outString) downto 0 do outString2 += outString[count]; exit(outString2); end; procedure tNode.addLink(newNode: tNode); begin self.adjacentNodes.add(newNode); end; function tNode.updateNode() : boolean; //Return true if it needs to be deleted. var count : integer; begin //Check if the mouse is currently inside this node. if (mouseX > self.x) then begin if (mouseX < self.x + 32) then begin if (mouseY > self.y) then begin if (mouseY < self.y + 32) then begin if (mouse1Down = True) then //Drag the node if mouse1 pressed. begin x := mouseX - 16; y := mouseY - 16; end; //Set the node to "selected" if right clicked for pathlinking. if (mouse2Down = True) then begin if (selectedNode1 = nil) then selectedNode1 := self else if (selectedNode1 <> self) then selectedNode2 := self; end; if ((deleteButton = True) and (name <> 'A') and (name <> 'F') ) then begin //Clear itself from all nodes to which it is linked. for count := 0 to (self.adjacentNodes.Count - 1) do begin //assuming it is actually there if (tNode(self.adjacentNodes[count]).adjacentNodes.IndexOf(self) <> -1) then tNode(self.adjacentNodes[count]).adjacentNodes.Remove(self); end; exit(true); //Exit the function straight away. end; end; end; end; end; exit(false); end; end.