From 13a4c62120bdbe24546613a25b19e60e2f0d87ec Mon Sep 17 00:00:00 2001
From: Xuan Trinh <xuan.trinh@student.unimelb.edu.au>
Date: Sat, 27 Mar 2021 17:36:59 +1100
Subject: [PATCH] =?UTF-8?q?Let=20piece=20-which=20is=20made=20it=20to=20it?=
 =?UTF-8?q?s=20target,=20choose=20another=20target=20if=20any.=20XUAN=20?=
 =?UTF-8?q?=1B5:36PM=2027=20March=202021?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Test_case/level_1/8.json                      |  22 +++
 search/__pycache__/main.cpython-38.pyc        | Bin 3858 -> 2823 bytes
 search/__pycache__/search_algo.cpython-38.pyc | Bin 4249 -> 6995 bytes
 search/main.py                                |  59 +------
 search/search_algo.py                         | 154 +++++++++++++++++-
 5 files changed, 171 insertions(+), 64 deletions(-)
 create mode 100644 Test_case/level_1/8.json

diff --git a/Test_case/level_1/8.json b/Test_case/level_1/8.json
new file mode 100644
index 0000000..c99b1f6
--- /dev/null
+++ b/Test_case/level_1/8.json
@@ -0,0 +1,22 @@
+{
+  "upper": [
+    [
+      "r",
+      4,
+      -4
+    ]
+  ],
+  "lower": [
+    [
+      "s",
+      0,
+      -2
+    ],
+    [
+      "s",
+      0,
+      4
+    ]
+  ],
+  "block": []
+}
\ No newline at end of file
diff --git a/search/__pycache__/main.cpython-38.pyc b/search/__pycache__/main.cpython-38.pyc
index 39cf0f0c5ea04dbc9c928500fcf177d8a05a2557..4796c0c303b7134efd9eeda4d2d15bd9c1c39d38 100644
GIT binary patch
delta 687
zcmbOv*Dl5v%FD~ez`(%Jbuli1Q)VKc45QmbZ6!_S9F`D<6qXd$7KSL+6t)!h7KSLc
zRQ42(IgBZsDO@cqQ5-2u!3>(*6HnYQNd_4J!^{i}44e!M49*M;48@BW7#ONFN*GEQ
zvzSsCB^jC-`vqzlN|+b0Og3Z^muJo9Dhgp_0KpQr6s8i!EcO)UUM5C{62=7_DU6fT
znUpP(N_dK<mGCw*Ffx?zm2j2tmk5;bG_xdfl?Z})Jk89BJcR`%Y$g27jEoE^48aVV
zEPgK;C+}slWE7hGk4cM-wV)_7uVk`1vyNUAcUop%N_<ITQF>}g6c>bc$xJS}#hRH{
zP+AhjQ(BOcSdtoFT#{IlI=PTp#yCncIU_YWJ3cclz92I-IW;~bvjl2@CUX%B0|Ub?
zmXySj#9ORj>6HvcqLWuK+o+3x0zd{7EX+)d0*n%je2jdI0!$pd9E@B{ER1Ymev$ZQ
zUX}w)jLehIu_>rVF$ejFN3l8k`-J-X74b7LFcb-b2qBOq%!w%}np{P~lZDyC<v@lP
zNrB`<;e;57#mB(FU^2Ob-I0-R^C|XaOo?(JQAH2|a*HNwkrIe4$-ux6#p)Oz?&%lB
z>I9}(T!I|KHJPH=z}|3#(oRLF7Tn?oOUEbY=j3D-XXfW+OuopaE2hT4z@W)_i#<L*
zB|kYnzK9KE3CCm!K79{y5EJCATg;hxB}E{WNM?df2f6$fhfQvNN@-529U~~<KpI#$
NI2gf@gF}JC1OU4Nm|Fk<

delta 1749
zcmZn{n<U2<%FD~ez`($8o*^!wU1=hp4C9Q6+Di2-IV`!XQLMRaQEa*FQS6KiDU2zs
zIUKp1QJf%l6jusc6n6@H6i*6U6mJT96kiHs6n_dwlt2n&lwc-9qEIG7qHrcdqDZP}
zGee?S3TFye3qzE63U>-m3qzDds$>f99L5yB6#f>LD5(^I6u}mTDCrcYU<OU0s?%J~
z6RWO-YBJxFOwLG6&W_Jai!aDbO-_x^$SjF3Ni0fFExE;&o0y#%pOl|ilyZxwv>+w1
zBsIRcB(Wq_lkpaJK~ZL22}JTGBLf4&OC}JJ%)r1f*^f~!q=X@bv6+#Pp-Q8Kv4km$
zIfY4*p_#E?pq8P8WdUmq!$QVd#&8BxhCqfOh6sjmhCCe>h7z`HuA&%51`sS^NMSBv
z%3@Dp>1ASMC}CQ_k-{{22cxoaRtZnhyb|6Lt`fcy{t}*MmPD=+ffB9~o@S;*o)U%<
zE|9H-6)6nC44SNdw-^(P*e44!S#k*8Vg);SvM-a?<T@tp@LSwznRzL2ze4=%l9^mm
z#LB?HaEm`DzdW@F#18<4OYtqv;?xqSoc!eM;v!}S1_n*$B5sg6mXySj#9OT3z+1^s
zBs*D+*+yN7fq|h|1{CMa9E?ni0*n%je2jdI0!$pd9E@B{ER1}NT#QBXn>(2gFfp=E
z_F_{|y~P~lAAXC?+21GB*RM#7fq|h&5=2OWEMZPeNzvpglAhep7A^-ew+LiIkt|37
zn2-apL>U+uoF}ueJ2HxHc4J@0l&A(0)dUeLAQ!V1X@S^^AQM>~<HJ4uZm~LnDHfL?
z$8b%iC^oP+9HF!mngzG`!P4=``8he6#hLke<&%B6bnA^77#Na4NdV+u5N2awU;u@o
zGbj|g7#J987)lr<8B!RtnTmu`m}(jG#GoR~*-S+$DJ->&c`PZcwTvljwM-?9wag_<
zE)20owJbF(CCrixH6VQ^B`hUOH7t@05VD!6mbHephB=#|sNST8rIx9NwU)Wiq=vZ!
zq_`@Dy@a)f!G<A^r-Z47Ns<A=OW_D+(Bw=kWn^IBQczG(2+7DSR!A$&OD@UG&r?Xw
zNX$!5EmkPWNL46H%qdM($WH@vvQsM+(lg6a^As}kKmuUBkmRC}l9^l&(w$gTsZf#+
zl2u5~$uCYVE>TF$OU<oR0Ed`DW{E;_VxB@$YGMgkcSNY8pOr#Vr9yFPL1Iy2NoopM
zYiU72Y7xjBaN2|D)ln!<RY=LtD^bWx1u4r{C{9f*O3qM7%P#_JsxQyT&q)Qj1m=*`
zvQ&_BGILWwdXw{W3lfV`^|-(`TY>D$g%};5omy$70P-Hxrx3@M<ST%3hC-qO)RSrX
zMS2S1sS3pz`K3823i)|Cl?vtgMcE4FnI#zt^$=GV<Rn(67O59Qj4p;)R+L&&T9jv{
zkXM?M0~RS#2c<x8lGFgPK<TmwoJ^HLTu@r}(_{mu(_1{gjuG)Lp1~oGe$KAo%y5g#
z%`+%CB;MJ>F(^tPC9}9BF)z73H9je|q&zh>uSf!v%Gshg!TtdG?iL%w3sKw<8l07*
zxF8&t%;J(;%-N}xQ5;aCQqdB8kvIbb!)#D0Rsf}IZXQN9Mjl2sCKeVJMixd6Mjl2X
zW)1~L7DhG}P__mu*Oa-%9v`2QpBx`w#0T<|z~l*B`t_h9qlg8>2jz??Zb&5Rm6l}Y
z6oK*!*vmyaAO*T0!T>}Vf(RoJVFDsdK?I^?0QvS7b8%`(5vYtPk_X9xihx_pnRz8e
zpj-)d5ZF&XU=l)r%8FYYHo5sJr8%i~pp07#Di>HdI2b`tgpr38<UJ(J1ZFd_F>@$#
InDD6p0Feo>g#Z8m

diff --git a/search/__pycache__/search_algo.cpython-38.pyc b/search/__pycache__/search_algo.cpython-38.pyc
index a78ee17d6e28f7e9f68cc5ee5a115a10aa34ce4f..38e12487fceb0dbd91d980333270203f9d429110 100644
GIT binary patch
delta 3699
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
G91Z|Z5Q-!K

delta 1221
zcmca?HdB!=l$V!_fq{V`kTEXdt;j?^8ODl<+M3af3@HpLOgWsnTv1$%3@OY}+$juE
zJSi+GtSt;tyeVuc>@5sYd?_3$oGlDd{3%>1+${`I0x3Kxye$k-f+>6{{4ESoLMZ|%
zf-MYD!YM+*44T3(LH1~JO#E9dtjTzbyPzmDuOvPxKd~s~7DF=gByow&PZ_T>G73-L
z%j_x5$-ux+ECABM!NSPF$j1c1T#QAclNDKHm1Gzg7-|?&7_*s*cv6^xL2Tx1rXq<H
zmSBby)?fxrw#gYR_o8kw2Hj#TxWyQJi?QeyV{wr%0|SF5V-#0GW@>V3d`V?NDp&|Y
zh%hiP+!9JpEr~BKDay}FPc4cEtCIz}1sqCj9E>2>urL-$Z(ho(!xSyZz`#%ha^@|T
zoXp~qD89skg4Dc}%)In?5FcVL$kHOP;R1;%De=WQnJKC9iOD6I`FUC(qe1!^I9Qlv
z5Rj=zezFdSEThk4FAf<~yBd}nCP{`8rfjAntr~`41}LAohOrqG0(M|Ah6OA&ObZzq
z89+Qu#?A9NvKWmtS&KM8-eSp4tt>9$0XbJ1#AkyzRFm}<Z$W->Cde%i7Yj~y;8IEh
zISI}2MW7(}1i4oT6fHblj4Vt%OgxM%%mR!o%v_9M`D7N592B!MFff4l%pgr_3=9k<
z3^fcL3^mNn%(W~vELn`3Z*e_hG+)W+r^#5v367atj1?=Hia?=yi>oBDC_S~rB{R7M
z;u3HOa@gb~<|d^i+LcWH%;R9pR3s1b4NGx;QHdsN5h$j>x{E;8fg`3!3FK#R6sUq&
zB9j|<6$R5kPGSSOlbeTGjHyU_@)q6%#+1pTe14PbxOpb`FzHR^73G<HoymBzDF0$^
zQIJ+p5-8H1e3)OUo)5(51rhup0%04-=}1<B?FBoWr?em?u_QIVxFoS8wGw1KC^8th
zco;cAX`7LcsYsWBfgza*<R~Zx1so_4ok7Y$Nu`Ftg&|g<mZ`pmv4{l}nxJG+!w4dq
znTl9IEL(;`mKw%jh9YHffP!ORlR1j3w4flhC;*h~Az=e{DA;*m0_;Y~<c!qh?D)(y
zNV<>D$SjG6#6mB~1)zk)z{J5Q#>mCNRHVniz~HATGFe8-zUmftacW{wa)w@MNoGzF
zIGjMfE7Ac44mj*Ui4GiB;AB#y4Uz!)7i<h9e!=bl6JW=1*yQG?l;)(`F@o#{3289#
WFtISQFms4-@N&p=$Z`mChyVbs6!R+p

diff --git a/search/main.py b/search/main.py
index 5f9abbd..59181f2 100644
--- a/search/main.py
+++ b/search/main.py
@@ -9,32 +9,17 @@ This script contains the entry point to the program (the code in
 import sys
 import json
 from search.movement_logic import *
-from search.search_algo import check_if_piece_hit_target, make_board, update_state
-from search.util import print_board
+from search.search_algo import *
 
 # Constant's definition.
 
 
-TYPE = 0
-ROW = 1
-COLUMN = 2
-A_WIN = 1
-B_WIN = 2
-DRAW = 0
-MAX_DISTANCE = 99
-FIRST_CHAR = 0
 
-upperDictPieces = {}
-lowerDictPieces ={}
-targetDict = {}
-
-setBlocks = set()
 
 
 def main():
     # define global variable
     global upperDictPieces, lowerDictPieces, targetDict, setBlocks
-    print("a")
     try:
         with open(sys.argv[1]) as file:
             data = json.load(file)
@@ -59,10 +44,10 @@ def main():
         find_target(piece)
     # keep moving until all the piece met its target
     while targetDict:
+        input()
         upperDictPieces = update_state(upperDictPieces, lowerDictPieces, setBlocks, targetDict)
-        targetDict = check_if_piece_hit_target(upperDictPieces, targetDict)
-        print(upperDictPieces)
-
+        targetDict = check_if_piece_hit_target(upperDictPieces, lowerDictPieces, targetDict)
+    print(lowerDictPieces)
 
 def parse_input(data):
     """
@@ -152,43 +137,7 @@ def piece_collision(pieceA, pieceB) -> int:
     return DRAW
 
 
-def find_target(piece_key):
-    """
-    This function changes the value of the key given in the
-    target dictionary to the closest enemy piece it can beat
-    XUAN: by separated the upper to lower piece, we dont need to search for the whole dictionary every time we compare.
 
-    :param piece_key: key of the piece to find a target for. We should only work with upper player's pieces
-    :return: null
-    """
-    global targetDict
-    # Set the target
-    if piece_key[TYPE] == "R":
-        target = "s"
-    elif piece_key[TYPE] == "S":
-        target = "p"
-    else:
-        target = "r"
-
-    # Now we check which target is closest
-    # Start with dummy information
-    targetPiece = ""
-    targetDist = MAX_DISTANCE
-    for key in lowerDictPieces:
-        if key[FIRST_CHAR] == target:
-            distance = distance_between(lowerDictPieces[key], lowerDictPieces[key])
-            # if the distance between this key and the query key is less than the least distance.
-            # as well as the key is not targeted by any other key.
-            if distance < targetDist:
-                targetPiece = key
-                targetDist = distance
-
-    # Now add target to dictionary
-    # case where no key that match criteria.
-    if targetDist == MAX_DISTANCE:
-        targetDict[piece_key] = ()
-    else:
-        targetDict[piece_key] = lowerDictPieces[targetPiece]
 
 
     # Situation 1: If you plan the route ahead without knowing any other piece route,
diff --git a/search/search_algo.py b/search/search_algo.py
index f55d69a..9d9519c 100644
--- a/search/search_algo.py
+++ b/search/search_algo.py
@@ -1,10 +1,23 @@
 from search.movement_logic import slide_right, slide_left, slide_up_left, slide_up_right, slide_down_left, \
-    slide_down_right, compare_tile, distance_between
+    slide_down_right, compare_tile, distance_between, swing_to_tile_1, swing_to_tile_2, swing_to_tile_3
 from search.util import print_board
 
 BLOCK = ""
 POSITION_CLOSEST_TO_TARGET = 0
+TYPE = 0
+ROW = 1
+COLUMN = 2
+A_WIN = 1
+B_WIN = 2
+DRAW = 0
+MAX_DISTANCE = 99
+FIRST_CHAR = 0
 
+upperDictPieces = {}
+lowerDictPieces ={}
+targetDict = {}
+
+setBlocks = set()
 
 def make_board(lowerPieces, upperPieces, setBlocks):
     """
@@ -32,9 +45,9 @@ def get_stronger_piece(piece_type):
     :param piece_type: the type of the piece that we are interested
     :return: the type of the piece that stronger than the input piece
     """
-    if piece_type == 'R':
+    if piece_type[0] == 'R':
         return 'p'
-    if piece_type == 'S':
+    if piece_type[0] == 'S':
         return 'r'
     return 's'
 
@@ -91,7 +104,7 @@ def add_if_valid(position_list, piece, new_position, piece_position, board):
             return position_list
 
         # check if the new position is occupied by piece that stronger
-        elif board[new_position] == get_stronger_piece(piece):
+        elif board[new_position][0] == get_stronger_piece(piece):
             return position_list
 
     # add the new position and return
@@ -111,7 +124,9 @@ def make_priority_list_of_action(upperDict, piece, targetDict, board):
     """
     # add all the adjacent move to queue
     position_list = add_slide_action(upperDict, piece, board)
+    position_list.extend(add_swing_action(upperDict, piece, board))
 
+    #print(position_list)
     # sort the list base on the how close it is to target
     position_list.sort(key=(lambda x: distance_between(x, targetDict[piece])))
 
@@ -134,21 +149,142 @@ def update_state(upperPieces, lowerPieces, setBlocks, targetDict):
 
     # right now, i assume there only 1 piece, there will be more code combine all the queue.
     for piece in upperPieces:
-        position_list = make_priority_list_of_action(upperPieces,piece, targetDict, board)
+        position_list = make_priority_list_of_action(upperPieces, piece, targetDict, board)
         upperPieces[piece] = position_list[POSITION_CLOSEST_TO_TARGET]
 
     return upperPieces
 
 
-def check_if_piece_hit_target(upperPiece, targetDict):
+def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict):
     """
     remove the target from the target dictionary if the upper piece is at its target location
     :param upperPiece: contain all upper piece
     :param targetDict: map upper piece to its lower target
     :return: the updated target dictionary
     """
-    for piece in upperPiece:
-        if targetDict and compare_tile(upperPiece[piece], targetDict[piece]):
+    removed = False
+    for piece in upperPieces:
+        if targetDict and compare_tile(upperPieces[piece], targetDict[piece]):
+            for removed_piece in lowerPieces:
+                if compare_tile(lowerPieces[removed_piece],targetDict[piece]):
+                   removed = removed_piece
             del targetDict[piece]
+            del lowerPieces[removed]
+            removed = True
+    # once the piece hit it target, it is free to find a new target.
+    # if there are more lower piece then which already targeted {some lower piece is not target}
+    # we can check if the available pieces can target those
+    if removed and len(lowerPieces) > len(targetDict):
+        for piece in upperPieces:
+            # when a piece is remove then there will
+            if piece in targetDict:
+                continue
+
+            find_target(piece)
+
+    return targetDict
+
+
+def add_swing_action(upperDict, piece, board):
+    """
+    check for adjacent tile.
+    if there are any adjacent tile to this add swing action from those tile
+    :param upperDict: contain all the upper piece
+    :param piece: which we want to move
+    :param board: dictionary contain all piece in the game
+    :return: list of all action added
+    """
+    adjacent_list = []
+    # check the right tile
+    right_tile = slide_right(upperDict[piece])
+    if not compare_tile(right_tile, upperDict[piece]) and\
+            right_tile in board and board[right_tile] != "":
+        adjacent_list.append(right_tile)
+
+    # check the left tile
+    left_tile = slide_left(upperDict[piece])
+    if not compare_tile(left_tile, upperDict[piece]) and\
+            left_tile in board and board[left_tile] != "":
+        adjacent_list.append(left_tile)
+
+    # check the up_left
+    up_left_tile = slide_up_left(upperDict[piece])
+    if not compare_tile(up_left_tile, upperDict[piece]) and\
+            up_left_tile in board and board[up_left_tile] != "":
+        adjacent_list.append(up_left_tile)
+
+    # check the up_right
+    up_right_tile = slide_up_right(upperDict[piece])
+    if not compare_tile(up_right_tile, upperDict[piece]) and\
+            up_right_tile in board and board[up_right_tile] != "":
+        adjacent_list.append(up_right_tile)
+
+    # check the down_left
+    down_left_tile = slide_down_left(upperDict[piece])
+    if not compare_tile(down_left_tile, upperDict[piece]) and\
+            down_left_tile in board and board[down_left_tile] != "":
+        adjacent_list.append(down_left_tile)
+
+    # check the down_right
+    down_right_tile = slide_down_right(upperDict[piece])
+    if not compare_tile(down_right_tile, upperDict[piece]) and\
+            down_right_tile in board and board[down_right_tile] != "":
+        adjacent_list.append(down_right_tile)
+
+    # if there are at least one adjacent piece : add the adjacent move from  those tile
+    position_list = []
+    for adjacent_piece in adjacent_list:
+        # add the swing action to tile 1 (look at swing_action section in movement_logic modulo)
+        position_list = add_if_valid(position_list, piece, swing_to_tile_1(upperDict[piece], adjacent_piece),
+                                     upperDict[piece], board)
+
+        # add the swing action to tile 2
+        position_list = add_if_valid(position_list, piece, swing_to_tile_2(upperDict[piece], adjacent_piece),
+                                    upperDict[piece], board)
+
+        # add the swing action to tile 3
+        position_list = add_if_valid(position_list, piece, swing_to_tile_3(upperDict[piece], adjacent_piece),
+                                    upperDict[piece], board)
+
+    return position_list
+
+
+def find_target(piece_key):
+    """
+    This function changes the value of the key given in the
+    target dictionary to the closest enemy piece it can beat
+    XUAN: by separated the upper to lower piece, we dont need to search for the whole dictionary every time we compare.
+
+    :param piece_key: key of the piece to find a target for. We should only work with upper player's pieces
+    :return: null
+    """
+    global targetDict
+    # Set the target
+    if piece_key[TYPE] == "R":
+        target = "s"
+    elif piece_key[TYPE] == "S":
+        target = "p"
+    else:
+        target = "r"
+
+    # Now we check which target is closest
+    # Start with dummy information
+    targetPiece = ""
+    targetDist = MAX_DISTANCE
+    print(lowerDictPieces)
+    for key in lowerDictPieces:
+        if key[FIRST_CHAR] == target:
+            distance = distance_between(upperDictPieces[piece_key], lowerDictPieces[key])
+            # if the distance between this key and the query key is less than the least distance.
+            # as well as the key is not targeted by any other key.
+            if distance < targetDist:
+                targetPiece = key
+                targetDist = distance
+
+    # Now add target to dictionary
+    # case where no key that match criteria.
+    if targetDist == MAX_DISTANCE:
+        return
+    else:
+        targetDict[piece_key] = lowerDictPieces[targetPiece]
 
-    return targetDict
\ No newline at end of file
-- 
GitLab