diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000000000000000000000000000000000000..db25fb7f0197e6d9c0ba94386084cc04e4198214 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,13 @@ +<component name="InspectionProjectProfileManager"> + <profile version="1.0"> + <option name="myName" value="Project Default" /> + <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true"> + <option name="ignoredErrors"> + <list> + <option value="N806" /> + <option value="N803" /> + </list> + </option> + </inspection_tool> + </profile> +</component> \ No newline at end of file diff --git a/search/__pycache__/main.cpython-38.pyc b/search/__pycache__/main.cpython-38.pyc index 84aa148a1abe1e015af49a4114970573a6d5286e..616e48299948de696d98b0d9e0253aa967bc760b 100644 Binary files a/search/__pycache__/main.cpython-38.pyc and b/search/__pycache__/main.cpython-38.pyc differ diff --git a/search/__pycache__/movement_logic.cpython-38.pyc b/search/__pycache__/movement_logic.cpython-38.pyc index ea2011bd4267979726c999e2ad4197c2eb26874c..73f5474c9ead21cb9510b416712b3b8c3be0f9bc 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/main.py b/search/main.py index 5a067833529a7c47de513cd2c2a0a6acaf258df8..4c8316d78ae749a75167f70e68122848f088acb7 100644 --- a/search/main.py +++ b/search/main.py @@ -15,12 +15,23 @@ import json from search.movement_logic import * from search.util import print_board, print_slide, print_swing +# Constant's definition. +TYPE = 0 +ROW = 1 +COLUMN = 2 + +A_WIN = 1 +B_WIN = 2 +DRAW = 0 + +MAX_DISTANCE = 99 + # Why don't we just make the pieces and blocks global then? # No need to ever pass them around -dictpieces = {} -setblocks = set() +dictPieces = {} +setBlocks = set() +dictTargets = {} -dicttargets = {} def main(): try: @@ -31,7 +42,7 @@ def main(): sys.exit(1) parse_input(data) - print(dictpieces) + print(dictPieces) # So basically it is heavily implied to treat the game as a state-based search problem. # We are also told in question 3 of the design report to discuss the time and space @@ -48,9 +59,6 @@ def main(): # Algorithm start - - - # TODO: # Find and print a solution to the board configuration described # by `data`. @@ -58,103 +66,130 @@ def main(): # `print_board` helper function? (See the `util.py` source code for # usage information). + def parse_input(data): + """ + data is a dictionary with keys "upper", "lower" and "block" + pieces in dictionary, blocks in set, we can use if position in setblocks + + parse data into either dictPieces or setBlocks + :param data: Dictionary obtain after read from JSON file using JSON module. + :return: NULL + """ # We can put the code to read the file NOT in the try/except statement because # if the file couldn't be read the process would end anyway - # data is a dictionary with keys "upper", "lower" and "block" - # pieces in dictionary, blocks in set, we can use if position in setblocks - initialpiecesupper = data["upper"] - initialpieceslower = data["lower"] - initialblocks = data["block"] + initialPiecesUpper = data["upper"] + initialPiecesLower = data["lower"] + initialBlocks = data["block"] + + keyWrite = "" + + # Parse the Upper's player token nump, numr, nums = 0, 0, 0 - keywrite = "" - for piece in initialpiecesupper: - if piece[0] == "p": + for piece in initialPiecesUpper: + if piece[TYPE] == "p": nump = nump + 1 - keywrite = "P" + str(nump) - elif piece[0] == "r": + keyWrite = "P" + str(nump) + elif piece[TYPE] == "r": numr = numr + 1 - keywrite = "R" + str(numr) + keyWrite = "R" + str(numr) else: nums = nums + 1 - keywrite = "S" + str(nums) - dictpieces[keywrite] = (piece[1], piece[2]) + keyWrite = "S" + str(nums) + dictPieces[keyWrite] = (piece[ROW], piece[COLUMN]) + + # parse the Lower player's token nump, numr, nums = 0, 0, 0 - for piece in initialpieceslower: - if piece[0] == "p": + for piece in initialPiecesLower: + if piece[TYPE] == "p": nump = nump + 1 - keywrite = "p" + str(nump) - elif piece[0] == "r": + keyWrite = "p" + str(nump) + elif piece[TYPE] == "r": numr = numr + 1 - keywrite = "r" + str(numr) + keyWrite = "r" + str(numr) else: nums = nums + 1 - keywrite = "s" + str(nums) - dictpieces[keywrite] = (piece[1], piece[2]) - for block in initialblocks: - setblocks.add((block[1], block[2])) - - -# 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 1 if piecea wins, 2 if pieceb wins and 0 if neither win -# Only look at first character of string -def piece_collision(piecea, pieceb) -> int: - piecea = piecea[0].lower() - pieceb = pieceb[0].lower() - if piecea == "r": - if pieceb == "s": - return 1 - elif pieceb == "p": - return 2 - elif piecea == "s": - if pieceb == "p": - return 1 - elif pieceb == "r": - return 2 - elif piecea == "p": - if pieceb == "r": - return 1 - elif pieceb == "s": - return 2 - return 0 - -# Input is the key of the piece to find a target for -# This function changes the value of the key given in the -# target dictionary to the closest enemy piece it can beat + keyWrite = "s" + str(nums) + dictPieces[keyWrite] = (piece[ROW], piece[COLUMN]) + + # parse the block object + for block in initialBlocks: + 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 + + def find_target(piece_key): - currentpos = dictpieces[piece_key] + """ + This function changes the value of the key given in the + target dictionary to the closest enemy piece it can beat + + :param piece_key: key of the piece to find a target for. We should only work with upper player's pieces + :return: null + """ + currentPos = dictPieces[piece_key] # Set the target target = "" - if piece_key[0] == "R": + if piece_key[TYPE] == "R": target = "s" - elif piece_key[0] == "S": + elif piece_key[TYPE] == "S": target = "p" - elif piece_key[0] == "P": + elif piece_key[TYPE] == "P": target = "r" - # If we haven't set a target by now, we're dealing with the wrong kind of piece + # If we haven't set a target by now, we're dealing with the lower player pieces else: return - #Now we check which target is closest - #Start with dummy information - targetpiece = "" - targetdist = 99 - for key in dictpieces: - if key[0] == target: - distance = distance_between(dictpieces[piece_key],dictpieces[key]) - if distance < targetdist: - targetpiece = key - targetdist = distance + # Now we check which target is closest + # Start with dummy information + targetPiece = "" + targetDist = MAX_DISTANCE + for key in dictPieces: + # XUAN: unfortunately i believe this logical operation will always be FALSE + # e.g: 'r' != 'r1' + if key[TYPE] == target: + distance = distance_between(dictPieces[piece_key], dictPieces[key]) + if distance < targetDist: + targetPiece = key + targetDist = distance # Now add target to dictionary - if targetdist == 99: - dicttargets[piece_key] = () + if targetDist == MAX_DISTANCE: + dictTargets[piece_key] = () else: - dicttargets[piece_key] = dictpieces[key] + # Xuan: does this 'variable' has any value? since it is out side its scope. + dictTargets[piece_key] = dictPieces[key] return - - - - - diff --git a/search/test.py b/search/test.py new file mode 100644 index 0000000000000000000000000000000000000000..1fa07dd88fddfd83e75e5a6d6bce10b177c3f40e --- /dev/null +++ b/search/test.py @@ -0,0 +1 @@ +print('r' == 'r1') \ No newline at end of file