diff --git a/src/main/java/net/berack/upo/ai/problem1/AStar.java b/src/main/java/net/berack/upo/ai/problem1/AStar.java index 4ad8136..1df2cad 100644 --- a/src/main/java/net/berack/upo/ai/problem1/AStar.java +++ b/src/main/java/net/berack/upo/ai/problem1/AStar.java @@ -22,9 +22,6 @@ public class AStar { private BiFunction heuristic; private TriFunction cost; - private int lastStateVisitedCount = 0; - private int lastStateTotalCount = 0; - /** * Crea una istanza dell'algoritmo A* con una funzione di azioni possibili da compiere dato uno stato * e una funzione di transizione che dato uno stato permette di raggiungerne un'altro tramite un'azione. @@ -95,16 +92,11 @@ public class AStar { Objects.requireNonNull(initial); Objects.requireNonNull(goal); - this.lastStateVisitedCount = 0; - this.lastStateTotalCount = 1; - NodeState found = null; var list = new PriorityQueue(); list.add(new NodeState(null, initial, null, 0, 0)); while(list.size() > 0) { - this.lastStateVisitedCount += 1; - var current = list.poll(); if(current.state.equals(goal)) { found = current; @@ -112,8 +104,6 @@ public class AStar { } for(var action : this.actions.apply(current.state)) try { - - this.lastStateTotalCount += 1; var next = this.transition.apply(current.state, action); var cost = this.cost.apply(current.state, next, action); var dist = this.heuristic.apply(next, goal); @@ -137,16 +127,6 @@ public class AStar { return path; } - - public int lastStateVisitedCount() { - return this.lastStateVisitedCount; - } - - public int lastStateTotalCount() { - return this.lastStateTotalCount; - } - - /** * Classe privata per mantenere i dati all'interno della PriorityQueue. * Non è stata messa statica dato che ho bisogno dello stato e dell'azione. @@ -168,7 +148,7 @@ public class AStar { @Override public int compareTo(NodeState other) { - return this.total - other.total; + return Integer.compare(this.total, other.total); } } diff --git a/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java b/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java index 6c7eae4..95dd9ca 100644 --- a/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java +++ b/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java @@ -25,9 +25,9 @@ public class Puzzle8 implements Iterable { for(var i = 0; i < n; i++) index[p1.puzzle[i]] = i; for(var i = 0; i < n; i++) { - var curr = p2.puzzle[i]; - if(curr == 0) continue; + if(i == p2.blank) continue; + var curr = p2.puzzle[i]; var i2 = index[curr]; sum += Math.abs((i / LENGTH) - (i2 / LENGTH)) + Math.abs((i % LENGTH) - (i2 % LENGTH)); } @@ -117,7 +117,28 @@ public class Puzzle8 implements Iterable { */ public int get(int x, int y) { if(x >= LENGTH) throw new IndexOutOfBoundsException(); - return puzzle[y * LENGTH + x]; + return get(y * LENGTH + x); + } + + /** + * Permette di ricevere in input il valore della coordinata passata in input. + * Il valore in input ha formato flat2D, ovvero è un numero che rappresenta una coordinata 2D in uno spazio finito. + * La formula generale per calcolare il numero è la seguente: x + (MAX_X + 1) * y. + * Quindi nel nostro caso si può calcolare la formula con: x + Puzzle8.LENGTH * y. + * NOTA: non usare questo metodo se non si ha capito che cosa significhi. Piuttosto utilizzare {@link #get(int, int)} + * @param flat2D la rappresentazione monodimensionale della coordinata 2D + * @return il valore in quel punto del puzzle. + */ + public int get(int flat2D) { + return puzzle[flat2D]; + } + + /** + * Permette di avere la posizione della tessera vuota in formato flat2D utilizzabile nel metodo {@link #get(int)} + * @return la posizione dello 0 o tessera vuota + */ + public int getBlankPosition() { + return this.blank; } /** @@ -201,13 +222,14 @@ public class Puzzle8 implements Iterable { var rand = new Random(); for(var i = this.puzzle.length - 1; i > 0; i--) { var j = rand.nextInt(i + 1); - var temp = this.puzzle[i]; this.puzzle[i] = this.puzzle[j]; this.puzzle[j] = temp; - - if(this.puzzle[i] == 0) this.blank = i; } + + for(var i = 0; i < this.puzzle.length; i++) + if(this.puzzle[i] == 0) + this.blank = i; } /** diff --git a/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java b/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java index 2343bb7..d63e89b 100644 --- a/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java +++ b/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java @@ -19,7 +19,7 @@ public class TestPuzzle { var puzzle = new Puzzle8(goalArray); for(var i = 0; i < goalArray.length; i++) - assertEquals(goalArray[i], puzzle.get(i%3, i/3), "Error in initialization"); + assertEquals(goalArray[i], puzzle.get(i), "Error in initialization"); var puzzle2 = new Puzzle8(goalArray); assertEquals(puzzle, puzzle2, "Error in equality"); @@ -71,8 +71,7 @@ public class TestPuzzle { var puzzle = new Puzzle8(goalArray); var moves = new Puzzle8.Move[] {RIGHT, DOWN, LEFT, UP, DOWN, RIGHT, UP, LEFT}; - for(var move : moves) - puzzle = new Puzzle8(puzzle, move); + for(var move : moves) puzzle = new Puzzle8(puzzle, move); assertEquals(new Puzzle8(goalArray), puzzle, "After useless moves the puzzle must be the same as before!"); } @@ -158,4 +157,21 @@ public class TestPuzzle { for(var move : actions) puzzle.move(move); assertEquals(puzzle, goal); } + + @Test + public void testShuffleBlankPosition() { + var puzzle = new Puzzle8(Puzzle8.DEFAULT_GOAL); + var tot = Puzzle8.LENGTH * Puzzle8.LENGTH; + + for(var i = 0; i < 1000; i++) { + puzzle.shuffle(); + + var blank = 10; + for(var j = 0; j < tot; j++) + if(puzzle.get(j) == 0) + blank = j; + + assertEquals(blank, puzzle.getBlankPosition()); + } + } }