diff --git a/search/__pycache__/method.cpython-38.pyc b/search/__pycache__/method.cpython-38.pyc
index 5e38a9f00b59c12ca1756d8f39293229d8a97b76..0400de112aa4ed4e6f0ff7a2edbb169348170aad 100644
Binary files a/search/__pycache__/method.cpython-38.pyc and b/search/__pycache__/method.cpython-38.pyc differ
diff --git a/search/__pycache__/movement_logic.cpython-38.pyc b/search/__pycache__/movement_logic.cpython-38.pyc
index 624608e075463829c30dedab89a6cbc99f4338d0..ea2011bd4267979726c999e2ad4197c2eb26874c 100644
Binary files a/search/__pycache__/movement_logic.cpython-38.pyc and b/search/__pycache__/movement_logic.cpython-38.pyc differ
diff --git a/search/search_algorithm.py b/search/search_algorithm.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffcad3c52daa066636289683a51574f5e48af2f2
--- /dev/null
+++ b/search/search_algorithm.py
@@ -0,0 +1,78 @@
+"""
+logic:
+    -> prioritise the action which take the token closer to its target
+"""
+from search.method import distance_between
+from search.movement_logic import slide_right, slide_left, slide_up_left, slide_up_right, slide_down_left, \
+    slide_down_right
+
+
+def add_to_queue(record, queue, token_position, target):
+    """
+    :argument record: the tile that current token already pass by
+    :param queue: tile a wait to be process.
+    :param token_position: current position
+    :param target: where the token want to go
+    :return:
+
+        -> check the adjcent tile and weight them {prioritise the tile close to the target first}
+        -> append them to the queue in that order
+    """
+    #add all the adjcent move to queue
+    appending_list = add_adjcent_action(record, token_position, target)
+
+    #sort the list base on the how close it is to target
+    appending_list.sort(key = (lambda x: distance_between(x, target)))
+
+    #add the list to the head to the queue
+    appending_list.extend(queue)
+
+    return appending_list
+
+
+def add_if_new_tile(record, list, tile, target):
+    """
+    handle check if the tile has been seen by the token before
+    we only add after we expand the node
+    :param record: log all move of the token while moving toward the target.
+    :param list: the temporary list to append to while await to process
+    :param tile: the adjcent tile of a token
+    :return: the list so the local change can be pass to higher scope
+    """
+    if not tile in record or (record[tile] != target):
+        list.append(tile)
+    return list
+
+
+def add_adjcent_action(record, token_position, target):
+    """
+    create a abstraction to hide implementation detail on how to add adjcent move
+    :param record: ensure add the move we have not seen
+    :param token: current position of the token
+    :param target: where the token want to get to
+    :return: the queue
+    """
+    appending_list = []
+
+    # check the right tile
+    appending_list = add_if_new_tile(record, appending_list, slide_right(token_position), target)
+
+    # check the left tile
+    appending_list = add_if_new_tile(record, appending_list, slide_left(token_position), target)
+
+    # check the up_left
+    appending_list = add_if_new_tile(record, appending_list, slide_up_left(token_position), target)
+
+    # check the up_uight
+    appending_list = add_if_new_tile(record, appending_list, slide_up_right(token_position), target)
+
+    # check the down_left
+    appending_list = add_if_new_tile(record, appending_list, slide_down_left(token_position), target)
+
+    # check the down_right
+    appending_list = add_if_new_tile(record, appending_list, slide_down_right(token_position), target)
+
+    return appending_list
+
+
+