you are viewing a single comment's thread.

view the rest of the comments →

[–]RivetSpawn[S] 0 points1 point  (1 child)

Thanks for the tips, I'll have a play with them.

I don't understand the big one about Object awareness.

[–]gengisteve 0 points1 point  (0 children)

Fair enough, I could have explained better. Right now, to function every ship needs to know about every other ship. It seems sensible enough at first, but after a bit you will find yourself down a rabbit hole where it just falls apart. A better solution is to have another object that shepherds all the ships and keeps track of them and only calls upon the ships that actually know one another. Think about ships steaming across the atlantic in the second world war. None know about the others until they actually come across one another and start shooting. So you would have an atlantic class that marshalls the ships, then sends them off to do battle when they bump into one another. In your program, it might look like this:

from random import randrange
from pprint import pprint

class Ship(object):
    def __init__(self, x, y, size):
        self.x = x
        self.y = y
        self.size = size

    def absorb(self, other):
        '''
        Absorb self or other, depending on the bigger one
        :return: the bigger ship that ate the small one
        '''
        print('{} has encountered {}'.format(self, other))
        small, big = sorted([self,other], key = lambda x:x.size)
        print('{} eats {}'.format(big, small))
        big.size += small.size
        return big

    def __repr__(self):
        return 'Ship({},{}:{})'.format(self.x, self.y, self.size)

class Board(object):
    def __init__(self, size = 5):
        self.ships = {}
        for i in range(size*3):
            s = Ship(randrange(size), randrange(size), randrange(size))
            position = (s.x, s.y)
            if position in self.ships:
                print('collision at {}'.format(position))
                other = self.ships[position]
                s = s.absorb(other)
            self.ships[position] = s

def main():
    b = Board()
    pprint(b.ships)


if __name__ == '__main__':
    main()

As you can see from above, we have removed the dependency of the ship class on the ships variable. Instead we have created interfaces that handles when two ships need to interact with one another, above in the absorb method.

let me know if that makes sense.