Skip to content

Commit

Permalink
Ch 3 - Highlight corresponding node on left/right sides on hover
Browse files Browse the repository at this point in the history
This will allow you to see the node in the graph at the same time you see the node in the queue, stack, or priority queue
  • Loading branch information
regalhotpocket authored and redblobgames committed Jan 2, 2018
1 parent edcf3c4 commit 3984ad4
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 42 deletions.
2 changes: 1 addition & 1 deletion 3-Solving-Problems-By-Searching/aStarSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class GraphAgentAStarSearch extends GraphAgent {
) {
// Expands next node
this.expand(this.problem.frontier[0]);

this.problem.nextToExpand = this.problem.frontier[0];
// Highlights a node which will be expanded at next iteration
const nextIterationNodeKey = this.problem.frontier[0];
const nextIterationNode = this.problem.nodes[nextIterationNodeKey];
Expand Down
90 changes: 86 additions & 4 deletions 3-Solving-Problems-By-Searching/c_aStarSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,33 @@ AStarSearchRenderer.prototype.attachEventListeners = function() {
this.onClickStepForward.bind(this)
);
this.dom.reset.addEventListener("click", this.onClickReset.bind(this));

this.options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
astar.graphDrawAgent.highlight(nodeKey);
$("#" + nodeKey + "a").css('background-color', astar.options.nodes.highlighted.fill);
$("#" + nodeKey + "p").css('background-color', astar.options.nodes.highlighted.fill);
$("#" + nodeKey + "e").css('background-color', astar.options.nodes.highlighted.fill);
};
this.options.nodes.frontier.onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
astar.graphDrawAgent.unhighlight(nodeKey);
let node = astar.graphProblem.nodes[nodeKey];
var backgroundObject = AStarSearchRenderer.helpers.getNodeStyle(astar.graphProblem, astar.options, node);
var backgroundColor = backgroundObject.backgroundColor;
$("#" + nodeKey + "a").css('background-color', backgroundColor);
$("#" + nodeKey + "p").css('background-color', backgroundColor);
$("#" + nodeKey + "e").css('background-color', backgroundColor);
};

this.options.nodes.next.onMouseEnter = this.options.nodes.frontier.onMouseEnter;
this.options.nodes.next.onMouseLeave = this.options.nodes.frontier.onMouseLeave;

this.options.nodes.explored.onMouseEnter = this.options.nodes.frontier.onMouseEnter;
this.options.nodes.explored.onMouseLeave = this.options.nodes.frontier.onMouseLeave;

this.options.nodes.unexplored.onMouseEnter = this.options.nodes.frontier.onMouseEnter;
this.options.nodes.unexplored.onMouseLeave = this.options.nodes.frontier.onMouseLeave;
};
AStarSearchRenderer.prototype.onChangeStartNode = function() {
var el = this.dom.startNode;
Expand Down Expand Up @@ -154,6 +181,9 @@ AStarSearchRenderer.prototype.reset = function() {
this.state.maxIterationsCount = this.graphAgent.solve();
// We have to reset graphProblem because it is already solved in the line above
this.graphProblem.reset();
this.graphProblem.initialKey = this.state.initialKey;
this.graphProblem.nextToExpand = this.state.initialKey;
this.graphProblem.goalKey = this.state.goalKey;
};
/**
* Renders some state of graphProblem
Expand Down Expand Up @@ -205,6 +235,10 @@ AStarSearchRenderer.prototype.render = function() {

// -------------------
this.graphProblem.reset();
this.graphProblem.initialKey = this.state.initialKey;
this.graphProblem.nextToExpand = this.state.initialKey;
this.graphProblem.goalKey = this.state.goalKey;
this.graphProblem.nodes[this.state.initialKey].state = "next";
this.graphAgent.solve(this.state.iterationsCount);
// It renders the graph (Two.js)
this.graphDrawAgent.iterate();
Expand Down Expand Up @@ -257,7 +291,7 @@ AStarSearchRenderer.prototype.render = function() {
helpers.forEach(
helpers.exploredNodes(this.graphProblem),
function(node) {
exploredNodesInnerHtml += templates.renderNodeToString(
exploredNodesInnerHtml += templates.renderExploredNodeToString(
this.graphProblem,
this.options,
node
Expand All @@ -266,6 +300,28 @@ AStarSearchRenderer.prototype.render = function() {
this
);
this.dom.exploredNodesContainer.innerHTML = exploredNodesInnerHtml;

for (node in this.graphProblem.explored){
let ele = document.getElementById(this.graphProblem.explored[node]+"e");
if (ele != null) {
ele.onmouseenter = this.options.nodes.frontier.onMouseEnter;
ele.onmouseleave = this.options.nodes.frontier.onMouseLeave;
}
}
for (node in this.graphProblem.frontier){
let ele = document.getElementById(this.graphProblem.frontier[node]+"p");
if (ele != null) {
ele.onmouseenter = this.options.nodes.frontier.onMouseEnter;
ele.onmouseleave = this.options.nodes.frontier.onMouseLeave;
}
}
for (key in this.graphProblem.nodes) {
let ele = document.getElementById(key+"a");
if (ele != null) {
ele.onmouseenter = this.options.nodes.frontier.onMouseEnter;
ele.onmouseleave = this.options.nodes.frontier.onMouseLeave;
}
}
};
AStarSearchRenderer.helpers = {
/**
Expand Down Expand Up @@ -348,8 +404,30 @@ AStarSearchRenderer.templates = {
'style="margin: 16px 16px 0 0; background-color:' +
backgroundColor +
' ;"' +
'class="graph-node pull-left">' +
'class="graph-node pull-left" nodeKey="' +
node.id +
'" id="' +
node.id +
'a">' +
node.id +
"</li>"
);
},
renderExploredNodeToString: function(graphProblem, options, node) {
var helpers = AStarSearchRenderer.helpers;
var backgroundObject = helpers.getNodeStyle(graphProblem, options, node);
var backgroundColor = backgroundObject["backgroundColor"];
return (
"<li " +
'style="margin: 16px 16px 0 0; background-color:' +
backgroundColor +
' ;"' +
'class="graph-node pull-left" nodeKey="' +
node.id +
'" id="' +
node.id +
'e">' +
node.id +
"</li>"
);
},
Expand All @@ -362,7 +440,11 @@ AStarSearchRenderer.templates = {
'<td><span style="background-color:' +
backgroundColor +
' ;" ' +
'class="graph-node">' +
'class="graph-node" id="' +
node.id +
'p" nodeKey="' +
node.id +
'">' +
node.id +
"</span></td>" +
"<td><span>" +
Expand All @@ -382,4 +464,4 @@ AStarSearchRenderer.templates = {
}
};

new AStarSearchRenderer();
var astar = new AStarSearchRenderer();
23 changes: 22 additions & 1 deletion 3-Solving-Problems-By-Searching/c_breadthFirstSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,30 @@ $(document).ready(function() {
var graphDrawAgent = new GraphDrawAgent(graphProblem, 'breadthFirstSearchCanvas', options, h, w);
var queueDrawAgent = new QueueDrawAgent('fifoQueueCanvas', h, w, graphProblem, options);

//Functions to detect when you hover over a node
options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.highlight(nodeKey);
queueDrawAgent.highlight(nodeKey);
};
options.nodes.frontier.onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.unhighlight(nodeKey);
queueDrawAgent.unhighlight(nodeKey);

};

options.nodes.next.onMouseEnter = options.nodes.frontier.onMouseEnter;
options.nodes.next.onMouseLeave = options.nodes.frontier.onMouseLeave;

let nextNode = breadthFirstSearch(graphProblem);
graphProblem.nodes[nextNode].state = "next";

while (n--) {
if (graphProblem.frontier.length > 0) {
var nextNode = breadthFirstSearch(graphProblem);
graphAgent.expand(nextNode);
nextNode = breadthFirstSearch(graphProblem);
graphProblem.nodes[nextNode].state = "next";
//If frontier is still present, find the next node to be expanded so it
//could be colored differently
if (graphProblem.frontier.length > 0) {
Expand All @@ -30,6 +50,7 @@ $(document).ready(function() {
break;
}
}

graphDrawAgent.iterate();
queueDrawAgent.iterate();
}
Expand Down
8 changes: 4 additions & 4 deletions 3-Solving-Problems-By-Searching/c_costDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@ $(document).ready(function() {
drawCostPath(bfsTwo, bfsShortestPath);
drawCostPath(ucsTwo, ucsShortestPath);

bfsGraphDrawAgent.highlight(nodeKey);
ucsGraphDrawAgent.highlight(nodeKey);
//bfsGraphDrawAgent.highlight(nodeKey);
//ucsGraphDrawAgent.highlight(nodeKey);
};
var onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
bfsGraphDrawAgent.unhighlight(nodeKey);
ucsGraphDrawAgent.unhighlight(nodeKey);
//bfsGraphDrawAgent.unhighlight(nodeKey);
//ucsGraphDrawAgent.unhighlight(nodeKey);
//Clear everything when mouse leaves
bfsGraphDrawAgent.iterate();
ucsGraphDrawAgent.iterate();
Expand Down
22 changes: 21 additions & 1 deletion 3-Solving-Problems-By-Searching/c_depthFirstSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,30 @@ $(document).ready(function() {
var graphDrawAgent = new GraphDrawAgent(graphProblem, 'depthFirstSearchCanvas', options, h, w);
var queueDrawAgent = new QueueDrawAgent('lifoQueueCanvas', h, w, graphProblem, options);

//Functions to detect when you hover over a node
options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.highlight(nodeKey);
queueDrawAgent.highlight(nodeKey);
};
options.nodes.frontier.onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.unhighlight(nodeKey);
queueDrawAgent.unhighlight(nodeKey);

};

options.nodes.next.onMouseEnter = options.nodes.frontier.onMouseEnter;
options.nodes.next.onMouseLeave = options.nodes.frontier.onMouseLeave;

let nextNode = breadthFirstSearch(graphProblem);
graphProblem.nodes[nextNode].state = "next";

while (n--) {
if (graphProblem.frontier.length > 0) {
var nextNode = depthFirstSearch(graphProblem);
graphAgent.expand(nextNode);
nextNode = depthFirstSearch(graphProblem);
graphProblem.nodes[nextNode].state = "next";
//If frontier is still present, find the next node to be expanded so it
//could be colored differently
if (graphProblem.frontier.length > 0) {
Expand Down
31 changes: 17 additions & 14 deletions 3-Solving-Problems-By-Searching/c_nodeExpansion.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
$(document).ready(function() {
var w = 600,
h = 350;

var w = 600, h = 350;

function init() {
var graph = new DefaultGraph();
Expand All @@ -25,6 +23,7 @@ $(document).ready(function() {
options.nodes.frontier.clickHandler = clickHandler;
options.nodes.next.clickHandler = clickHandler;

//Functions to detect when you hover over a node
options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
frontierNodesAgent.highlight(nodeKey);
Expand All @@ -36,15 +35,16 @@ $(document).ready(function() {
graphDrawAgent.unhighlight(nodeKey);
};

graphDrawAgent.nodeGroups['A']._renderer.elem.onmouseenter = options.nodes.frontier.onMouseEnter;
graphDrawAgent.nodeGroups['A']._renderer.elem.onmouseleave = options.nodes.frontier.onMouseLeave;

graphDrawAgent.reset();
frontierNodesAgent.iterate();
};
$('#nodeRestartButton').click(init);
init();
});




$(document).ready(function() {
var w = 600,
h = 350;
Expand Down Expand Up @@ -84,7 +84,6 @@ $(document).ready(function() {
init();
});


//Function to draw the frontier nodes
function DrawFrontierAgent(selector, h, w, problem, options) {
this.canvas = document.getElementById(selector);
Expand All @@ -108,21 +107,25 @@ function DrawFrontierAgent(selector, h, w, problem, options) {
circle.fill = options.nodes.frontier.fill;
var group = this.two.makeGroup(circle, text);
this.two.update();
$(group._renderer.elem).attr('nodeKey', node.id);
group._renderer.elem.onmouseenter = options.nodes.frontier.onMouseEnter;
group._renderer.elem.onmouseleave = options.nodes.frontier.onMouseLeave;
this.nodeDict[node.text] = group;
}
this.two.update();
}

this.highlight = function(nodeKey) {
this.nodeDict[nodeKey]._collection[0].scale = 1.2;
this.nodeDict[nodeKey]._collection[0].fill = options.nodes.highlighted.fill;
this.two.update();
}

this.unhighlight = function(nodeKey) {
if (this.nodeDict[nodeKey]) {
this.nodeDict[nodeKey]._collection[0].scale = 1;
this.two.update();
}
let node = this.nodeDict[nodeKey];
if (node == this.problem.nextToExpand)
node._collection[0].fill = options.nodes.next.fill;
else
node._collection[0].fill = options.nodes.frontier.fill;

this.two.update();
}
this.iterate();
}
Loading

0 comments on commit 3984ad4

Please sign in to comment.