0

I am currently working on a game that enables users to place pieces onto a grid. Once a piece has been placed on the grid, there should be some functionality that prevents further pieces from being added in the same grid positions. Below is what I have designed so far for this feature.

The issue I am having is that the function always returns false, thereby enabling pieces to be continually added into the same grid positions, even if there is a ship placed. start and end are both integer values and direction is either horizontal or vertical:

    const checkIfShipPresent = (direction, start, end) => {
        if (direction === 'horizontal') {
            for (let i = start; i <= end; i++) {
                shipYard.forEach((ship => {
                    if (ship.position.includes(i)) {
                        return true;
                    }
                }))
            };
            return false;

The below code illustrates how I have been attempting to test the function:

    const checkIfShipPresent = (direction, start, end) => {
        if (direction === 'horizontal') {
            for (let i = start; i <= end; i++) {
                shipYard.forEach((ship => {
                    console.log(ship.position)
                    console.log(i)
                    console.log(ship.position.includes(i))
                    if (ship.position.includes(i)) {
                        console.log("triggered")
                        return true;
                    }
                }))
            };
            console.log("firing")
            return false;

Here is the associated console log results (with a ship placed at grid positions [0,1,2,3,4] and clicking on cell 0):

gameboardFactory.js:71 (5) [0, 1, 2, 3, 4]
gameboardFactory.js:72 0
gameboardFactory.js:73 true
gameboardFactory.js:75 triggered
gameboardFactory.js:71 (5) [0, 1, 2, 3, 4]
gameboardFactory.js:72 1
gameboardFactory.js:73 true
gameboardFactory.js:75 triggered
gameboardFactory.js:71 (5) [0, 1, 2, 3, 4]
gameboardFactory.js:72 2
gameboardFactory.js:73 true
gameboardFactory.js:75 triggered
gameboardFactory.js:71 (5) [0, 1, 2, 3, 4]
gameboardFactory.js:72 3
gameboardFactory.js:73 true
gameboardFactory.js:75 triggered
gameboardFactory.js:71 (5) [0, 1, 2, 3, 4]
gameboardFactory.js:72 4
gameboardFactory.js:73 true
gameboardFactory.js:75 triggered
gameboardFactory.js:80 firing

I need the function to return true if there is a ship present, but as you can see it doesn't ever break out of the loop and consequently will always return false.

4
  • 3
    the return true is from the function inside the forEach (which ignores its return value) - you're not actually returning from the checkIfShipPresent function Commented Mar 17, 2021 at 20:27
  • 1
    Consider using const foundTarget = shipYard.some(ship => { ... }) -- return true; will now break out of the loop and propagate to foundTarget, which you can test and return. Commented Mar 17, 2021 at 20:30
  • 3
    BTW, forEach never stops even if you return. Commented Mar 17, 2021 at 20:31
  • 1
    Does this answer your question? What does `return` keyword mean inside `forEach` function? Commented Mar 17, 2021 at 20:34

1 Answer 1

3

Look closely again at this section of your code - particularly the return true;:

for (let i = start; i <= end; i++) {
    shipYard.forEach((ship => {
        if (ship.position.includes(i)) {
            return true;
        }
    }))
};
return false;

return returns from - and exits - the function it's inside. Which here is the anonymous arrow function passed to the forEach method. Note that forEach actually ignores any return value of the callback passed to it - it's only ever useful for any side effects of the function passed to it.

If you wish to return true from your wider function when the if condition holds, you should use a standard for loop instead of forEach. This doesn't involve any functions, so return will do as you want:

for (let i = start; i <= end; i++) {
    for (const ship of shipYard) {
        if (ship.position.includes(i)) {
            return true;
        }
    }))
};
return false;

(I've used the more concise for ... of loop form, but a regular for (let j = 0; j < shipYard.length; j++) style loop would also work fine.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.