Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions 3-Solving-Problems-By-Searching/c_bi-directional.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ class BidirectionalDiagram {
this.final = this.problem.final;
this.textElement = textElement;

this.initialColor = 'hsl(0, 20%, 80%)';
this.initialColor = 'hsl(0, 2%, 76%)';
this.edgeColor = 'hsl(0, 2%, 80%)';
this.sourceBFSColor = 'hsl(209, 100%, 50%)';
this.sourceBFSColor = 'hsl(200,50%,70%)';
this.destBFSColor = 'hsl(209, 30%, 50%)';
this.sourceColor = 'hsl(209, 100%, 20%)';
this.destColor = 'hsl(209, 100%, 20%)';
Expand Down Expand Up @@ -80,7 +80,7 @@ class BidirectionalDiagram {
this.steps++;
//Update steps in the page
this.textElement.style('color', this.textColorScale(this.steps));
this.textElement.text(this.steps);
this.textElement.text(`${this.steps} nodes`);
}
}

Expand All @@ -99,6 +99,10 @@ class BidirectionalDiagram {
}
}, this.delay);
}

destroy() {
clearInterval(this.intervalFunction);
}
}

class BFSDiagram extends BidirectionalDiagram {
Expand All @@ -119,14 +123,24 @@ class BFSDiagram extends BidirectionalDiagram {
}

$(document).ready(function() {
let bidirectionalDiagram = new BidirectionalDiagram(d3.select('#bi-directional').select('#biCanvas'), 500, 550);
let bfsDiagram = new BFSDiagram(d3.select('#bi-directional').select('#bfsCanvas'), 500, 550)

function init() {
let bidirectionalDiagram = new BidirectionalDiagram(d3.select('#backtracking').select('#biCanvas'), 500, 550);
let bfsDiagram = new BFSDiagram(d3.select('#backtracking').select('#bfsCanvas'), 500, 550)
bidirectionalDiagram = new BidirectionalDiagram(d3.select('#bi-directional').select('#biCanvas'), 500, 550);
bfsDiagram = new BFSDiagram(d3.select('#bi-directional').select('#bfsCanvas'), 500, 550)
let graph = new Graph(500, 530, 1500);
let problem = new BidirectionalProblem(graph);
bidirectionalDiagram.init(problem, d3.select('#backtracking').select('#biStepCount'));
bfsDiagram.init(problem, d3.select('#backtracking').select('#bfsStepCount'));
bidirectionalDiagram.init(problem, d3.select('#bi-directional').select('#biStepCount'));
bfsDiagram.init(problem, d3.select('#bi-directional').select('#bfsStepCount'));
}

function restart() {
bidirectionalDiagram.destroy();
bfsDiagram.destroy();
init();
}

init();
$('#backtracking .restart-button').click(init);
$('#bi-directional .restart-button').click(restart);
});
31 changes: 16 additions & 15 deletions 3-Solving-Problems-By-Searching/c_costDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,8 @@ $(document).ready(function() {
var colorPathInGraph = function(graphDrawAgent, path) {
let nodeGroups = graphDrawAgent.nodeGroups;
for (var i = 0; i < path.path.length; i++) {
nodeKey = path.path[i].node;;
for (var j = 0; j < nodeGroups.length; j++) {
if ($(nodeGroups[j]._renderer.elem).attr('nodeKey') == nodeKey) {
nodeGroups[j]._collection[0].fill = 'hsl(108, 96%, 80%)';
break;
}
}
nodeKey = path.path[i].node;
nodeGroups[nodeKey]._collection[0].fill = 'hsl(108, 96%, 80%)';
}
let edges = graphDrawAgent.edges;
for (var i = 0; i < path.path.length - 1; i++) {
Expand All @@ -33,31 +28,30 @@ $(document).ready(function() {
}
}
graphDrawAgent.two.update();

}
//Function to draw the cost path in the bottom of the graph
var drawCostPath = function(two, path) {
two.clear();
path.path = path.path.reverse();
let runningCost = 0;
var i, x1, x2, y = 20;
var i, x1, x2, y = 23;
for (i = 0; i < path.path.length - 1; i++) {
x1 = i * 65 + 20;
x2 = (i + 1) * 65 + 20;
y = 20;
x1 = i * 65 + 30;
x2 = (i + 1) * 65 + 30;
y = 23;
line = two.makeLine(x1, y, x2, y);
line.stroke = 'hsla(202, 100%, 56%, 1)';
line.linewidth = 5;
edgeText = two.makeText(path.path[i + 1].cost, (x1 + x2) / 2, 10);
rect = two.makeRectangle(x1, y, 30, 30);
rect = two.makeCircle(x1, y, 20);
rect.fill = 'hsl(108, 96%, 80%)';
nodeText = two.makeText(path.path[i].node, x1, y);
nodeCost = two.makeText(runningCost, x1, y + 40);
nodeCost.size = 17;
runningCost += path.path[i + 1].cost;
}
x1 = i * 65 + 20;
rect = two.makeRectangle(x1, y, 40, 40);
x1 = i * 65 + 30;
rect = two.makeCircle(x1, y, 22);
rect.fill = 'hsl(108, 96%, 80%)';
nodeText = two.makeText(path.path[i].node, x1, y);
nodeText.size = 22;
Expand Down Expand Up @@ -95,8 +89,14 @@ $(document).ready(function() {
//Draw the cost path at the bottom
drawCostPath(bfsTwo, bfsShortestPath);
drawCostPath(ucsTwo, ucsShortestPath);

bfsGraphDrawAgent.highlight(nodeKey);
ucsGraphDrawAgent.highlight(nodeKey);
};
var onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
bfsGraphDrawAgent.unhighlight(nodeKey);
ucsGraphDrawAgent.unhighlight(nodeKey);
//Clear everything when mouse leaves
bfsGraphDrawAgent.iterate();
ucsGraphDrawAgent.iterate();
Expand All @@ -116,6 +116,7 @@ $(document).ready(function() {
options.nodes.next.onMouseLeave = onMouseLeave;
options.edges.showCost = true;
options.nodes.unexplored.clickHandler = function() {};
options.nodes.frontier.clickHandler = function() {};
bfsGraphDrawAgent = new GraphDrawAgent(graphProblem, 'no-costGraphCanvas', options, h, w);
ucsGraphDrawAgent = new GraphDrawAgent(graphProblem, 'costGraphCanvas', options, h, w);
};
Expand Down
62 changes: 52 additions & 10 deletions 3-Solving-Problems-By-Searching/c_nodeExpansion.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ $(document).ready(function() {
var graph = new DefaultGraph();
var graphProblem = new GraphProblem(graph.nodes, graph.edges, 'A', null);
var graphAgent = new GraphAgent(graphProblem);
var frontierNodesAgent = new DrawFrontierAgent('frontierCanvas', 150, 250, graphProblem);
var options = new DefaultOptions();
var frontierNodesAgent = new DrawFrontierAgent('frontierCanvas', 150, 250, graphProblem, options);

var graphDrawAgent = new GraphDrawAgent(graphProblem, 'nodeExpansionCanvas', options, h, w);

//Function to execute whenever a node is clicked
var clickHandler = function() {
//Find out which node has been clicked
Expand All @@ -17,10 +20,23 @@ $(document).ready(function() {
graphAgent.expand(nodeKey);
graphDrawAgent.iterate();
frontierNodesAgent.iterate();
graphDrawAgent.unhighlight(nodeKey);
};
options.nodes.frontier.clickHandler = clickHandler;
options.nodes.next.clickHandler = clickHandler
var graphDrawAgent = new GraphDrawAgent(graphProblem, 'nodeExpansionCanvas', options, h, w);
options.nodes.next.clickHandler = clickHandler;

options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
frontierNodesAgent.highlight(nodeKey);
graphDrawAgent.highlight(nodeKey);
};
options.nodes.frontier.onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
frontierNodesAgent.unhighlight(nodeKey);
graphDrawAgent.unhighlight(nodeKey);
};

graphDrawAgent.reset();
};
$('#nodeRestartButton').click(init);
init();
Expand All @@ -32,35 +48,45 @@ $(document).ready(function() {
$(document).ready(function() {
var w = 600,
h = 350;
var options = new DefaultOptions();

function init() {
var graph = new DefaultGraph();
var graphProblem = new GraphProblem(graph.nodes, graph.edges, String.fromCharCode(65 + Math.random() * 15), null);
var graphAgent = new GraphAgent(graphProblem);
var options = new DefaultOptions();
var graphDrawAgent = new GraphDrawAgent(graphProblem, 'agentViewCanvas', options, h, w);
//For this simulation, unexplored nodes and edges needs to be invisible
options.nodes.unexplored.opacity = 0;
options.edges.unvisited.opacity = 0;
var clickHandler = function() {
let nodeKey = $(this).attr('nodeKey');
graphAgent.expand(nodeKey);
graphDrawAgent.iterate();
graphDrawAgent.unhighlight(nodeKey);
};
options.nodes.frontier.clickHandler = clickHandler;
options.nodes.next.clickHandler = clickHandler;
options.nodes.frontier.onMouseEnter = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.highlight(nodeKey);
}
options.nodes.frontier.onMouseLeave = function() {
let nodeKey = $(this).attr('nodeKey');
graphDrawAgent.unhighlight(nodeKey);
}

var graphDrawAgent = new GraphDrawAgent(graphProblem, 'agentViewCanvas', options, h, w);
graphDrawAgent.reset();
};
$('#agentViewRestartButton').click(init);
$('#legendExpanded').css('background-color', 'hsl(0,50%,75%)');
$('#legendFrontier').css('background-color', 'hsl(200,50%,70%)');
$('#legendUnexplored').css('background-color', 'hsl(0, 2%, 76%)');
$('#legendExpanded').css('background-color', options.nodes.explored.fill);
$('#legendFrontier').css('background-color', options.nodes.frontier.fill);
$('#legendUnexplored').css('background-color', options.nodes.unexplored.fill);
init();
});


//Function to draw the frontier nodes
function DrawFrontierAgent(selector, h, w, problem) {
function DrawFrontierAgent(selector, h, w, problem, options) {
this.canvas = document.getElementById(selector);
this.canvas.innerHTML = '';
this.two = new Two({
Expand All @@ -71,16 +97,32 @@ function DrawFrontierAgent(selector, h, w, problem) {
this.nodeRadius = 15;
this.iterate = function() {
this.two.clear();
this.nodeDict = {};
frontierNodes = this.problem.frontier;
for (var i = 0; i < frontierNodes.length; i++) {
node = this.problem.nodes[frontierNodes[i]];
var x = (i % 4) * 50 + 40;
var y = (Math.floor(i / 4)) * 50 + 20;
var circle = this.two.makeCircle(x, y, this.nodeRadius);
var text = this.two.makeText(node.text, x, y);
circle.fill = 'hsl(200,50%,70%)';
circle.fill = options.nodes.frontier.fill;
var group = this.two.makeGroup(circle, text);
this.two.update();
this.nodeDict[node.text] = group;
}
this.two.update();
}

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

this.unhighlight = function(nodeKey) {
if (this.nodeDict[nodeKey]) {
this.nodeDict[nodeKey]._collection[0].scale = 1;
this.two.update();
}
}
this.iterate();
}
60 changes: 15 additions & 45 deletions 3-Solving-Problems-By-Searching/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ var GraphDrawAgent = function(graphProblem, selector, options, h, w) {
this.problem = graphProblem;

this.options = options;
this.nodeGroups = [];
this.nodeGroups = {};
this.edges = [];

this.reset = function() {
Expand Down Expand Up @@ -305,17 +305,16 @@ var GraphDrawAgent = function(graphProblem, selector, options, h, w) {
}
group._renderer.elem.onmouseenter = currentOptions.onMouseEnter;
group._renderer.elem.onmouseleave = currentOptions.onMouseLeave;
this.nodeGroups.push(group);
this.nodeGroups[key] = group;
}
this.two.update();
};
//Updates the nodes
this.iterateNodes = function() {
let nodeOptions = this.options.nodes;
for (var i = 0; i < this.nodeGroups.length; i++) {
let group = this.nodeGroups[i];
for (let nodeKey in this.nodeGroups) {
let group = this.nodeGroups[nodeKey];
let circle = group._collection[0];
let nodeKey = $(group._renderer.elem).attr('nodeKey');
let currentNode = this.problem.nodes[nodeKey];
let state = currentNode.state;
if (this.problem.nextToExpand == nodeKey) {
Expand Down Expand Up @@ -367,6 +366,14 @@ var GraphDrawAgent = function(graphProblem, selector, options, h, w) {
this.iterateEdges();
this.iterateNodes();
}
this.highlight = function(nodeKey) {
this.nodeGroups[nodeKey]._collection[0].scale = 1.2;
this.two.update();
}
this.unhighlight = function(nodeKey) {
this.nodeGroups[nodeKey]._collection[0].scale = 1;
this.two.update();
}
this.reset();
};

Expand All @@ -384,17 +391,17 @@ function QueueDrawAgent(selector, h, w, problem, options) {
width: w
}).appendTo(this.canvas);
this.problem = problem;
this.nodeRadius = 25;
this.nodeRadius = options.nodes.nodeRadius;
this.options = options;

this.iterate = function() {
this.two.clear();
var frontier = this.problem.frontier;
for (var i = 0; i < frontier.length; i++) {
node = this.problem.nodes[frontier[i]];
var x = (i) * 30 + 40;
var x = (i) * (this.nodeRadius+20) + 40;
var y = 20;
var rect = this.two.makeRectangle(x, y, this.nodeRadius, this.nodeRadius);
var rect = this.two.makeCircle(x, y, this.nodeRadius);
rect.fill = options.nodes.frontier.fill;
if (frontier[i] == this.problem.nextToExpand) {
rect.fill = options.nodes.next.fill;
Expand Down Expand Up @@ -433,42 +440,5 @@ var dlsDrawAgent = function(selector) {
}
}
this.graphDrawAgent.iterate();
this.iterateDepthsOnEdges();
}

this.drawDepthOnEdges = function() {
this.graphDrawAgent.depths = [];
let edges = this.graphDrawAgent.edges;
for (let i = 0; i < edges.length; i++) {
let node1Key = $(edges[i]._renderer.elem).attr('node1');
let node2Key = $(edges[i]._renderer.elem).attr('node2');
let node1 = this.graphProblem.nodes[node1Key];
let node2 = this.graphProblem.nodes[node2Key];
let coords = getEdgeCostLocation(node1.x, node1.y, node2.x, node2.y);
let text = this.graphDrawAgent.two.makeText(0, coords.x, coords.y);
text.opacity = 0;
this.graphDrawAgent.two.update();
$(text._renderer.elem).attr('node1', node1Key);
$(text._renderer.elem).attr('node2', node2Key);
this.graphDrawAgent.depths.push(text);
}
}
this.iterateDepthsOnEdges = function() {
for (let i = 0; i < this.graphDrawAgent.depths.length; i++) {
let text = this.graphDrawAgent.depths[i];
let node1Key = $(text._renderer.elem).attr('node1');
let node2Key = $(text._renderer.elem).attr('node2');
let node1 = this.graphProblem.nodes[node1Key];
let node2 = this.graphProblem.nodes[node2Key];
if (node1.state == 'explored' && node2.state == 'explored') {
let depth = Math.max(node1.depth, node2.depth);
text.value = depth;
text.opacity = 1;
} else {
text.opacity = 0;
}
}
this.graphDrawAgent.two.update();
}
this.drawDepthOnEdges();
}
Loading