Skip to content
Snippets Groups Projects
Commit 39a7cb30 authored by Xuan Trinh's avatar Xuan Trinh
Browse files

Can run!! [D[D[D under most scenario! Will work on what if there no way a...

Can run!! [D[D[D under most scenario! Will work on what if there no way a piece can get to its target. XUAN 5:30PM [D[D[D[D[D[8[B[C[C[C[C[C 27 Mar 2021
parent 13a4c621
No related branches found
No related tags found
No related merge requests found
{
"upper": [
[
"p",
0,
-3
],
[
"s",
0,
0
]
],
"lower": [
[
"r",
0,
1
],
[
"p",
0,
2
]
],
"block": [
[
"",
-1,
-3
],
[
"",
-1,
-2
],
[
"",
-1,
-1
],
[
"",
-1,
0
],
[
"",
-1,
1
],
[
"",
-1,
2
],
[
"",
-1,
3
],
[
"",
0,
3
],
[
"",
1,
-4
],
[
"",
1,
-3
],
[
"",
1,
-2
],
[
"",
1,
-1
],
[
"",
1,
0
],
[
"",
1,
1
],
[
"",
1,
2
]
]
}
\ No newline at end of file
No preview for this file type
No preview for this file type
......@@ -8,14 +8,8 @@ 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 *
# Constant's definition.
def main():
# define global variable
......@@ -47,7 +41,8 @@ def main():
input()
upperDictPieces = update_state(upperDictPieces, lowerDictPieces, setBlocks, targetDict)
targetDict = check_if_piece_hit_target(upperDictPieces, lowerDictPieces, targetDict)
print(lowerDictPieces)
print_board(make_board(lowerDictPieces,upperDictPieces,setBlocks))
def parse_input(data):
"""
......@@ -101,40 +96,7 @@ def parse_input(data):
setBlocks.add((block[ROW], block[COLUMN]))
def piece_collision(pieceA, pieceB) -> int:
"""
Our upper pieces are R, P and S, lower pieces are r, p and s
We will convert both to lower case letters and check each case
Would be nice to use comparator but can't have r>s>p>r using it
Return A_WIN if pieceA wins, B_WIN if pieceB wins and DRAW if neither win
Only look at first character of string
:param pieceA: type of the token in {'R','P','S','r','p','s'}
:param pieceB: type of the token in {'R','P','S','r','p','s'}
:return: A_WIN, B_WIN or DRAW
"""
pieceA = pieceA[TYPE].lower()
pieceB = pieceB[TYPE].lower()
if pieceA == "r":
if pieceB == "s":
return A_WIN
elif pieceB == "p":
return B_WIN
elif pieceA == "s":
if pieceB == "p":
return A_WIN
elif pieceB == "r":
return B_WIN
elif pieceA == "p":
if pieceB == "r":
return A_WIN
elif pieceB == "s":
return B_WIN
return DRAW
......
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, swing_to_tile_1, swing_to_tile_2, swing_to_tile_3
from search.movement_logic import *
from search.util import print_board
BLOCK = ""
# BLOCK should be "" but put [X] so we can observe from the print_board statement
BLOCK = "[X]"
POSITION_CLOSEST_TO_TARGET = 0
TYPE = 0
ROW = 1
......@@ -16,9 +16,10 @@ FIRST_CHAR = 0
upperDictPieces = {}
lowerDictPieces ={}
targetDict = {}
targeted_l_piece = set()
setBlocks = set()
def make_board(lowerPieces, upperPieces, setBlocks):
"""
create a board of the current game -> can do a position look up.
......@@ -124,10 +125,12 @@ 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)
# add all the swing action to queue
position_list.extend(add_swing_action(upperDict, piece, board))
#print(position_list)
# sort the list base on the how close it is to target
if piece in targetDict.keys():
position_list.sort(key=(lambda x: distance_between(x, targetDict[piece])))
return position_list
......@@ -146,15 +149,71 @@ def update_state(upperPieces, lowerPieces, setBlocks, targetDict):
# create the board in order to support faster look up
board = make_board(lowerPieces, upperPieces, setBlocks)
print_board(board)
possible_action = {}
# 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)
upperPieces[piece] = position_list[POSITION_CLOSEST_TO_TARGET]
possible_action[piece] = make_priority_list_of_action(upperPieces, piece, targetDict, board)
upperPieces = choose_optimal_combination(possible_action, upperPieces, board, targetDict)
return upperPieces
def choose_optimal_combination(possible_action, upperPieces, board, targetDict):
"""
prioritise action lead a piece directly to its target.
else choose a combination that does not cause collision between upper piece
:param possible_action: all set of possible move sorted base on how close they are to the piece target
:param upperPieces: contain all upper piece
:param board: all piece
:param targetDict: map all piece to its target
:return:
"""
finished = set()
for piece in possible_action.keys():
if piece in possible_action.keys():
if piece in targetDict.keys() and compare_tile(possible_action[piece][0], targetDict[piece]):
# perform swap and update board
del board[upperPieces[piece]]
upperPieces[piece] = targetDict[piece]
board[targetDict[piece]] = piece
# we've finished with this piece.
finished.add(piece)
# each piece is moved once and only once.
for piece in possible_action:
if piece in finished:
continue
index = 0
moved = False
while not moved:
# check if the move exist in the board
if possible_action[piece][index] not in board.keys():
# perform swap and update board
del board[upperPieces[piece]]
upperPieces[piece] = possible_action[piece][index]
board[possible_action[piece][index]] = piece
moved = True
else:
# check if no collision happen:
if piece_collision(board[possible_action[piece][index]], piece) == DRAW:
# perform swap and update board
del board[upperPieces[piece]]
upperPieces[piece] = possible_action[piece][index]
board[possible_action[piece][index]] = piece
moved = True
index += 1
return upperPieces
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
......@@ -164,7 +223,7 @@ def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict):
"""
removed = False
for piece in upperPieces:
if targetDict and compare_tile(upperPieces[piece], targetDict[piece]):
if piece in targetDict.keys() and compare_tile(upperPieces[piece], targetDict[piece]):
for removed_piece in lowerPieces:
if compare_tile(lowerPieces[removed_piece],targetDict[piece]):
removed = removed_piece
......@@ -185,6 +244,42 @@ def check_if_piece_hit_target(upperPieces, lowerPieces, targetDict):
return targetDict
def piece_collision(pieceA, pieceB) -> int:
"""
Our upper pieces are R, P and S, lower pieces are r, p and s
We will convert both to lower case letters and check each case
Would be nice to use comparator but can't have r>s>p>r using it
Return A_WIN if pieceA wins, B_WIN if pieceB wins and DRAW if neither win
Only look at first character of string
:param pieceA: type of the token in {'R','P','S','r','p','s'}
:param pieceB: type of the token in {'R','P','S','r','p','s'}
:return: A_WIN, B_WIN or DRAW
"""
pieceA = pieceA[TYPE].lower()[0]
pieceB = pieceB[TYPE].lower()[0]
if pieceA == "r":
if pieceB == "s":
return A_WIN
elif pieceB == "p":
return B_WIN
elif pieceA == "s":
if pieceB == "p":
return A_WIN
elif pieceB == "r":
return B_WIN
elif pieceA == "p":
if pieceB == "r":
return A_WIN
elif pieceB == "s":
return B_WIN
return DRAW
def add_swing_action(upperDict, piece, board):
"""
check for adjacent tile.
......@@ -198,37 +293,37 @@ def add_swing_action(upperDict, piece, board):
# 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] != "":
right_tile in board and board[right_tile] != BLOCK:
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] != "":
left_tile in board and board[left_tile] != BLOCK:
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] != "":
up_left_tile in board and board[up_left_tile] != BLOCK:
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] != "":
up_right_tile in board and board[up_right_tile] != BLOCK:
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] != "":
down_left_tile in board and board[down_left_tile] != BLOCK:
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] != "":
down_right_tile in board and board[down_right_tile] != BLOCK:
adjacent_list.append(down_right_tile)
# if there are at least one adjacent piece : add the adjacent move from those tile
......@@ -271,9 +366,8 @@ def find_target(piece_key):
# Start with dummy information
targetPiece = ""
targetDist = MAX_DISTANCE
print(lowerDictPieces)
for key in lowerDictPieces:
if key[FIRST_CHAR] == target:
if key[FIRST_CHAR] == target and key not in targeted_l_piece:
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.
......@@ -287,4 +381,5 @@ def find_target(piece_key):
return
else:
targetDict[piece_key] = lowerDictPieces[targetPiece]
targeted_l_piece.add(targetPiece)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment