Top Banner
TUGAS BESAR KECERDASAN BUATAN Implementasi Teknik Pencarian A* Pada Aplikasi Wolu Puzzle Di Susun Oleh : Ryan Danny Kresnawan (1104120069) Trio Wibowo Martha (1104121156) SK-36-03 PROGRAM STUDI SISTEM KOMPUTER FAKULTAS TEKNIK ELEKTRO
33

Implementasi Algortima A Star Pada Aplikasi Wolu Puzzle

Oct 02, 2015

Download

Documents

Tugas Besar Mata Kuliah Artificial Intelligence : Implementasi Algoritma A Star Pada Aplikasi Wolu Puzzle
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

TUGAS BESAR KECERDASAN BUATANImplementasi Teknik Pencarian A* Pada Aplikasi Wolu Puzzle

Di Susun Oleh :Ryan Danny Kresnawan (1104120069)Trio Wibowo Martha (1104121156)SK-36-03

PROGRAM STUDI SISTEM KOMPUTERFAKULTAS TEKNIK ELEKTROUNIVERSITAS TELKOM2014

2 | Page

BAB IDESKRIPSI MASALAHWolu Puzzle adalah representasi permainan teka-teki yang dapat diselesaikan dengan mengurutkan atau menyusun komponen-komponen pembentuknya sesuai dengan kondisi yang berurut. Komponen pada Wolu Puzzle adalah berupa kotak-kotak bernomor yang dapat diacak sedemikian hingga menjadi suatu pola random yang dapat dicari jalan penyelesaiannya . Sesuai namanya, Wolu Puzzle terdiri atas 8 kotak dan 1 tempat kosong yang dapat digerakkan dengan aturan tertentu. Aturan pergerakannya hanya berupa empat arah pergerakan, yaitu atas, bawah, kanan, dan kiri. Pada Wolu Puzzle, batasannya adalah ukuran 33. Sehingga, 8 kotak yang dimiliki hanya dapat bergerak dalam lingkup ukuran tersebut.

Aplikasi permainan merupakan salah satu implementasi dari ilmu di bidang komputer. Inti dari sebuah aplikasi permainan adalah mengembangkan kemampuan otak untuk mengatur strategi, kecepatan, dan ketepatan dalam mencapai tujuan akhir. Salah satu contoh permainan adalah puzzle. Puzzle terdiri dari beberapa jenis, ada yang menggunakan angka, huruf, dan gambar. Dalam permainan puzzle, pemain diharapkan dapat mencapai tujuan akhir untuk membentuk sebuah puzzle menjadi sebuah gambar atau pola yang benar dengan waktu yang cepat. Algoritma A Star adalah algoritma pencarian graf yang menemukan jalur dari status awal ke status akhir. Algoritma ini menggunakan fungsi heuristic (biasanya didenotasikan dengan ) untuk menentukan urutan dimana pencarian dilakukan dengan mengunjungi node dalam pohon. merepresentasikan biaya jalan yang paling efisien sampai ke tujuan. Fungsi heuristic yang digunakan Algoritma A Star untuk memecahkan kasus bervariasi tergantung dari kasus yang akan dihadapi, misal untuk memecahkan kasus pencarian jalur terpendek dari satu ke kota lain menggunakan fungsi heuristic distance plus cost sedang untuk memecahkan kasus Wolu Puzzle, maka digunakan fungsi heuristic city block distance atau sering juga disebut dengan istilah manhattan distance. Dalam program Wolu Puzzle ini, Initial state di tentukan secara acak, dan dengan Final state yang sudah ditentukan. Untuk memenangkan permainan, pemain harus mencapai Final state yang sudah ditentukan sebelumnya, selain itu program juga akan memberikan solusi yang tepat dan cepat untuk menyelesaikan Wolu Puzzle jika pemain menginginkannya.

BAB IIRANCANGAN STATE SPACEDari kasus Wolu Puzzle ini, terdapat kemungkinan state space yaitu sebagai berikut : 1 | Artificial Intelligence

1,2,3,4,5,6,7,8,B 1,2,3,4,5,6,B,7,8 1,2,3,4,5,B,6,7,8 1,2,3,4,B,5,6,7,8 1,2,3,B,4,5,6,7,8 dst

State dalam masalah Wolu Puzzle ini di definisikan sebagai : (a,b,c,d,e,f,g,h,i) dengan nilai a,b,c,d,e,f,g,h,i adalah 1,2,3,4,5,6,7,8,B dan tidak boleh sama satu dengan yang lainnya. Dalam kasus 8-Puzzle ini akan terdapat 9x8x7x6x5x4x3x2x1 = 362880 State yang mungkin terjadi. State space ditenukan secara acak oleh program. Final state sudah ditentukan sebelumnya dan bersifat tetap atau tidak berubah. Operator yang digunakan yaitu BL(Blank Left), BR(Blank Right), BU (Blank Up), dan BD (Blank Down). BU (Blank Up) : Posisi Blank (B) ditukar dengan nilai yang berada diatasnya. BD (Blank Down) : Posisi Blank (B) ditukar dengan nilai yang berada dibawahnya. BL (Blank Left): Posisi Blank (B) ditukar dengan nilai yang berada dikirinya. BR (Blank Right): Posisi Blank (B) ditukar dengan nilai yang berada dikananya.

Contoh kemungkinan yang dapat terjadi :

Initial StateFinal State

BAB IIIRANCANGAN FUNGSI EVALUASIAlgoritma A Star merupakan salah satu algoritma yang menggunakan fungsi biaya (cost). Algoritma A Star memeriksa kelayakan biaya yang diperlukan untuk mencapai suatu simpul dari sebuah simpul lain. Dalam kasus Wolu Puzzle ini, algoritma A Star membandingkan 2 posisi puzzle yaitu posisi puzzle awal (state awal) dengan posisi puzzle yang terurut dengan benar (state akhir). Rumus yang digunakan oleh algoritma A Star yaitu :f(n) = g(n) + h(n)dengan :

g(n) = Jumlah pergerakan untuk mencapai Final state.h(n) = Jumlah total gerakan vertikal dan horisontal yang diperlukan setiap kotak pada state-n untuk mencapai final state. 123

456

7B8

Contoh Penentuan heuristic :

Nilai heuristic susunan diatas yaitu h(n)= 2 karena kotak-8 dan kotak-blank membutuhkan satu kali gerakan untuk mencapai Final State.

BAB IVSIMULASI SEARCHINGDalam simulasi searching yang akan digunakan pada program, diambil satu sample data Initial State secara acak yaitu :Simulasi :f(n)=g(n)+h(n)g(n) = Jumlah pergerakan untuk mencapai Final state yang dimulai dari initial state.h(n) = Jumlah total gerakan vertikal dan horisontal yang diperlukan setiap kotak pada state-n untuk mencapai final state.

Initial State

f(n)= 0 + 6 = 4

f(n)= 1 + 6 = 7f(n)= 1 + 6 = 7

f(n)= 2 + 6 = 8f(n)= 2 + 4 = 6f(n)= 2 + 8 = 10

f(n)= 3 + 4 = 7f(n)= 3 + 2 = 5f(n)= 3 + 6 = 9f(n)= 3 + 6 = 9

f(n)= 4 + 0 = 4f(n)= 4 + 4 = 8f(n)= 4 + 4 = 8

Final State

BAB VLISTING PROGRAM

1.MainMenu.java

package tubes1AI;

import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.InputEvent;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;

import javax.swing.AbstractAction;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JMenuItem;import javax.swing.JPanel;import javax.swing.JToolBar;import javax.swing.KeyStroke;import javax.swing.border.EtchedBorder;

public class MainMenu extends JFrame implements KeyListener {private static final long serialVersionUID = 33L;private TestAction all = new TestAction();private KotakPuzzle kotak = new KotakPuzzle();// menu file dan deklarasi itemprivate JMenu game;private JMenuItem newGame;private JMenu solve;private JMenuItem aStar;private JMenu help;private JMenuItem finalState;

private JMenuBar menu = new JMenuBar();

public MainMenu() {};

public MainMenu(String name) {setTitle(name);this.setLayout(new BorderLayout());

add(kotak, BorderLayout.CENTER);// add(kotak, BorderLayout.EAST);

// membuat menugame = createJMenu("Game", 'G');solve = createJMenu("Solve", 'S');help = createJMenu("Help", 'H');

newGame = createJMenuItem("New Game ", 'N', 'N', 0, all);game.add(newGame);

aStar = createJMenuItem("A* ", 'S', 'S', 0, all);solve.add(aStar);

finalState = createJMenuItem("Final State ", 'A', ' ', 0, all);help.add(finalState);

menu.setSelected(game);

menu.setBorder(new EtchedBorder());menu.add(game);menu.add(solve);menu.add(help);

this.setJMenuBar(menu);

addKeylistener();this.setFocusable(true);} // end of MainInterface(String name) constructor

public void solving() {kotak.solvepuzzle();}

// event handlersclass TestAction extends AbstractAction {

private static final long serialVersionUID = 33L;

public TestAction() {}

public void actionPerformed(ActionEvent event) {

if (event.getSource() == newGame) {removeKeylistener();addKeylistener();

kotak.randomize();}

else if (event.getSource() == finalState) {JFrame tempFrame = new JFrame("Final State");tempFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);tempFrame.getContentPane().add(new JLabel(new ImageIcon(getClass().getResource("Images/final.png"))));tempFrame.pack();tempFrame.setResizable(false);tempFrame.setLocationRelativeTo(null);tempFrame.setVisible(true);}

if (event.getSource() == aStar) {kotak.solvepuzzle();removeKeylistener();}

} // end of method ActionPerformed()} // end of class TestAction

// menambahkan buttonvoid addButton(JToolBar toolBar, JButton button, String toolTipText) {toolBar.add(button);button.setText(null);button.setToolTipText(toolTipText);}

// membuat menuJMenu createJMenu(String jMenuName, char mnemonicChar) {JMenu myMenu = new JMenu(jMenuName);myMenu.getPopupMenu().setLightWeightPopupEnabled(false);myMenu.setMnemonic(mnemonicChar);

return myMenu;}

// membuat menu itemJMenuItem createJMenuItem(String jMenuName, char mnemonicChar, int keyChar,int modifierInt, AbstractAction action) {JMenuItem menuItem = new JMenuItem(jMenuName);menuItem.setMnemonic(mnemonicChar);menuItem.setAccelerator(KeyStroke.getKeyStroke(keyChar, modifierInt));menuItem.addActionListener(action);

return menuItem;}

public void keyTyped(KeyEvent event) {}

public void keyPressed(KeyEvent event) {}

public void keyReleased(KeyEvent event) {

// menggunakan tombol arah untuk tombol kontrolif ((event.getKeyCode() == KeyEvent.VK_UP) || (event.getKeyCode() == KeyEvent.VK_LEFT)|| (event.getKeyCode() == KeyEvent.VK_RIGHT) || (event.getKeyCode() == KeyEvent.VK_DOWN)) {

// menggerakan kotak jika benarkotak.cekGerak(event.getKeyCode());

if (kotak.cekFinal())removeKeylistener();}}

public void removeKeylistener() {this.removeKeyListener(this);}

public void addKeylistener() {this.addKeyListener(this);}}

2.KotakPuzzle.java

package tubes1AI;

import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.util.Random;

import javax.swing.Icon;import javax.swing.ImageIcon;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.Timer;import javax.swing.border.BevelBorder;import javax.swing.border.EtchedBorder;

public class KotakPuzzle extends JPanel implements ActionListener {

private static final long serialVersionUID = 333L;// kotak angka puzzle dalam bentuk matriksprivate JLabel[][] tile = new JLabel[3][3];private Node startNode, smallestNode, branchNode;private LinkList openList = new LinkList();private LinkList closeList = new LinkList();private LinkList finalState = new LinkList();

private ListNode currentListNode;

// inisial matriks acakprivate int[][] tileMatrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

// final state matriksprivate int[][] FinalState = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

// icon untuk kotakprivate Icon tempIcon = new ImageIcon();

private int idCount;private int tempInt;// instansiasi pengacakanprivate Random r = new Random();

// hitungan pengacakanprivate int countScramble;

// waktu mulai dan selesei pengacakanprivate Timer timer, timer1;private FinalPathTimer finalPathTimer = new FinalPathTimer();

// kotak kosongprivate int iEmpty = 2, jEmpty = 2;

// instansiasi kotak baruKotakPuzzle() {setLayout(new GridLayout(3, 3, 5, 5));setBorder(new EtchedBorder());

timer = new Timer(0, this);timer1 = new Timer(300, finalPathTimer);for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)tile[i][j] = createJLabel(String.format("Images/%d.png",tileMatrix[i][j]));

addTiles();// mengacak posisi kotakrandomize();}

public JLabel createJLabel(String path) {JLabel newLabel = new JLabel();newLabel.setIcon(new ImageIcon(getClass().getResource(path)));newLabel.setBorder(new BevelBorder(BevelBorder.RAISED));

return newLabel;}

// cek pergerakan kotakpublic void cekGerak(int keyCode) {

switch (keyCode) {case KeyEvent.VK_UP:if (iEmpty == 2) {break;} else {blankDown();iEmpty += 1;}break;case KeyEvent.VK_DOWN:if (iEmpty == 0) {break;} else {blankUp();iEmpty -= 1;}

break;

case KeyEvent.VK_LEFT:if (jEmpty == 2) {break;} else {blankRight();jEmpty += 1;}break;

case KeyEvent.VK_RIGHT:

if (jEmpty == 0) {break;} else {blankLeft();jEmpty -= 1;}break;}

}

// blank leftprivate void blankLeft() {tempIcon = tile[iEmpty][jEmpty].getIcon();tempInt = tileMatrix[iEmpty][jEmpty];

// menggerakkan kotaktile[iEmpty][jEmpty].setIcon(tile[iEmpty][jEmpty - 1].getIcon());// update matrikstileMatrix[iEmpty][jEmpty] = tileMatrix[iEmpty][jEmpty - 1];

tile[iEmpty][jEmpty - 1].setIcon(tempIcon);tileMatrix[iEmpty][jEmpty - 1] = tempInt;}

// blank rightprivate void blankRight() {tempIcon = tile[iEmpty][jEmpty].getIcon();tempInt = tileMatrix[iEmpty][jEmpty];

// menggerakan kotaktile[iEmpty][jEmpty].setIcon(tile[iEmpty][jEmpty + 1].getIcon());// update matrikstileMatrix[iEmpty][jEmpty] = tileMatrix[iEmpty][jEmpty + 1];

tile[iEmpty][jEmpty + 1].setIcon(tempIcon);tileMatrix[iEmpty][jEmpty + 1] = tempInt;}

// blank upprivate void blankUp() {tempIcon = tile[iEmpty][jEmpty].getIcon();tempInt = tileMatrix[iEmpty][jEmpty];

// menggerakkan kotaktile[iEmpty][jEmpty].setIcon(tile[iEmpty - 1][jEmpty].getIcon());// update matrikstileMatrix[iEmpty][jEmpty] = tileMatrix[iEmpty - 1][jEmpty];

tile[iEmpty - 1][jEmpty].setIcon(tempIcon);tileMatrix[iEmpty - 1][jEmpty] = tempInt;}

// blank downprivate void blankDown() {tempIcon = tile[iEmpty][jEmpty].getIcon();tempInt = tileMatrix[iEmpty][jEmpty];

// menggerakkan kotatile[iEmpty][jEmpty].setIcon(tile[iEmpty + 1][jEmpty].getIcon());// update matrikstileMatrix[iEmpty][jEmpty] = tileMatrix[iEmpty + 1][jEmpty];

tile[iEmpty + 1][jEmpty].setIcon(tempIcon);tileMatrix[iEmpty + 1][jEmpty] = tempInt;}

// metode penyelesaian puzzlepublic void solvepuzzle() {System.gc();openList.setEmptyList();finalState.setEmptyList();closeList.setEmptyList();idCount = 0;startNode = new Node(0, tileMatrix, idCount, -1);

openList.insertAtBack(startNode);

while (!openList.isEmpty()) {smallestNode = openList.getSmallestNode();// Final state munculif (isSameState(smallestNode.getState(), FinalState)) {closeList.insertAtBack(smallestNode);break;} else {// Final state not reached yet and needs further search{openList.removeNode(smallestNode);closeList.insertAtBack(smallestNode);// case 0if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 0) {branchNode = blankRight(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();}

// case 1else if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 1) {branchNode = blankLeft(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();branchNode = blankRight(smallestNode);checkBranchNodeInLists();}

// case 2else if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 2) {branchNode = blankLeft(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();}// case 3else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 0) {branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankRight(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();}// case 4else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 1) {branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankRight(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();branchNode = blankLeft(smallestNode);checkBranchNodeInLists();}// case 5else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 2) {branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankLeft(smallestNode);checkBranchNodeInLists();branchNode = blankDown(smallestNode);checkBranchNodeInLists();}// case 6else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 0) {branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankRight(smallestNode);checkBranchNodeInLists();}// case 7else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 1) {branchNode = blankLeft(smallestNode);checkBranchNodeInLists();branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankRight(smallestNode);checkBranchNodeInLists();}// case 8else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 2) {branchNode = blankUp(smallestNode);checkBranchNodeInLists();branchNode = blankLeft(smallestNode);checkBranchNodeInLists();}}}

backTrackNodes();currentListNode = finalState.getFirstNode();timer1.start();resetTilesMatrix();}

private void resetTilesMatrix() {iEmpty = jEmpty = 2;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {tileMatrix[i][j] = FinalState[i][j];}}}

// cek nodepublic void checkBranchNodeInLists() {if (closeList.alreadyExists(branchNode));else {if (!openList.alreadyExists(branchNode)) {openList.insertAtBack(branchNode);}}}

public void backTrackNodes() {

Node insertNode = closeList.getLastNode().getNode();

finalState.insertAtFront(insertNode);

ListNode current = closeList.getLastNode().previousNode;

while (current != null) {if (insertNode.getParentID() == current.getNode().getID()) {insertNode = current.getNode();finalState.insertAtFront(insertNode);}current = current.previousNode;}

}

// cek statepublic boolean isSameState(int[][] A, int[][] B) {for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)if (A[i][j] != B[i][j])return false;return true;}

// menambahkan kotakpublic void addTiles() {for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)add(tile[i][j]);}

// blank leftpublic Node blankLeft(Node currentNode) {int[][] tmpState = new int[3][3];int i, j;for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)tmpState[i][j] = currentNode.getState()[i][j];int x = currentNode.getEmptyX();int y = currentNode.getEmptyY();

int tmp = tmpState[x][y];tmpState[x][y] = tmpState[x][y - 1];tmpState[x][y - 1] = tmp;

return new Node(currentNode.getG() + 1, tmpState, ++idCount, currentNode.getID());}

// blank rightpublic Node blankRight(Node currentNode) {int[][] tmpState = new int[3][3];int i, j;for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)tmpState[i][j] = currentNode.getState()[i][j];

int x = currentNode.getEmptyX();int y = currentNode.getEmptyY();

int tmp = tmpState[x][y];tmpState[x][y] = tmpState[x][y + 1];tmpState[x][y + 1] = tmp;

return new Node(currentNode.getG() + 1, tmpState, ++idCount, currentNode.getID());}

// blank uppublic Node blankUp(Node currentNode) {int[][] tmpState = new int[3][3];int i, j;for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)tmpState[i][j] = currentNode.getState()[i][j];

int x = currentNode.getEmptyX();int y = currentNode.getEmptyY();

int tmp = tmpState[x][y];tmpState[x][y] = tmpState[x - 1][y];tmpState[x - 1][y] = tmp;

return new Node(currentNode.getG() + 1, tmpState, ++idCount, currentNode.getID());}

// blank downpublic Node blankDown(Node currentNode) {int[][] tmpState = new int[3][3];int i, j;for (i = 0; i < 3; i++)for (j = 0; j < 3; j++)tmpState[i][j] = currentNode.getState()[i][j];

int x = currentNode.getEmptyX();int y = currentNode.getEmptyY();

int tmp = tmpState[x][y];tmpState[x][y] = tmpState[x + 1][y];tmpState[x + 1][y] = tmp;

return new Node(currentNode.getG() + 1, tmpState, ++idCount, currentNode.getID());}

// acak kotakpublic void randomize() {countScramble = 0;timer.start();}

// cek final statepublic boolean cekFinal() {if (tileMatrix[0][0] == 1 && tileMatrix[0][1] == 2&& tileMatrix[0][2] == 3 && tileMatrix[1][0] == 4&& tileMatrix[1][1] == 5 && tileMatrix[1][2] == 6&& tileMatrix[2][0] == 7 && tileMatrix[2][1] == 8&& tileMatrix[2][2] == 9) {JOptionPane.showMessageDialog(KotakPuzzle.this,"Selamat ! Kamu Menang !!", "Message",JOptionPane.INFORMATION_MESSAGE);return true;}

return false;}

// mengerakkan kotakpublic void actionPerformed(ActionEvent event) {

int randNum;countScramble++;

if (countScramble < 200) {

if (iEmpty == 0 && jEmpty == 0) {randNum = r.nextInt(2);if (randNum == 0) {tempInt = tileMatrix[0][0];tempIcon = tile[0][0].getIcon();tileMatrix[0][0] = tileMatrix[0][1];tile[0][0].setIcon(tile[0][1].getIcon());tileMatrix[0][1] = tempInt;tile[0][1].setIcon(tempIcon);jEmpty = 1;} else {tempInt = tileMatrix[0][0];tempIcon = tile[0][0].getIcon();tileMatrix[0][0] = tileMatrix[1][0];tile[0][0].setIcon(tile[1][0].getIcon());tileMatrix[1][0] = tempInt;tile[1][0].setIcon(tempIcon);iEmpty = 1;}} else if (iEmpty == 0 && jEmpty == 1) {randNum = r.nextInt(3);if (randNum == 0) {tempInt = tileMatrix[0][1];tempIcon = tile[0][1].getIcon();tileMatrix[0][1] = tileMatrix[0][0];tile[0][1].setIcon(tile[0][0].getIcon());tileMatrix[0][0] = tempInt;tile[0][0].setIcon(tempIcon);jEmpty = 0;} else if (randNum == 1) {tempInt = tileMatrix[0][1];tempIcon = tile[0][1].getIcon();tileMatrix[0][1] = tileMatrix[0][2];tile[0][1].setIcon(tile[0][2].getIcon());tileMatrix[0][2] = tempInt;tile[0][2].setIcon(tempIcon);jEmpty = 2;} else {tempInt = tileMatrix[0][1];tempIcon = tile[0][1].getIcon();tileMatrix[0][1] = tileMatrix[1][1];tile[0][1].setIcon(tile[1][1].getIcon());tileMatrix[1][1] = tempInt;tile[1][1].setIcon(tempIcon);iEmpty = 1;}} else if (iEmpty == 0 && jEmpty == 2) {randNum = r.nextInt(2);if (randNum == 0) {tempInt = tileMatrix[0][2];tempIcon = tile[0][2].getIcon();tileMatrix[0][2] = tileMatrix[0][1];tile[0][2].setIcon(tile[0][1].getIcon());tileMatrix[0][1] = tempInt;tile[0][1].setIcon(tempIcon);jEmpty = 1;} else {tempInt = tileMatrix[0][2];tempIcon = tile[0][2].getIcon();tileMatrix[0][2] = tileMatrix[1][2];tile[0][2].setIcon(tile[1][2].getIcon());tileMatrix[1][2] = tempInt;tile[1][2].setIcon(tempIcon);iEmpty = 1;}} else if (iEmpty == 1 && jEmpty == 0) {randNum = r.nextInt(3);if (randNum == 0) {tempInt = tileMatrix[1][0];tempIcon = tile[1][0].getIcon();tileMatrix[1][0] = tileMatrix[0][0];tile[1][0].setIcon(tile[0][0].getIcon());tileMatrix[0][0] = tempInt;tile[0][0].setIcon(tempIcon);iEmpty = 0;} else if (randNum == 1) {tempInt = tileMatrix[1][0];tempIcon = tile[1][0].getIcon();tileMatrix[1][0] = tileMatrix[1][1];tile[1][0].setIcon(tile[1][1].getIcon());tileMatrix[1][1] = tempInt;tile[1][1].setIcon(tempIcon);jEmpty = 1;} else {tempInt = tileMatrix[1][0];tempIcon = tile[1][0].getIcon();tileMatrix[1][0] = tileMatrix[2][0];tile[1][0].setIcon(tile[2][0].getIcon());tileMatrix[2][0] = tempInt;tile[2][0].setIcon(tempIcon);iEmpty = 2;}} else if (iEmpty == 1 && jEmpty == 1) {randNum = r.nextInt(4);if (randNum == 0) {tempInt = tileMatrix[1][1];tempIcon = tile[1][1].getIcon();tileMatrix[1][1] = tileMatrix[0][1];tile[1][1].setIcon(tile[0][1].getIcon());tileMatrix[0][1] = tempInt;tile[0][1].setIcon(tempIcon);iEmpty = 0;} else if (randNum == 1) {tempInt = tileMatrix[1][1];tempIcon = tile[1][1].getIcon();tileMatrix[1][1] = tileMatrix[1][0];tile[1][1].setIcon(tile[1][0].getIcon());tileMatrix[1][0] = tempInt;tile[1][0].setIcon(tempIcon);jEmpty = 0;} else if (randNum == 2) {tempInt = tileMatrix[1][1];tempIcon = tile[1][1].getIcon();tileMatrix[1][1] = tileMatrix[1][2];tile[1][1].setIcon(tile[1][2].getIcon());tileMatrix[1][2] = tempInt;tile[1][2].setIcon(tempIcon);jEmpty = 2;} else {tempInt = tileMatrix[1][1];tempIcon = tile[1][1].getIcon();tileMatrix[1][1] = tileMatrix[2][1];tile[1][1].setIcon(tile[2][1].getIcon());tileMatrix[2][1] = tempInt;tile[2][1].setIcon(tempIcon);iEmpty = 2;}} else if (iEmpty == 1 && jEmpty == 2) {randNum = r.nextInt(3);if (randNum == 0) {tempInt = tileMatrix[1][2];tempIcon = tile[1][2].getIcon();tileMatrix[1][2] = tileMatrix[0][2];tile[1][2].setIcon(tile[0][2].getIcon());tileMatrix[0][2] = tempInt;tile[0][2].setIcon(tempIcon);iEmpty = 0;} else if (randNum == 1) {tempInt = tileMatrix[1][2];tempIcon = tile[1][2].getIcon();tileMatrix[1][2] = tileMatrix[1][1];tile[1][2].setIcon(tile[1][1].getIcon());tileMatrix[1][1] = tempInt;tile[1][1].setIcon(tempIcon);jEmpty = 1;} else {tempInt = tileMatrix[1][2];tempIcon = tile[1][2].getIcon();tileMatrix[1][2] = tileMatrix[2][2];tile[1][2].setIcon(tile[2][2].getIcon());tileMatrix[2][2] = tempInt;tile[2][2].setIcon(tempIcon);iEmpty = 2;}} else if (iEmpty == 2 && jEmpty == 0) {randNum = r.nextInt(2);if (randNum == 0) {tempInt = tileMatrix[2][0];tempIcon = tile[2][0].getIcon();tileMatrix[2][0] = tileMatrix[1][0];tile[2][0].setIcon(tile[1][0].getIcon());tileMatrix[1][0] = tempInt;tile[1][0].setIcon(tempIcon);iEmpty = 1;} else {tempInt = tileMatrix[2][0];tempIcon = tile[2][0].getIcon();tileMatrix[2][0] = tileMatrix[2][1];tile[2][0].setIcon(tile[2][1].getIcon());tileMatrix[2][1] = tempInt;tile[2][1].setIcon(tempIcon);jEmpty = 1;}}

else if (iEmpty == 2 && jEmpty == 1) {randNum = r.nextInt(3);if (randNum == 0) {tempInt = tileMatrix[2][1];tempIcon = tile[2][1].getIcon();tileMatrix[2][1] = tileMatrix[1][1];tile[2][1].setIcon(tile[1][1].getIcon());tileMatrix[1][1] = tempInt;tile[1][1].setIcon(tempIcon);iEmpty = 1;

} else if (randNum == 1) {tempInt = tileMatrix[2][1];tempIcon = tile[2][1].getIcon();tileMatrix[2][1] = tileMatrix[2][0];tile[2][1].setIcon(tile[2][0].getIcon());tileMatrix[2][0] = tempInt;tile[2][0].setIcon(tempIcon);jEmpty = 0;} else {tempInt = tileMatrix[2][1];tempIcon = tile[2][1].getIcon();tileMatrix[2][1] = tileMatrix[2][2];tile[2][1].setIcon(tile[2][2].getIcon());tileMatrix[2][2] = tempInt;tile[2][2].setIcon(tempIcon);jEmpty = 2;}} else if (iEmpty == 2 && jEmpty == 2) {randNum = r.nextInt(2);if (randNum == 0) {tempInt = tileMatrix[2][2];tempIcon = tile[2][2].getIcon();tileMatrix[2][2] = tileMatrix[1][2];tile[2][2].setIcon(tile[1][2].getIcon());tileMatrix[1][2] = tempInt;tile[1][2].setIcon(tempIcon);iEmpty = 1;} else {tempInt = tileMatrix[2][2];tempIcon = tile[2][2].getIcon();tileMatrix[2][2] = tileMatrix[2][1];tile[2][2].setIcon(tile[2][1].getIcon());tileMatrix[2][1] = tempInt;tile[2][1].setIcon(tempIcon);jEmpty = 1;}}} else {stopTimer();}

}

// menghentikan timerpublic void stopTimer() {timer.stop();}

// FinalPathTimerclass FinalPathTimer implements ActionListener {public void actionPerformed(ActionEvent event) {if (currentListNode != null) {for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++) {tile[i][j].setIcon(new ImageIcon(getClass().getResource(String.format("Images/%d.png",currentListNode.getNode().getState()[i][j]))));}currentListNode = currentListNode.getNext();} elsestopTimer1();}

// menghentikan timer1public void stopTimer1() {timer1.stop();}}}

3.LinkList.java

package tubes1AI;

public class LinkList {// node pertamaprivate ListNode firstNode;// node terakhirprivate ListNode lastNode;

public LinkList() {firstNode = lastNode = null;}

public void insertAtBack(Node node) {if (isEmpty())firstNode = lastNode = new ListNode(node);else {ListNode newNode = new ListNode(node);lastNode.nextNode = newNode;newNode.previousNode = lastNode;lastNode = newNode;}}

public void insertAtFront(Node node) {if (isEmpty())firstNode = lastNode = new ListNode(node);else {ListNode newNode = new ListNode(node);newNode.nextNode = firstNode;firstNode.previousNode = newNode;firstNode = newNode;}}

public Node getSmallestNode() {

Node minimumNode = firstNode.getNode();ListNode current = firstNode.getNext();

while (current != null) {if (current.getNode().getF() < minimumNode.getF())minimumNode = current.getNode();current = current.getNext();}return minimumNode;}

public void removeNode(Node node) {if (isEmpty())return;else if (isSameState(node, firstNode.getNode()) && firstNode == lastNode) {firstNode = lastNode = null;return;} else if (isSameState(node, firstNode.getNode())) {firstNode = firstNode.getNext();firstNode.previousNode = null;return;} else if (isSameState(node, lastNode.getNode())) {lastNode = lastNode.getPrevious();lastNode.nextNode = null;} else {ListNode current = firstNode;while (current.getNext() != null) {if (isSameState(current.getNext().getNode(), node)) {current.nextNode.nextNode.previousNode = current;current.nextNode = current.getNext().getNext();return; // break} elsecurrent = current.nextNode;}}}

// cek apakah kosongpublic boolean isEmpty() {return firstNode == null;}

// cek apakah isipublic boolean alreadyExists(Node node) {if (!isEmpty()) {ListNode current = firstNode;while (current != null) {if (isSameState(current.getNode(), node))return true;elsecurrent = current.getNext();}return false;}return false;}

// cek apakah state samapublic boolean isSameState(Node A, Node B) {int[][] stateA = A.getState();int[][] stateB = B.getState();

for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)if (stateA[i][j] != stateB[i][j])return false;return true;}

public ListNode getLastNode() {return lastNode;}

public ListNode getFirstNode() {return firstNode;}

// set list yang kosongpublic void setEmptyList() {firstNode = lastNode = null;}}

4.ListNode.javapackage tubes1AI;

public class ListNode {// nodeprivate Node node;// node berikutnyapublic ListNode nextNode;// node sebelumnyapublic ListNode previousNode;

// list node barupublic ListNode() {node = new Node();}

// list node barupublic ListNode(Node node) {this(node, null, null);}

// list node barupublic ListNode(Node node, ListNode previous, ListNode next) {this.node = node;previousNode = previous;nextNode = next;}

public Node getNode() {return node;}

public ListNode getNext() {return nextNode;}

public ListNode getPrevious() {return previousNode;}}

5.Node.javapackage tubes1AI;

public class Node {// deklarasi 9 kotak ke dalam node // stateprivate int[][] state = new int[3][3];

private int h; // deklarasi fungsi heuristic Manhattanprivate int g;private int id;private int parentID;private int emptyX;private int emptyY;

public Node(){g = -1;id = -1;parentID = -1;}

// instansiasi node baru.public Node(int g, int[][] state, int id, int parentID) {this.g = g;setState(state);

this.id = id;this.parentID = parentID;}

// mengcopy semua variabel fungsipublic void copyAll(Node n) {setState(n.getState());h = n.getH();g = n.getG();id = n.id;parentID = n.getParentID();emptyX = n.getEmptyX();emptyY = n.getEmptyY();}

public int[][] getState() {return state;}

public void setState(int[][] state) {for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)this.state[i][j] = state[i][j];calculateXY();calculateH();}

// menghitung xypublic void calculateXY() {for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++)if (state[i][j] == 9) {emptyX = i;emptyY = j;break;}}

public int getID() {return id;}

public int getParentID() {return parentID;}

public int getG() {return g;}

public int getH() {return h;}

public int getEmptyX() {return emptyX;}

public int getEmptyY() {return emptyY;}

public int getF() {return g + h;}

// menghitung hpublic void calculateH() {int tempH = 0;int FinalStateX = 0, FinalStateY = 0;for (int i = 0; i < 3; i++)for (int j = 0; j < 3; j++) {switch (state[i][j]) {case 1:FinalStateX = 0;FinalStateY = 0;break;case 2:FinalStateX = 0;FinalStateY = 1;break;case 3:FinalStateX = 0;FinalStateY = 2;break;case 4:FinalStateX = 1;FinalStateY = 0;break;case 5:FinalStateX = 1;FinalStateY = 1;break;case 6:FinalStateX = 1;FinalStateY = 2;break;case 7:FinalStateX = 2;FinalStateY = 0;break;case 8:FinalStateX = 2;FinalStateY = 1;break;case 9:FinalStateX = 2;FinalStateY = 2;break;}tempH += Math.abs(FinalStateX - i) + Math.abs(FinalStateY - j);}

this.h = tempH;}

}

6.WoluPuzzle.java (Kelas Utama)package tubes1AI;

import javax.swing.JFrame;

public class WoluPuzzle {

public static void main(String[] args) {MainMenu frame = new MainMenu("Wolu Puzzle");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();frame.setResizable(false);frame.setVisible(true);frame.setLocationRelativeTo(null);}

}