Reply to topic  [ 64 posts ]  Go to page 1, 2, 3, 4, 5  Next
OOP problems 
Author Message
Spends far too much time on here
User avatar

Joined: Thu Apr 23, 2009 11:36 pm
Posts: 3527
Location: Portsmouth
Reply with quote
Hello Java friends. I was going to post in the previous Java thread, but it seems that came to a sad end. :?

Well, I've got a really foggy head right now from thinking about OOP and Java. I'm not sure if my problem is with Java or OOP, but I suspect it's OOP.

Basically - I'm writing a chess application, and I think I'm getting in a muddle by trying to apply procedural programming methods to OOP.

What I've tried to code is a 2D array of type "Piece" (ie chess piece ;) )

Code:
public class Piece {
   char display; // character code to display to the user
   boolean colourIsWhite;
   
   public char getName() {
      return display;
   }
   
   public void setColour(boolean newval)
      { // changes value of colourIsWhite
         colourIsWhite = newval;
      }
}


I have a number of classes extending "Piece" - Pawn, Rook, Queen etc and one called Empty for an empty square.

Code:
public class Pawn extends Piece {
   
   public Pawn(boolean setColour, char name) {   
      display = name;
      
      colourIsWhite = setColour;
   }
}


The idea is that these subclasses will be stored in the 2D array which represents the board. The problem is, that it has the type "Piece"

The first question I'm struggling to find an answer to is can an array of type "Piece" store references to objects of type Pawn, Rook, Empty etc?

My code currently creates the array, and populates it with 'Empty' pieces. This compiles fine, which makes me think perhaps the Piece type array is able to store references to objects of Empty type.

However, when I try to access the objects that I think are stored in the array I get a NullPointerException, which makes me think it never stored the object references in the first place.

I hope I've made my problem clear - and hope somebody will be able to give me a pointer or two.

_________________
Image


Thu Jan 28, 2010 9:49 pm
Profile
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 9:40 pm
Posts: 5288
Location: ln -s /London ~
Reply with quote
Nick wrote:
The first question I'm struggling to find an answer to is can an array of type "Piece" store references to objects of type Pawn, Rook, Empty etc?

Yes.

I haven't used Java enough in the last two years to remember how it actually works on a nitty-gritty level to answer your second question. Sorry.

_________________
timark_uk wrote:
Gay sex is better than no sex

timark_uk wrote:
Edward Armitage is Awesome. Yes, that's right. Awesome with a A.


Thu Jan 28, 2010 9:59 pm
Profile
Spends far too much time on here
User avatar

Joined: Thu Apr 23, 2009 11:36 pm
Posts: 3527
Location: Portsmouth
Reply with quote
EddArmitage wrote:
Nick wrote:
The first question I'm struggling to find an answer to is can an array of type "Piece" store references to objects of type Pawn, Rook, Empty etc?

Yes.


Thank goodness for that!

I'm really not very good at this OOP stuff and spent ages doing UML for it, under the impression I could code it that way.

I was starting to think it might be back to the drawing board!! :o

Sometimes it's hard to tell whether what you are trying to is possible but not done properly, or just impossible. And I find most of the compiler messages beyond cryptic! :lol:

Quote:
I haven't used Java enough in the last two years to remember how it actually works on a nitty-gritty level to answer your second question. Sorry.


Not to worry, I'll keep Googling! :P

And hoping someone else posts with details ;) *cough* Oli *cough*

_________________
Image


Thu Jan 28, 2010 10:05 pm
Profile
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Hmm...

What type of array are you storing the objects in?

Personally I don't use anything but the ArrayList class for storing objects. It can take any object and has no predefined size so you can access, add and remove objects from anywhere in the ArrayList. You also do not have to instantiate the object to a name before storing it.

i.e.
Code:
ArrayList pieces = new ArrayList();

pieces.add(new Pawn(true,"pawn"));


BTW, I am not sure entirely of the cause of your error so I am only showing you how I might store these objects to see if it helps at all.

In order to then access your pieces you would use something like.

Code:
Piece miscPiece;
Class unknownClass;
miscPiece = (Piece) pieces.get(x);
unknownClass = miscPiece.getClass();
if(unknownClass.getName() == "Pawn")
{
//cast to Pawn class and do something with it.
}


I realise you're doing this through a 2D array set up so you would need more complex code to get a x, y reference for a piece but that's how I'd store and retrieve the pieces.

I hope this helps?

Let me know if I've missed the point completely :D (wouldn't be the first time).

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Last edited by Fogmeister on Thu Jan 28, 2010 10:35 pm, edited 2 times in total.



Thu Jan 28, 2010 10:20 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Nick wrote:
*cough* Oli *cough*

Where is the smug smiley? :D

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 10:23 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 6:36 pm
Posts: 5150
Location: /dev/tty0
Reply with quote
Fogmeister wrote:
Hmm...

What type of array are you storing the objects in?

Personally I don't use anything but the ArrayList class for storing objects. It can take any object and has no predefined size so you can access, add and remove objects from anywhere in the ArrayList. You also do not have to instantiate the object to a name before storing it.


A Vector will do the same but is thread safe, so get into the habit of using that. I've gotta run. I'll try to answer questions tomorrow if no one else has :)


Thu Jan 28, 2010 10:30 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
I knew there was another way of getting the class of the object!

You can also use...

Code:
Piece miscPiece;
miscPiece = (Piece) pieces.get(x);

if(miscPiece instanceof Pawn)
{
//cast to Pawn class and do something with it.
}

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 10:33 pm
Profile WWW
Spends far too much time on here
User avatar

Joined: Thu Apr 23, 2009 11:36 pm
Posts: 3527
Location: Portsmouth
Reply with quote
Thanks for the replies guys. Oli in particular ;)

Fogmeister wrote:
What type of array are you storing the objects in?


It's a static array defined like this:
Code:
static Piece[][] boardSquares;

I hope that answers your question???

Quote:
Personally I don't use anything but the ArrayList class for storing objects. It can take any object and has no predefined size so you can access, add and remove objects from anywhere in the ArrayList.


I've read quite a bit around the 'net to do with ArrayLists, but thought it might be best to stick to what I thought I knew! :oops:

Quote:
You also do not have to instantiate the object to a name before storing it.
Code:
ArrayList pieces = new ArrayList();

pieces.add(new Pawn());


Hmmm, I don't quite understand this. By using the word 'new' are you not instantiating the object? I was under the impression that the word 'new' was the trigger for the constructor? Surely if the constructor has exectued, the object is instantiated?

Right now I'm doing it this way:
Code:
boardSquares[1][i] = new Pawn( true, 'P' ); //loop through the second row to add a row of white pawns


Quote:
BTW, I am not sure entirely of the cause of your error so I am only showing you how I might store these objects to see if it helps at all.


Thanks. :)

I was considering ArrayList because it would make it easier to deal with a Pawn reaching the end of the board and becoming a Queen. Right now though, that's the least of my problems!!

Quote:
In order to then access your pieces you would use something like.

Code:
Piece miscPiece;
Class unknownClass;
miscPiece = pieces.get(x);
unknownClass = miscPiece.getClass();
if(unknownClass.getName() == "Pawn")
{
//cast to Pawn class and do something with it.
}


Hmm, that's all very alien to me, but just reading it through now it seems that objects are stored in the ArrayList pieces, without actually knowing what type of object they are, and their type is found later??.

Quote:
I realise you're doing this through a 2D array set up so you would need more complex code to get a x, y reference for a piece but that's how I'd store and retrieve the pieces.


My initial thought (and the way I was thinking when I created the UML and class diagrams etc) was "oooh a chess board is a perfect 2D array. I can have an element for each square on the board, and a square's element can store a reference to the piece object that is sat on it"

Having done all the planning and sitting down to start coding, I was beginning to wonder if that approach was even likely to work.

What are your thoughts?

_________________
Image


Thu Jan 28, 2010 10:37 pm
Profile
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Nick wrote:
Quote:
You also do not have to instantiate the object to a name before storing it.
Code:
ArrayList pieces = new ArrayList();

pieces.add(new Pawn());


Hmmm, I don't quite understand this. By using the word 'new' are you not instantiating the object? I was under the impression that the word 'new' was the trigger for the constructor? Surely if the constructor has exectued, the object is instantiated?

Sorry, I thought that was a bit vague but never went back to change it.

A lot of people I have seen the code of will do something like...

Code:
ArrayList pieces = new ArrayList();
Piece myPiece = new Pawn(true, "pawn");
pieces.add(myPiece);


I just meant that you don't have to go through the middle step. TBH I haven't got much experience with arrays as I came across ArrayLists first and stuck with them.

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 10:41 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 9:40 pm
Posts: 5288
Location: ln -s /London ~
Reply with quote
Nick wrote:
Hmm, that's all very alien to me, but just reading it through now it seems that objects are stored in the ArrayList pieces, without actually knowing what type of object they are, and their type is found later???

Presactly! Once in the array you don't know what subclass of piece any of the pieces are. Therefore, Oli is proposing, when retrieving them you use the instanceof method to work out what type of piece it is. Personally I would just overide all the methods of piece (Make it abstract) and then not worry about what the type of it is, as it will always do the right thing when you call, for example, a method listing all possible squares it can move to.

_________________
timark_uk wrote:
Gay sex is better than no sex

timark_uk wrote:
Edward Armitage is Awesome. Yes, that's right. Awesome with a A.


Thu Jan 28, 2010 10:44 pm
Profile
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Nick wrote:
Quote:
In order to then access your pieces you would use something like.

Code:
Piece miscPiece;
Class unknownClass;
miscPiece = (Piece) pieces.get(x);
unknownClass = miscPiece.getClass();
if(unknownClass.getName() == "Pawn")
{
//cast to Pawn class and do something with it.
}


Hmm, that's all very alien to me, but just reading it through now it seems that objects are stored in the ArrayList pieces, without actually knowing what type of object they are, and their type is found later??

That's true, objects stored in an ArrayList are stored purely as instances of Object. They need to be cast into their type in order to get them out and use them, but even with an array of the type you are using you can still only ever know that it's a Piece. You would still have to probe it further to ask it what type of Piece it is surely?

Quote:
Quote:
I realise you're doing this through a 2D array set up so you would need more complex code to get a x, y reference for a piece but that's how I'd store and retrieve the pieces.


My initial thought (and the way I was thinking when I created the UML and class diagrams etc) was "oooh a chess board is a perfect 2D array. I can have an element for each square on the board, and a square's element can store a reference to the piece object that is sat on it"

Having done all the planning and sitting down to start coding, I was beginning to wonder if that approach was even likely to work.

What are your thoughts?

Definitely stay with the 2D array. It is something I have thought about writing myself a number of times but never got round to. However, whenever I have started jotting things down on paper the only way I can see it working is to use 2D arrays. I wrote a path finding program that would find it's way around a maze and used 2D arrays to get that working.

One thing to say with 2D arrays and stuff (that I found anyway) is setting it up initially is a PITA but once it's set up you can write a couple of methods to do all the complex stuff then it makes working with them a hell of a lot easier.

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 10:51 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 9:40 pm
Posts: 5288
Location: ln -s /London ~
Reply with quote
Fogmeister wrote:
They need to be cast into their type in order to get them out and use them, but even with an array of the type you are using you can still only ever know that it's a Piece. You would still have to probe it further to ask it what type of Piece it is surely?

I'd go for just overriding methods, and design the classes such that this can be the case. Have one method to output all possible target-squares given its current position. Actually, do you need many other methods? It's late and I can't think.

_________________
timark_uk wrote:
Gay sex is better than no sex

timark_uk wrote:
Edward Armitage is Awesome. Yes, that's right. Awesome with a A.


Thu Jan 28, 2010 11:01 pm
Profile
Spends far too much time on here
User avatar

Joined: Thu Apr 23, 2009 11:36 pm
Posts: 3527
Location: Portsmouth
Reply with quote
Quote:
Definitely stay with the 2D array. It is something I have thought about writing myself a number of times but never got round to. However, whenever I have started jotting things down on paper the only way I can see it working is to use 2D arrays.


Okay, thank goodness for that! I had a horrible moment earlier where I thought I had spent ages writing my plans and UML but that it was never going to work the way I was trying it.

Quote:
even with an array of the type you are using you can still only ever know that it's a Piece. You would still have to probe it further to ask it what type of Piece it is surely?


To be honest, I don't know and I've struggled to find anything useful to learn from online.

I declare the array like this:
Code:
static Piece[][] boardSquares; // create an array for pieces


And add items to it like this:
Code:
boardSquares[i][ii] = new Pawn( true, 'P' );
But obviously Pawn could be Queen, Rook, or whatever.

I thought that would mean the pieces are being stored as their subclass type? ie Pawn - is that not true? The compiler isn't giving me any errors with this code, but I get NPE errors at run time on this line:
Code:
pieceChar = boardSquares[i][ii].getName();


That's what made me think that perhaps the objects weren't being stored correctly. I expected the array to be full of objects of type Pawn and Empty which were both instantiated with a char in their display variable, which is what getName() is returning. getName() is a method of Piece.

Hmmmm.

Quote:
I'd go for just overriding methods, and design the classes such that this can be the case. Have one method to output all possible target-squares given its current position. Actually, do you need many other methods? It's late and I can't think.


I don't know anything about abstract classes or overriding methods, so I don't really think that's an option unfortunately. I get the feeling this might be coming next semester *gulp*.

_________________
Image


Thu Jan 28, 2010 11:04 pm
Profile
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
Ah!

I've just been browsing the interwebs a bit.

Just a thought.

You haven't actually instantiated the array.

You'll need this...

Code:
static Piece[][] boardSquares = new Piece[8][8];


N.B. when adding Pieces to this you need to add them from boardSquares[0][0] to boardSquares[7][7]. (Also, for good practice I'd name the array boardSquare (i.e. not plural), when you are referencing it you are only referencing a single square) :D

At compile time it doesn't recognise that it hasn't been instantiated and it compiles because you have declared it.

At run time the NPE is on the Piece array.

... I think.

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 11:18 pm
Profile WWW
I haven't seen my friends in so long
User avatar

Joined: Thu Apr 23, 2009 7:35 pm
Posts: 6580
Location: Getting there
Reply with quote
In fact, just reading a bit about arrays...

They're really fricking useful! :D

I wished I'd read up on them before doing my path finding stuff. Would have made it a hell of a lot easier :D

_________________
Oliver Foggin - iPhone Dev

JJW009 wrote:
The count will go up until they stop counting. That's the way counting works.


Doodle Sub!
Game Of Life

Image Image


Thu Jan 28, 2010 11:26 pm
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 64 posts ]  Go to page 1, 2, 3, 4, 5  Next

Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.