From 569f902126fb557f50fce17ff7e14b77c7bd0a06 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Wed, 10 Jan 2024 12:42:13 +0100 Subject: [PATCH] Tests - added test for 8-Puzzle --- .../net/berack/upo/ai/problem1/Puzzle8.java | 32 ++++++++++--------- .../berack/upo/ai/problem1/TestPuzzle.java | 14 ++++++++ 2 files changed, 31 insertions(+), 15 deletions(-) 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 866b160..6a82935 100644 --- a/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java +++ b/src/main/java/net/berack/upo/ai/problem1/Puzzle8.java @@ -5,6 +5,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; import java.util.Random; +import java.util.function.BiFunction; /** * Classe utilizzata per la rappresentazione del problema delle 8 tessere. @@ -17,6 +18,20 @@ import java.util.Random; public class Puzzle8 implements Iterable { public static final int LENGTH = 3; public static final int[] DEFAULT_GOAL = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 0}; + public static final BiFunction HEURISTIC_MANHATTAN = (p1, p2) -> { + var sum = 0; + var n = p1.puzzle.length; + var index = new int[n]; + + for(var i = 0; i < n; i++) index[p1.puzzle[i]] = i; + for(var i = 0; i < n; i++) { + var curr = p2.puzzle[i]; + var i2 = index[curr]; + + sum += Math.abs((i / LENGTH) - (i2 / LENGTH)) + Math.abs((i % LENGTH) - (i2 % LENGTH)); + } + return sum; + }; /** * Possibili movimenti della tessera "vuota" @@ -250,21 +265,8 @@ public class Puzzle8 implements Iterable { public List solve(Puzzle8 goal) { if(!this.isSolvable(goal)) return null; - var aStar = new AStar(Puzzle8::availableMoves, (p, m) -> new Puzzle8(p, m)) - .setHeuristic((p1, p2) -> { - var sum = 0; - var n = p1.puzzle.length; - var index = new int[n]; - - for(var i = 0; i < n; i++) index[p1.puzzle[i]] = i; - for(var i = 0; i < n; i++) { - var curr = p2.puzzle[i]; - var i2 = index[curr]; - - sum += Math.abs((i / LENGTH) - (i2 / LENGTH)) + Math.abs((i % LENGTH) - (i2 % LENGTH)); - } - return sum; - }); + var aStar = new AStar(Puzzle8::availableMoves, (p, m) -> new Puzzle8(p, m)); + aStar.setHeuristic(HEURISTIC_MANHATTAN); return aStar.solve(this, Objects.requireNonNull(goal)); } 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 f7ff407..040f800 100644 --- a/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java +++ b/src/test/java/net/berack/upo/ai/problem1/TestPuzzle.java @@ -147,4 +147,18 @@ public class TestPuzzle { assertEquals(puzzle, goal); } + + @Test + public void testSolveHard() { + var goal = new Puzzle8(Puzzle8.DEFAULT_GOAL); + var puzzle = new Puzzle8(0,5,2,4,1,7,3,8,6); + var actions = puzzle.solve().toArray(new Puzzle8.Move[0]); + for(var move : actions) puzzle.move(move); + assertEquals(puzzle, goal); + + puzzle = new Puzzle8(0,8,3,7,5,2,6,1,4); + actions = puzzle.solve().toArray(new Puzzle8.Move[0]); + for(var move : actions) puzzle.move(move); + assertEquals(puzzle, goal); + } }