Selecting lowest position from 'array'












0












$begingroup$


My goal is to move a 'monster' (mX, mY) in a 2d grid towards the player (pX, pY). The monster can move 8 directions.



I have working code for this, but I'm very new to Python and have a strong inclination it is awful and there is faster ways to do it.



I do this by creating a 3 x 3 array around the monsters position (array slot 4), and filling it with the distance from that array position to the player. Then I check if any are lower than the monsters current distance, and if so, move the monster to it.



enter image description here



Here is my current code, apologies if it makes you puke, I'm still learning the ropes.



# get the distance between the monster and player
dist = math.hypot(pX - mX, pY - mY)

if dist > 1.5 and dist < 10:

# make an 'array' grid to store updated distances in
goto = np.full((3, 3), 10, dtype=float)

# if each position in the array passes a
# collision check, add each new distance

if collisionCheck(mID, (mX-1), (mY-1), mMap) == 0:
goto[0][0] = round(math.hypot(pX - (mX-1), pY - (mY-1)), 1)

if collisionCheck(mID, mX, (mY-1), mMap) == 0:
goto[0][1] = round(math.hypot(pX - mX, pY - (mY-1)), 1)

if collisionCheck(mID, (mX+1), (mY-1), mMap) == 0:
goto[0][2] = round(math.hypot(pX - (mX+1), pY - (mY-1)), 1)

if collisionCheck(mID, (mX-1), mY, mMap) == 0:
goto[1][0] = round(math.hypot(pX - (mX-1), pY - mY), 1)

# goto[1][1] is skipped since that is the monsters current position

if collisionCheck(mID, (mX+1), mY, mMap) == 0:
goto[1][2] = round(math.hypot(pX - (mX+1), pY - mY), 1)

if collisionCheck(mID, (mX-1), (mY+1), mMap) == 0:
goto[2][0] = round(math.hypot(pX - (mX-1), pY - (mY+1)), 1)

if collisionCheck(mID, mX, (mY+1), mMap) == 0:
goto[2][1] = round(math.hypot(pX - mX, pY - (mY+1)), 1)

if collisionCheck(mID, (mX+1), (mY+1), mMap) == 0:
goto[2][2] = round(math.hypot(pX - (mX+1), pY - (mY+1)), 1)

# get the lowest distance, and its key
lowest = goto.min()
lowestKey = goto.argmin()

# if the lowest distance is lower than monsters current position, move

if lowest < dist:
if lowestKey == 0:
newX = mX - 1
newY = mY - 1

if lowestKey == 1:
newY = mY - 1

if lowestKey == 2:
newX = mX + 1
newY = mY - 1

if lowestKey == 3:
newX = mX - 1

if lowestKey == 5:
newX = mX + 1

if lowestKey == 6:
newY = mY + 1
newX = mX - 1

if lowestKey == 7:
newY = mY + 1

if lowestKey == 8:
newX = mX + 1
newY = mY + 1


What is the cleanest, simplest, and fastest way to do what I'm doing? This is going to loop through many monsters at once!










share|improve this question









New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Could you add more description, how big is the board, is the player always in the 3x3 grid?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Is there anything the monster can collide with?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
    $endgroup$
    – Peilonrayz
    4 hours ago


















0












$begingroup$


My goal is to move a 'monster' (mX, mY) in a 2d grid towards the player (pX, pY). The monster can move 8 directions.



I have working code for this, but I'm very new to Python and have a strong inclination it is awful and there is faster ways to do it.



I do this by creating a 3 x 3 array around the monsters position (array slot 4), and filling it with the distance from that array position to the player. Then I check if any are lower than the monsters current distance, and if so, move the monster to it.



enter image description here



Here is my current code, apologies if it makes you puke, I'm still learning the ropes.



# get the distance between the monster and player
dist = math.hypot(pX - mX, pY - mY)

if dist > 1.5 and dist < 10:

# make an 'array' grid to store updated distances in
goto = np.full((3, 3), 10, dtype=float)

# if each position in the array passes a
# collision check, add each new distance

if collisionCheck(mID, (mX-1), (mY-1), mMap) == 0:
goto[0][0] = round(math.hypot(pX - (mX-1), pY - (mY-1)), 1)

if collisionCheck(mID, mX, (mY-1), mMap) == 0:
goto[0][1] = round(math.hypot(pX - mX, pY - (mY-1)), 1)

if collisionCheck(mID, (mX+1), (mY-1), mMap) == 0:
goto[0][2] = round(math.hypot(pX - (mX+1), pY - (mY-1)), 1)

if collisionCheck(mID, (mX-1), mY, mMap) == 0:
goto[1][0] = round(math.hypot(pX - (mX-1), pY - mY), 1)

# goto[1][1] is skipped since that is the monsters current position

if collisionCheck(mID, (mX+1), mY, mMap) == 0:
goto[1][2] = round(math.hypot(pX - (mX+1), pY - mY), 1)

if collisionCheck(mID, (mX-1), (mY+1), mMap) == 0:
goto[2][0] = round(math.hypot(pX - (mX-1), pY - (mY+1)), 1)

if collisionCheck(mID, mX, (mY+1), mMap) == 0:
goto[2][1] = round(math.hypot(pX - mX, pY - (mY+1)), 1)

if collisionCheck(mID, (mX+1), (mY+1), mMap) == 0:
goto[2][2] = round(math.hypot(pX - (mX+1), pY - (mY+1)), 1)

# get the lowest distance, and its key
lowest = goto.min()
lowestKey = goto.argmin()

# if the lowest distance is lower than monsters current position, move

if lowest < dist:
if lowestKey == 0:
newX = mX - 1
newY = mY - 1

if lowestKey == 1:
newY = mY - 1

if lowestKey == 2:
newX = mX + 1
newY = mY - 1

if lowestKey == 3:
newX = mX - 1

if lowestKey == 5:
newX = mX + 1

if lowestKey == 6:
newY = mY + 1
newX = mX - 1

if lowestKey == 7:
newY = mY + 1

if lowestKey == 8:
newX = mX + 1
newY = mY + 1


What is the cleanest, simplest, and fastest way to do what I'm doing? This is going to loop through many monsters at once!










share|improve this question









New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Could you add more description, how big is the board, is the player always in the 3x3 grid?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Is there anything the monster can collide with?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
    $endgroup$
    – Peilonrayz
    4 hours ago
















0












0








0





$begingroup$


My goal is to move a 'monster' (mX, mY) in a 2d grid towards the player (pX, pY). The monster can move 8 directions.



I have working code for this, but I'm very new to Python and have a strong inclination it is awful and there is faster ways to do it.



I do this by creating a 3 x 3 array around the monsters position (array slot 4), and filling it with the distance from that array position to the player. Then I check if any are lower than the monsters current distance, and if so, move the monster to it.



enter image description here



Here is my current code, apologies if it makes you puke, I'm still learning the ropes.



# get the distance between the monster and player
dist = math.hypot(pX - mX, pY - mY)

if dist > 1.5 and dist < 10:

# make an 'array' grid to store updated distances in
goto = np.full((3, 3), 10, dtype=float)

# if each position in the array passes a
# collision check, add each new distance

if collisionCheck(mID, (mX-1), (mY-1), mMap) == 0:
goto[0][0] = round(math.hypot(pX - (mX-1), pY - (mY-1)), 1)

if collisionCheck(mID, mX, (mY-1), mMap) == 0:
goto[0][1] = round(math.hypot(pX - mX, pY - (mY-1)), 1)

if collisionCheck(mID, (mX+1), (mY-1), mMap) == 0:
goto[0][2] = round(math.hypot(pX - (mX+1), pY - (mY-1)), 1)

if collisionCheck(mID, (mX-1), mY, mMap) == 0:
goto[1][0] = round(math.hypot(pX - (mX-1), pY - mY), 1)

# goto[1][1] is skipped since that is the monsters current position

if collisionCheck(mID, (mX+1), mY, mMap) == 0:
goto[1][2] = round(math.hypot(pX - (mX+1), pY - mY), 1)

if collisionCheck(mID, (mX-1), (mY+1), mMap) == 0:
goto[2][0] = round(math.hypot(pX - (mX-1), pY - (mY+1)), 1)

if collisionCheck(mID, mX, (mY+1), mMap) == 0:
goto[2][1] = round(math.hypot(pX - mX, pY - (mY+1)), 1)

if collisionCheck(mID, (mX+1), (mY+1), mMap) == 0:
goto[2][2] = round(math.hypot(pX - (mX+1), pY - (mY+1)), 1)

# get the lowest distance, and its key
lowest = goto.min()
lowestKey = goto.argmin()

# if the lowest distance is lower than monsters current position, move

if lowest < dist:
if lowestKey == 0:
newX = mX - 1
newY = mY - 1

if lowestKey == 1:
newY = mY - 1

if lowestKey == 2:
newX = mX + 1
newY = mY - 1

if lowestKey == 3:
newX = mX - 1

if lowestKey == 5:
newX = mX + 1

if lowestKey == 6:
newY = mY + 1
newX = mX - 1

if lowestKey == 7:
newY = mY + 1

if lowestKey == 8:
newX = mX + 1
newY = mY + 1


What is the cleanest, simplest, and fastest way to do what I'm doing? This is going to loop through many monsters at once!










share|improve this question









New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




My goal is to move a 'monster' (mX, mY) in a 2d grid towards the player (pX, pY). The monster can move 8 directions.



I have working code for this, but I'm very new to Python and have a strong inclination it is awful and there is faster ways to do it.



I do this by creating a 3 x 3 array around the monsters position (array slot 4), and filling it with the distance from that array position to the player. Then I check if any are lower than the monsters current distance, and if so, move the monster to it.



enter image description here



Here is my current code, apologies if it makes you puke, I'm still learning the ropes.



# get the distance between the monster and player
dist = math.hypot(pX - mX, pY - mY)

if dist > 1.5 and dist < 10:

# make an 'array' grid to store updated distances in
goto = np.full((3, 3), 10, dtype=float)

# if each position in the array passes a
# collision check, add each new distance

if collisionCheck(mID, (mX-1), (mY-1), mMap) == 0:
goto[0][0] = round(math.hypot(pX - (mX-1), pY - (mY-1)), 1)

if collisionCheck(mID, mX, (mY-1), mMap) == 0:
goto[0][1] = round(math.hypot(pX - mX, pY - (mY-1)), 1)

if collisionCheck(mID, (mX+1), (mY-1), mMap) == 0:
goto[0][2] = round(math.hypot(pX - (mX+1), pY - (mY-1)), 1)

if collisionCheck(mID, (mX-1), mY, mMap) == 0:
goto[1][0] = round(math.hypot(pX - (mX-1), pY - mY), 1)

# goto[1][1] is skipped since that is the monsters current position

if collisionCheck(mID, (mX+1), mY, mMap) == 0:
goto[1][2] = round(math.hypot(pX - (mX+1), pY - mY), 1)

if collisionCheck(mID, (mX-1), (mY+1), mMap) == 0:
goto[2][0] = round(math.hypot(pX - (mX-1), pY - (mY+1)), 1)

if collisionCheck(mID, mX, (mY+1), mMap) == 0:
goto[2][1] = round(math.hypot(pX - mX, pY - (mY+1)), 1)

if collisionCheck(mID, (mX+1), (mY+1), mMap) == 0:
goto[2][2] = round(math.hypot(pX - (mX+1), pY - (mY+1)), 1)

# get the lowest distance, and its key
lowest = goto.min()
lowestKey = goto.argmin()

# if the lowest distance is lower than monsters current position, move

if lowest < dist:
if lowestKey == 0:
newX = mX - 1
newY = mY - 1

if lowestKey == 1:
newY = mY - 1

if lowestKey == 2:
newX = mX + 1
newY = mY - 1

if lowestKey == 3:
newX = mX - 1

if lowestKey == 5:
newX = mX + 1

if lowestKey == 6:
newY = mY + 1
newX = mX - 1

if lowestKey == 7:
newY = mY + 1

if lowestKey == 8:
newX = mX + 1
newY = mY + 1


What is the cleanest, simplest, and fastest way to do what I'm doing? This is going to loop through many monsters at once!







python array






share|improve this question









New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 13 mins ago









Jamal

30.3k11119227




30.3k11119227






New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 5 hours ago









user1022585user1022585

1011




1011




New contributor




user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






user1022585 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • $begingroup$
    Could you add more description, how big is the board, is the player always in the 3x3 grid?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Is there anything the monster can collide with?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
    $endgroup$
    – Peilonrayz
    4 hours ago




















  • $begingroup$
    Could you add more description, how big is the board, is the player always in the 3x3 grid?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Is there anything the monster can collide with?
    $endgroup$
    – Peilonrayz
    5 hours ago










  • $begingroup$
    The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
    $endgroup$
    – user1022585
    5 hours ago










  • $begingroup$
    Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
    $endgroup$
    – Peilonrayz
    4 hours ago


















$begingroup$
Could you add more description, how big is the board, is the player always in the 3x3 grid?
$endgroup$
– Peilonrayz
5 hours ago




$begingroup$
Could you add more description, how big is the board, is the player always in the 3x3 grid?
$endgroup$
– Peilonrayz
5 hours ago












$begingroup$
The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
$endgroup$
– user1022585
5 hours ago




$begingroup$
The board could be any size, this just creates a temporary array around the monster to decide which square it will move to
$endgroup$
– user1022585
5 hours ago












$begingroup$
Is there anything the monster can collide with?
$endgroup$
– Peilonrayz
5 hours ago




$begingroup$
Is there anything the monster can collide with?
$endgroup$
– Peilonrayz
5 hours ago












$begingroup$
The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
$endgroup$
– user1022585
5 hours ago




$begingroup$
The collisioncheck() routine returns a 0 or a 1. Its an external def that checks if any other monsters, players or walls are at that position.
$endgroup$
– user1022585
5 hours ago












$begingroup$
Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
$endgroup$
– Peilonrayz
4 hours ago






$begingroup$
Hopefully I've not messed up my math when converting to this comment, but you can use: d = math.degrees(math.atan((pY - mY) / (pX - mY))) and 'N NE E SE S SW W NW'.split()[int((d + 22.5) // 45)] to know which direction you want to go if there are no collisions.
$endgroup$
– Peilonrayz
4 hours ago












1 Answer
1






active

oldest

votes


















1












$begingroup$

Some thoughts from a non-game-developer:




  • The second and subsequent if lowestKey should use elif to short-circuit the evaluation when it finds a match.

  • I believe algorithms such as A* (A-star) are very well suited to find the shortest path between two points on a 2-dimensional map.

  • Running this code through a linter such as flake8 will show how to make your code more pythonic.






share|improve this answer









$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });






    user1022585 is a new contributor. Be nice, and check out our Code of Conduct.










    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213762%2fselecting-lowest-position-from-array%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1












    $begingroup$

    Some thoughts from a non-game-developer:




    • The second and subsequent if lowestKey should use elif to short-circuit the evaluation when it finds a match.

    • I believe algorithms such as A* (A-star) are very well suited to find the shortest path between two points on a 2-dimensional map.

    • Running this code through a linter such as flake8 will show how to make your code more pythonic.






    share|improve this answer









    $endgroup$


















      1












      $begingroup$

      Some thoughts from a non-game-developer:




      • The second and subsequent if lowestKey should use elif to short-circuit the evaluation when it finds a match.

      • I believe algorithms such as A* (A-star) are very well suited to find the shortest path between two points on a 2-dimensional map.

      • Running this code through a linter such as flake8 will show how to make your code more pythonic.






      share|improve this answer









      $endgroup$
















        1












        1








        1





        $begingroup$

        Some thoughts from a non-game-developer:




        • The second and subsequent if lowestKey should use elif to short-circuit the evaluation when it finds a match.

        • I believe algorithms such as A* (A-star) are very well suited to find the shortest path between two points on a 2-dimensional map.

        • Running this code through a linter such as flake8 will show how to make your code more pythonic.






        share|improve this answer









        $endgroup$



        Some thoughts from a non-game-developer:




        • The second and subsequent if lowestKey should use elif to short-circuit the evaluation when it finds a match.

        • I believe algorithms such as A* (A-star) are very well suited to find the shortest path between two points on a 2-dimensional map.

        • Running this code through a linter such as flake8 will show how to make your code more pythonic.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 5 hours ago









        l0b0l0b0

        4,4141023




        4,4141023






















            user1022585 is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            user1022585 is a new contributor. Be nice, and check out our Code of Conduct.













            user1022585 is a new contributor. Be nice, and check out our Code of Conduct.












            user1022585 is a new contributor. Be nice, and check out our Code of Conduct.
















            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f213762%2fselecting-lowest-position-from-array%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            Refactoring coordinates for Minecraft Pi buildings written in Python