0

I'm making in-console Battleship game in Python and I have a code that checks if the ship can fit into the list. It does not look very appealing and I'd like to simplify it into a more appealing version.

if (direction is "N" and row - size < 0) or \
  (direction is "E" and column + size > 10) or \
  (direction is "S" and row + size > 10) or \
  (direction is "W" and column - size < 0):
    print("It does not fit")

I was thinking of using the dictionary, but couldn't think of a way to use variables and maths operator (-+ <>) inside

  • 4
    Do not use `is` for equality comparisons. Use `==` (`is` checks for identity, whether two objects are the same. The fact that it works here is an implementation detail, and may break.) – Paritosh Singh Nov 22 '19 at 11:49

3 Answers3

1
if any([direction is "N" and row - size < 0, direction is "E" and column + size > 10, direction is "S" and row + size > 10, direction is "W" and column - size < 0]):
    print("It does not fit")

Sure there is a lot of improvement with your code to but this is a start

Other improvements

if any([direction == "N" and size > row, direction == "E" and column + size > 10, direction == "S" and row + size > 10, direction == "W" and size > column]):

A better way, more clear;

dir_classifier = {'N': size > row, 
'E': (column + size) > 10,
 'W': size > column,
 'S': (row + size > 10)}


if dir_classifier[direction]:
     print("It does not fit")
E.Serra
  • 1,495
  • 11
  • 14
0

Well, its not the most readable way, but i think it a cool think to notice

def is_valid(direction):
    n = ord(direction)
    bits = count_bits(n)
    result = (bits == 4) * row) + ((bits != 4) * col) + ((((n&7)==6) * -1) * size
    if (0 > result > 10):
        print('invalid')

def count_bits(n):
  n = (n & 0x5555555555555555) + ((n & 0xAAAAAAAAAAAAAAAA) >> 1)
  n = (n & 0x3333333333333333) + ((n & 0xCCCCCCCCCCCCCCCC) >> 2)
  n = (n & 0x0F0F0F0F0F0F0F0F) + ((n & 0xF0F0F0F0F0F0F0F0) >> 4)
  n = (n & 0x00FF00FF00FF00FF) + ((n & 0xFF00FF00FF00FF00) >> 8)
  n = (n & 0x0000FFFF0000FFFF) + ((n & 0xFFFF0000FFFF0000) >> 16)
  n = (n & 0x00000000FFFFFFFF) + ((n & 0xFFFFFFFF00000000) >> 32) # This last & isn't strictly necessary.
  return n

Counting bit functino from : link

Explanation

count_bits - counts the set bits of a number

S and N require to use the row element, which they both have 4 set bits in there ascii value, so it help us to determ the using of the value row or colum, it there are 4 set bits, we use the row, and if not, we use the col.

then we need to know if we want to substract the size, or adding it up, then we use (((n&7)==6) which tells as if the 3 lsb is equals to 6, which will be true for N and W

Reznik
  • 2,663
  • 1
  • 11
  • 31
-1

If possible, remove "negation" from condition. Then extract condition to a function isFit(direction, row, column, size). So it will look like this:

if isFit(direction, row, column, size):
    print('It fits!!!')
else:
    print('It does not fit')

This way it looks neat and easy to read.

Further, you can create a proper Ship class with properties like size, direction, column, row. Then it will look even better:

if isFit(ship):
    print('...')

Also, isFit can be a method of Ship class:

if ship.isFit():
    print('...')
iutinvg
  • 3,479
  • 3
  • 21
  • 18
  • Why should I remove negation? This 'if' is in function that validates input-related stuff, and therefore I'm checking if arguments do not pass the conditions. – zanstaszek9 Nov 22 '19 at 12:33
  • To make it easier to read. Only for that. With the negation it's harder to create a proper name for the function. Even adding `not` before the function name in the condition will be easier to read (in case you don't need `else` part). – iutinvg Nov 22 '19 at 13:35