"Battleship" style game

S

Shawn Milochik

I started learning Java for fun, and the first project assignment in
the book is to create a game like "Battleship." So, of course, I wrote
it in Python first, just for fun. I haven't had the time to look up
all the Java syntax.

So, here it is, fully functional. I thought I'd throw it out there and
see if anyone would like to offer any useful tips. I'm not claiming
it's bulletproof, but it works. I just kind of came up with all the
methods off of the top of my head, so if anyone has any suggestions
for more elegant or efficient code, please let me know.

http://shawnmilo.com/ships/

Thanks,
Shawn
 
M

Marco Mariani

Shawn said:
> I'm not claiming it's bulletproof, but it works. I just kind of came up with all the
methods off of the top of my head, so if anyone has any suggestions
for more elegant or efficient code, please let me know.

Yes it's in Python alright, but it's not Pythonese yet. You could try
avoiding the getter/setter stuff, and camelCase method naming, things
like that, for a start.
 
S

Shawn Milochik

Yes it's in Python alright, but it's not Pythonese yet. You could try
avoiding the getter/setter stuff, and camelCase method naming, things like
that, for a start.


What do you mean avoiding the getter/setter stuff? If I understand
correctly, you're saying to directly access the attributes, which I
specifically want to avoid because I may want to enforce some rules
(such as not changing a ship length after it's created).

The camel-case thing I get -- I use that and this_type quite a bit,
probably because of the inconsistency of the languages I use
regularly, and standards at work and conventions in my hobby
programming.
 
S

Steve Holden

Shawn said:
What do you mean avoiding the getter/setter stuff? If I understand
correctly, you're saying to directly access the attributes, which I
specifically want to avoid because I may want to enforce some rules
(such as not changing a ship length after it's created).
If you wanted to enforce those restrictions you could just turn
attributes into properties.
The camel-case thing I get -- I use that and this_type quite a bit,
probably because of the inconsistency of the languages I use
regularly, and standards at work and conventions in my hobby
programming.

PEP 008 is the usual style recommendation.

regards
Steve
 
G

Gabriel Genellina

What do you mean avoiding the getter/setter stuff? If I understand
correctly, you're saying to directly access the attributes, which I
specifically want to avoid because I may want to enforce some rules
(such as not changing a ship length after it's created).

I think Marco Mariani was suggesting something like this:

class Ship(object):

def __init__(self, length):
self._length = length

def get_length(self):
return self._length
length = property(get_length) # a read only property
 
D

Diez B. Roggisch

Shawn said:
Thanks. I wasn't aware of the property() function, but I read up on
it. I modified the Vessels.py file, but not the board file (except
where necessary to handle the changes made to Vessels. Is this better?

http://shawnmilo.com/ships/ships2/


Not really. The point about properties is that you *can* make attribute
access trigger getter or setter code.

But not that you do unless there is an actual reason for that. The way
you do it now is simply introducing clutter, without benefit. Your class
would be half the current size - without loss of functionality.



Diez
 
S

Shawn Milochik

Not really. The point about properties is that you *can* make attribute
access trigger getter or setter code.

But not that you do unless there is an actual reason for that. The way you
do it now is simply introducing clutter, without benefit. Your class would
be half the current size - without loss of functionality.



Diez

It is true that it would be fewer lines of code with the same
functionality, but it's better practice to have that framework in
place so that any changes made in the future wouldn't break any of the
code accessing my class. Obviously this is a fairly simple game that
has a fixed set of rules, but I'm trying to cultivate good habits, and
I don't think that doing it this way is anti-Pythonic.

Unless, of course, anything I said is wrong, which is always possible.
If I'm missing a bigger-picture idea, I'd like to know about it.

Thanks,
Shawn
 
S

Steve Holden

Shawn said:
It is true that it would be fewer lines of code with the same
functionality, but it's better practice to have that framework in
place so that any changes made in the future wouldn't break any of the
code accessing my class. Obviously this is a fairly simple game that
has a fixed set of rules, but I'm trying to cultivate good habits, and
I don't think that doing it this way is anti-Pythonic.

Unless, of course, anything I said is wrong, which is always possible.
If I'm missing a bigger-picture idea, I'd like to know about it.
The point of using property() is that you can start out using attribute
access on its own (which is the standard Python way to do things:
getters and setters are seen by most as redundant code).

Once you need programmed access on read and/or write, leave the client
code (the code that accesses the attributes) as it is, but turn the
attributes into properties so that the functions are invoked
automatically on attribute-style access.

So I believe what Diez was saying is that by using properties in your
existing code you are getting the worst of both worlds - unnecessarily
complex objects, and code that uses those objects by calling methods
when it could be accessing attributes (or properties - depending on the
implementation). At least this is true of your Ship test code.

regards
Steve
 
D

Diez B. Roggisch

Shawn said:
It is true that it would be fewer lines of code with the same
functionality, but it's better practice to have that framework in
place so that any changes made in the future wouldn't break any of the
code accessing my class. Obviously this is a fairly simple game that
has a fixed set of rules, but I'm trying to cultivate good habits, and
I don't think that doing it this way is anti-Pythonic.

Unless, of course, anything I said is wrong, which is always possible.
If I'm missing a bigger-picture idea, I'd like to know about it.

You miss that Java has no properties, and thus forces prorgammers to
wrap all attribute-access into getter/setters - just in case one wants
something other than pure attribute access in some distant future to come.

In Python this is not needed. If something starts as an attribute, and
then evolves so that it needs more complex logic when being accessed,
you introduce a property of the same name.


Don't waste time coding for a future you can't even pretend to know. Do
what is needed to solve the actual problem.


Diez
 
Z

Zvezdan Petkovic

It is true that it would be fewer lines of code with the same
functionality, but it's better practice to have that framework in
place so that any changes made in the future wouldn't break any of the
code accessing my class. Obviously this is a fairly simple game that
has a fixed set of rules, but I'm trying to cultivate good habits, and
I don't think that doing it this way is anti-Pythonic.

Well, they are trying to help you with the best practices.
You offered the code for review and they reviewed it.
Whether you'll accept what they say or deny it is your call, of course.

FWIW, the Pythonic way would be:
.... def __init__(self, length):
.... self._length = length
.... @property
.... def length(self):
.... return self._length
....Traceback (most recent call last):

Using @property decorator makes a read-only property. If you need a
read/write property there are several ways to define setter and
deleter methods with or without decorators.

I hope you see that

x = s.length
s.position = y

is a completely different style than

x = s.get_length()
s.set_position(y)

Most of the people who program in Python prefer the first style above.
 
L

Lie

What do you mean avoiding the getter/setter stuff? If I understand
correctly, you're saying to directly access the attributes, which I
specifically want to avoid because I may want to enforce some rules
(such as not changing a ship length after it's created).

I just want to add the note that since you're planning to move the
code to Java, although you should avoid getter and setter in python
(since it's redundant because of property), you should use getter and
setter in the Java version because it is the best practice in Java.
 
F

Falstaff

Well, they are trying to help you with the best practices.
You offered the code for review and they reviewed it.
Whether you'll accept what they say or deny it is your call, of course.

FWIW, the Pythonic way would be:

 >>> class Ship(object):
...     def __init__(self, length):
...         self._length = length
...     @property
...     def length(self):
...         return self._length
...
 >>> s = Ship(5)
 >>> s.length
5
 >>> # notice how the property is read-only which is what you wanted
 >>> s.length = 7
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
 >>> ^D

Using @property decorator makes a read-only property.  If you need a  
read/write property there are several ways to define setter and  
deleter methods with or without decorators.

I hope you see that

        x = s.length
        s.position = y

is a completely different style than

        x = s.get_length()
        s.set_position(y)

Most of the people who program in Python prefer the first style above.

I certainly didn't expect this thread to end like this. Sure, most
Python people prefer properties over straight accessors, but that is
just reworking the methods in the class, and not the reworking the
object model itself. Thus stopping at 'use properties' misses out on
the one, true promised land of data encapsulation. See e.g.

"Why getter and setter methods are evil"
...Don't ask for the information you need to do the work;
ask the object that has the information to do the work for you...
Allen Holub
http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?page=3

or any other number of OO references on data encapsulation. This can
even apply to GUI objects now - rather than having the GUI object pull
data from the model object, you have the model draw itself w/ a
draw_myself method, perhaps implemented by a handler.

That goes for Java too, AFAIK.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,983
Messages
2,570,187
Members
46,748
Latest member
MerryWhitm

Latest Threads

Top