3

I am creating a battleships game and would like to check the positions around the players targeted position to check if any ships are located there,i.e.

!(https://i.stack.imgur.com/TIB7R.jpg)

on this board the program would check positions (2,0), (1,1), (2,2) and (3,1) for any ships, if there were any present the subroutine would return True, and if not it would return False.

So this is my current code:

def RadarScan(Board, Ships, R, C):
    around = [[C, R - 1], [C + 1, R], [C, R + 1], [C - 1, R]]
    for i in around:
        for x in range(2):
            if int(i[x]) > 9 or int(i[x]) < 0:
                around.remove(i)
    near = False
    for i in range(len(around)):
        if Board[around[i][0]][around[i][1]] == "-" or "m" or "h":
            continue
        else:
            near = True
            break
    if near == True:
        return True
    else:
        return False

When checking if the positions around the targeted one are on the board, I use a for loop to increment through the list around, which contains all the surrounding positions, however let's say the second position of around was (10,9), the for loop would remove this position because its not on the board and then increment to the next position in around, i.e. the third position, however there are only the original positions 1, 3, and 4 left in around so it would skip checking the original position 3 and instead go straight to the original position 4.

(Sorry if that's a bit confusing)

So my question is, is there something I can add beneath 'around.remove(i)' that moves back the increment of the for loop 'for i in around' by 1?

0isab
  • 67
  • 2
  • 7
  • Why at all do you use the first nested for loop? Just do the check <0 and >9 when adding the elements to your around list? Then you only have valid items in the list and you do not take further care about this – simirimia Oct 26 '19 at 07:04
  • @simirimia , how would I go about doing that? – 0isab Oct 26 '19 at 07:08
  • Fundamentally, the problem you are trying to solve by "moving the iterator back one" is the one caused by trying to remove items from a list while iterating over it. – Karl Knechtel Oct 26 '19 at 08:01
  • Also, I don't know where you learned to write `for i in range(len(...))`, but don't do that, and stop listening to whoever told you to do it. Just iterate directly over the elements. – Karl Knechtel Oct 26 '19 at 08:03

3 Answers3

1

Modifying the item you are iterating over does not work.

I don’t know why you have int(i[x]). Do you expect R or C not to be an integer?

The Board[][] == "-" or "m" or "h" is always True because "m" or "h" is always True

Your loop is better written as:

for x, y in around:
    if x in range(10) and y in range(10):
        if Board[x][y] not in "-mh":
            return True
return False
AJNeufeld
  • 8,526
  • 1
  • 25
  • 44
0

One approach might be to have a manual index, if I'm understanding your question correctly:

def RadarScan(Board, Ships, R, C):
    around = [[C, R - 1], [C + 1, R], [C, R + 1], [C - 1, R]]
    index = 0
    for i in range(len(around)):
        index += 1
        for x in range(2):
            if int(around[index][x]) > 9 or int(around[index][x]) < 0:
                around.remove(around[index])
                index -= 1

    near = False
    for i in range(len(around)):
        if Board[around[i][0]][around[i][1]] == "-" or "m" or "h":
            continue
        else:
            near = True
            break
    if near == True:
        return True
    else:
        return False
Ryan
  • 1,032
  • 1
  • 10
  • 23
0

For loops can't do this. Use while loops:

def RadarScan(Board, Ships, R, C):
    around = [[C, R - 1], [C + 1, R], [C, R + 1], [C - 1, R]]
    c= 0
    while c < len(around)-1:
        i = around[c]
        for x in range(2):
            if int(i[x]) > 9 or int(i[x]) < 0:
                around.remove(i)
                c-= 1
        c += 1
    near = False
    for i in range(len(around)):
        if Board[around[i][0]][around[i][1]] == "-" or "m" or "h":
            continue
        else:
            near = True
            break
    if near == True:
        return True
    else:
        return False

This should do the trick

Sid
  • 2,174
  • 1
  • 13
  • 29
  • c is not incremented here, however when i add an else statement after 'c -= 1' which increments c by 1, I get an error message where an invalid position has got through (I'm using (9,9) as the targeted position since it has two off-board values) – 0isab Oct 26 '19 at 07:20