Skip to content

Commit

Permalink
Refactor Node class (using heuristicValue as an object)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreKavalerski committed Jul 4, 2020
1 parent b078929 commit e44bee1
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 64 deletions.
13 changes: 13 additions & 0 deletions src/classes/HeuristicValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default class HeuristicValue {
g: number;
h: number;

constructor(g: number, h: number){
this.g = g;
this.h = h;
}

get f(){
return this.g + this.h;
}
}
5 changes: 3 additions & 2 deletions src/classes/Node.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { State } from "../utils/state";
import { operations } from "../utils/operations";
import HeuristicValue from "./HeuristicValue";

class NodeInfo {
evaluationFunctionValue: number;
evaluationFunctionValue: HeuristicValue;
operation: operations;
state: State;
previousNode?: NodeInfo;

constructor(efValue: number, op: operations, s: State, prev?: NodeInfo){
constructor(efValue: HeuristicValue, op: operations, s: State, prev?: NodeInfo){
this.evaluationFunctionValue = efValue
this.operation = op
this.state = s
Expand Down
7 changes: 1 addition & 6 deletions src/functions/heuristic.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { State, StateItem } from "../utils/state"
import StateItemPosition from "../classes/StateItemPosition";


function calcHeuristicValue(actualState: State, goalState: State, gValue: number){
return gValue + calcHValue(actualState, goalState);
}

function calcHValue(actualState: State, goalState: State){
let totalDistance = 0;
for (let line in actualState){
Expand All @@ -28,4 +23,4 @@ function calcDistanceOfItem(item: StateItem, itemPosition: StateItemPosition, go
return 10; //TODO: Rever esse valor (ou tratamento diferente caso o item buscado não exista no estado objetivo)
}

export { calcHeuristicValue, calcDistanceOfItem }
export { calcHValue, calcDistanceOfItem }
18 changes: 10 additions & 8 deletions src/functions/node.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
import { operations } from './../utils/operations';
import { NodeInfo } from "../classes/Node"
import { State } from '../utils/state';
import { calcHeuristicValue } from './heuristic';
import { calcHValue } from './heuristic';
import { applyOperation } from './operations';
import HeuristicValue from '../classes/HeuristicValue';

function generateNodeList(node: NodeInfo, goalState: State, gValue: number): NodeInfo[]{
function generateNodeList(node: NodeInfo, goalState: State): NodeInfo[]{
let childrenNodes: NodeInfo[] = [];
const childUp = generateAndTest(operations.up, node, goalState, gValue);
const childUp = generateAndTest(operations.up, node, goalState, node.evaluationFunctionValue.g);
if (childUp){
childrenNodes.push(childUp);
}
const childRight = generateAndTest(operations.right, node, goalState, gValue);
const childRight = generateAndTest(operations.right, node, goalState, node.evaluationFunctionValue.g);
if (childRight){
childrenNodes.push(childRight);
}
const childDown = generateAndTest(operations.down, node, goalState, gValue);
const childDown = generateAndTest(operations.down, node, goalState, node.evaluationFunctionValue.g);
if (childDown){
childrenNodes.push(childDown);
}
const childLeft = generateAndTest(operations.left, node, goalState, gValue);
const childLeft = generateAndTest(operations.left, node, goalState, node.evaluationFunctionValue.g);
if (childLeft){
childrenNodes.push(childLeft);
}

return childrenNodes.sort((a, b) => (a.evaluationFunctionValue < b.evaluationFunctionValue) ? -1 : 1);
return childrenNodes;
}

function generateAndTest(op: operations, node: NodeInfo, goalState: State, gValue: number): NodeInfo | null{
Expand All @@ -35,7 +36,8 @@ function generateAndTest(op: operations, node: NodeInfo, goalState: State, gValu
}

function generateNode(state: State, op: operations, goalState: State, gValue: number, previousNode?: NodeInfo): NodeInfo{
const heuristicValue = calcHeuristicValue(state, goalState, gValue);
const hValue = calcHValue(state, goalState);
const heuristicValue = new HeuristicValue(gValue, hValue);
return new NodeInfo(heuristicValue, op, state, previousNode);
}

Expand Down
29 changes: 12 additions & 17 deletions tests/heuristic.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { expect } from 'chai';
import { calcHeuristicValue, calcDistanceOfItem } from "../src/functions/heuristic";
import { calcHValue, calcDistanceOfItem } from "../src/functions/heuristic";
import { State, StateItem } from '../src/utils/state';
import StateItemPosition from '../src/classes/StateItemPosition';

describe('Heuristic Smoke Tests', () => { // the tests container
it('should exist calcHeuristicValue function', () => {
expect(calcHeuristicValue).to.exist;
it('should exist calcHValue function', () => {
expect(calcHValue).to.exist;
});

it('should return a number when call calcHeuristicValue function', () => {
const initialState: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 0;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.be.a('number');
expect(calcHValue(initialState, goalState)).to.be.a('number');
});

it('should exist calcDistanceOfItem function', () => {
Expand Down Expand Up @@ -50,47 +50,42 @@ describe('Testing returns of calcDistanceOfItem', () => {
});
})

describe('Testing returns of calcHeuristicValue', () => {
it('should return 14 when call calcHeuristicValue function', () => {
describe('Testing returns of calcHValue', () => {
it('should return 14 when call calcHValue function', () => {
const initialState: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 0;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(14);
expect(calcHValue(initialState, goalState)).to.equal(14);
});


it('should return 15 when call calcHeuristicValue function', () => {
const initialState: State = [[null,5,8], [4,1,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 1;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(15);
expect(calcHValue(initialState, goalState)).to.equal(14);
});

it('should return 15 when call calcHeuristicValue function', () => {
const initialState: State = [[4,5,8], [7,1,6], [null, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 1;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(15);
expect(calcHValue(initialState, goalState)).to.equal(14);
});

it('should return 13 when call calcHeuristicValue function', () => {
const initialState: State = [[4,5,8], [1,null,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 1;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(13);
expect(calcHValue(initialState, goalState)).to.equal(12);
});

it('should return 14 when call calcHeuristicValue function', () => {
const initialState: State = [[4,null,8], [1,5,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 2;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(14);
expect(calcHValue(initialState, goalState)).to.equal(12);
});

it('should return 12 when call calcHeuristicValue function', () => {
const initialState: State = [[4,5,8], [1,2,6], [7, null, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const gValue = 2;
expect(calcHeuristicValue(initialState, goalState, gValue)).to.equal(12);
expect(calcHValue(initialState, goalState)).to.equal(10);
});
})
73 changes: 42 additions & 31 deletions tests/node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { expect } from 'chai';
import { generateNodeList, generateNode } from "../src/functions/node";
import { NodeInfo } from "../src/classes/Node";
import { State } from '../src/utils/state';
import HeuristicValue from '../src/classes/HeuristicValue';


describe('Node Smoke Tests', () => { // the tests container
Expand All @@ -16,10 +17,10 @@ describe('Node Smoke Tests', () => { // the tests container

it('should return an Array when call generateNodeList function', () => {
const state: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const node: NodeInfo = new NodeInfo(14, operations.none, state);
const gValue = 0;
const heuristicValue = new HeuristicValue(0, 14);
const node: NodeInfo = new NodeInfo(heuristicValue, operations.none, state);

expect(generateNodeList(node, state, gValue)).to.be.an('Array');
expect(generateNodeList(node, state)).to.be.an('Array');
});

it('should return a NodeInfo object when call generateNode function', () => {
Expand All @@ -34,75 +35,85 @@ describe('Testing returns of generateNode function', () => {
it('should return this NodeInfo obj when call generateNode function', () => {
const state: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const finalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const heuristicValue = new HeuristicValue(0, 14);

const expectedNode = new NodeInfo(14, operations.none, state);
const expectedNode = new NodeInfo(heuristicValue, operations.none, state);
const gValue = 0;
expect(generateNode(state, operations.none, finalState, gValue)).to.eql(expectedNode);
});

it('should return this NodeInfo obj when call generateNode function', () => {
const state: State = [[4,5,8], [1,null,6], [7, 2, 3]];
const finalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const heuristicValue = new HeuristicValue(1, 12);

const expectedNode = new NodeInfo(13, operations.left, state);
const expectedNode = new NodeInfo(heuristicValue, operations.left, state);
const gValue = 1;
expect(generateNode(state, operations.left, finalState, gValue)).to.eql(expectedNode);
});

it('should return this NodeInfo obj when call generateNode function', () => {
const state: State = [[4,5,8], [1,2,6], [7, 3, null]];
const finalState: State = [[1,2,3], [4,5,6], [7, 8, null]];

const mockedPreviousNode = new NodeInfo(0, operations.none, state);
const expectedNode = new NodeInfo(13, operations.up, state, mockedPreviousNode);
const heuristicValuePrevious = new HeuristicValue(0, 0);

const mockedPreviousNode = new NodeInfo(heuristicValuePrevious, operations.none, state);
const heuristicValueExpected = new HeuristicValue(3, 10);
const expectedNode = new NodeInfo(heuristicValueExpected, operations.up, state, mockedPreviousNode);
const gValue = 3;
expect(generateNode(state, operations.up, finalState, gValue, mockedPreviousNode)).to.eql(expectedNode);
});
});


describe('Testing returns of generateNodeList function', () => {

it('should return this NodeInfo array when call generateNodeList function', () => {
const state: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const rootNode = new NodeInfo(14, operations.none, state);
const gValue = 0;

const stateChild1: State = [[null,5,8], [4,1,6], [7, 2, 3]];
const expectedChild1 = new NodeInfo(15, operations.up, stateChild1, rootNode);
const heuristicValueRoot = new HeuristicValue(0, 14);
const rootNode = new NodeInfo(heuristicValueRoot, operations.none, state);

const stateChild1: State = [[null,5,8], [4,1,6], [7, 2, 3]];
const heuristicValue1 = new HeuristicValue(1, 14);
const expectedChild1 = new NodeInfo(heuristicValue1, operations.up, stateChild1, rootNode);

const stateChild2: State = [[4,5,8], [1,null,6], [7, 2, 3]];
const expectedChild2 = new NodeInfo(13, operations.right, stateChild2, rootNode);

const stateChild3: State = [[4,5,8], [7,1,6], [null, 2, 3]];
const expectedChild3 = new NodeInfo(15, operations.down, stateChild3, rootNode);
const heuristicValue2 = new HeuristicValue(1, 12);
const expectedChild2 = new NodeInfo(heuristicValue2, operations.right, stateChild2, rootNode);

const childrenList = [expectedChild2, expectedChild1 , expectedChild3];
const stateChild3: State = [[4,5,8], [7,1,6], [null, 2, 3]];
const heuristicValue3 = new HeuristicValue(1, 14);
const expectedChild3 = new NodeInfo(heuristicValue3, operations.down, stateChild3, rootNode);

expect(generateNodeList(rootNode, goalState, gValue)).to.eql(childrenList);
const childrenList = [expectedChild1, expectedChild2 , expectedChild3];

expect(generateNodeList(rootNode, goalState)).to.eql(childrenList);
});

it('should return this NodeInfo array when call generateNodeList function', () => {
const state: State = [[4,5,8], [1,null,6], [7, 2, 3]];
const goalState: State = [[1,2,3], [4,5,6], [7, 8, null]];
const rootNode = new NodeInfo(13, operations.right, state);
const gValue = 1;

const heuristicValueRoot = new HeuristicValue(1, 12);
const rootNode = new NodeInfo(heuristicValueRoot, operations.right, state);
const stateChild1: State = [[4,null,8], [1,5,6], [7, 2, 3]];
const expectedChild1 = new NodeInfo(14, operations.up, stateChild1, rootNode);
const heuristicValue1 = new HeuristicValue(2, 12);
const expectedChild1 = new NodeInfo(heuristicValue1, operations.up, stateChild1, rootNode);

const stateChild2: State = [[4,5,8], [1,6,null], [7, 2, 3]];
const expectedChild2 = new NodeInfo(14, operations.right, stateChild2, rootNode);
const heuristicValue2 = new HeuristicValue(2, 12);
const expectedChild2 = new NodeInfo(heuristicValue2, operations.right, stateChild2, rootNode);

const stateChild3: State = [[4,5,8], [1,2,6], [7, null, 3]];
const expectedChild3 = new NodeInfo(12, operations.down, stateChild3, rootNode);
const heuristicValue3 = new HeuristicValue(2, 10);
const expectedChild3 = new NodeInfo(heuristicValue3, operations.down, stateChild3, rootNode);

const stateChild4: State = [[4,5,8], [null,1,6], [7, 2, 3]];
const expectedChild4 = new NodeInfo(16, operations.left, stateChild4, rootNode);
const heuristicValue4 = new HeuristicValue(2, 14);
const expectedChild4 = new NodeInfo(heuristicValue4, operations.left, stateChild4, rootNode);

const childrenList = [expectedChild3, expectedChild1, expectedChild2, expectedChild4];

expect(generateNodeList(rootNode, goalState, gValue)).to.eql(childrenList);
const childrenList = [expectedChild1, expectedChild2, expectedChild3, expectedChild4];
expect(generateNodeList(rootNode, goalState)).to.eql(childrenList);
});
});

0 comments on commit e44bee1

Please sign in to comment.