OOP Question

Okay this isn't really a Java question, rather a OOP question.

Say i'm creating a class heirarchy of Objects, which have both functionality (not related to how it looks) and can be displayed.

For instance the game of chess. Each Chess piece has it's own movements etc. It also has a specific way to be drawn, depending on the GUI/Text user interface, eg character, 2D, 3D models of it.

The question is this: Should I implement the drawing methods in a separate class and have a reference to this in the class within the functionality class or vice versa. Or should I have a subclass of the functionality Class implementing the specific drawing mechanisms?

Which is better OOP practice? In terms of engineering considerations, and adaptablility of the class heirarchy?

I want to be able to change the look of the program at any stag with minimal reprogramming at a later stage.

[923 byte] By [rwfocke] at [2007-9-26 1:23:05]
# 1

The best way would be to have multiple interfaces. What you could have is a Drawable interface for all classes that need to be drawn. Baiscally you can create more interfaces just for defining the hierarchy in functionality.

So a Piece class can actually implement as many interfaces as you want. For example::

public interface Drawable

{

public void draw(Graphics g, int x, int y);

}

public class ChessPiece implements Drawable

{

// all members and method .... eg position and so on

}

public class ChessBoard

{

}

public class ChessGame

{

ChessBoard board;

ChessPiece blackPieces[];

ChessPiece whitePieces[];

// and so on...

}

Hope that answers it.

Ta

Sriram

spany at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 2

My personal opinion is that movments/charachteristics of a piece and how it looks/is represented should be completly seperate and should have no knowledge of each other.

That is , as I understand it good OOP.

they should be accessed from interfaces which is in turn called by an instance of your game class.

really you would want your players to move and the game to play and have things redraw when the system is ready to draw , like paint() it draws when it can draw and not when you tell it , you jus make a request.

you then paint what is happening at the present time

50fps or higher :)

is that correct?

slinqi at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 3
is there , while I think about it , a good site for learningOOP and UML?
slinqi at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 4
Thanks for the replies. Yes i think the interface way is good for my Java version. The separate classes will help with my C++ version. Thanks.. Going to have to split these points... or i'll just give you 5 each?
rwfocke at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 5

There is a common pattern to accomplish this form of separation, called Model-View-Controller (MVC). Here, the model holds your 'business' logic (the chess rules), the view contains the representation classes and the controller is the glue between the two.

Take a look at http://c2.com/cgi/wiki?ModelViewController as a starting point.

ipreuss at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 6

To learn OOP, my opinion is, you may be better off with a book. I doubt if anyone on the net knows good OOP practice. You have to go for an author in the Ph.D. level if you need to learn good Object orientation, or someone wiht extreme experience in this field. The rest of them are just trying to make a living by publishing bits and pieces here and there. I preach that OO is not at all easy. In fact 3/4 of my developing time goes to picking objects. And after I program them, I find myself changing them and needing to re-program them. It is not shame to improve your objects along the way. OOP lies in the field of Software Engineering.

As far as your chess game, (my opinion) I am against interfaces. Although most replies in this topic are in favor of interfaces, I personally avoid them like Hell. Just to let you know that you can do it, without interfaces as well.

MVC is for simplier systems. I would like to see how you implement your Models and controller. View may be easy. You are not out of the forest if your Model requires another 50 objects to implement, and your Controller also a bunch of objects on its own.

A chess A.I. game is being written by IBM and their purpose is to beat the russian Chess champion whats-his-name I forgot. May be you learn something from them.

Chris.

Boston University.

javaDotDynamicDashSiteDotNet at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 7

Don not go for the interfaces!

Ther purpose of interfaces is to define a set of methods

which can be implemented by an arbitrary number of classes.

In your case you have one class (or group of classes)

and a potential unlimited number of ways to display them.

when you want to add another display method you have

to change every single class!!!

Go for the MVC aproach. For an nice example look at the

JTable and JTree of Swing ... the front end nows sh** about how the models behave, and the models don't now how they get displayed ... you can write classes to display a table model as ascii or html or morse code without changing the table model. That is what you want.

Spieler

spieler at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 8

Let me get this right.

The best idea is to create a model class, which models the functionality of the chess piece. Then create a view class that implements how to display the model. And then use a controller class to link the two together...

Thank that sounds better that doing the interface way cause that still needs alot of reprogramming.

Interfaces are out of the question anyway since I'm actually writing this in C++ but I might port it to Java...

rwfocke at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 9

1. you can 'fake' interface in any OOP language by just providing empty methods

2. The controller doesn't really link view class and

modell class its purpose is to allow the user to change the model.

In a lot of cases view and controller become the same thing ... which is just fine in a lot of cases

for you this could look like this:

public Interface ChessPiece{

...

public Point getPosition();

public void moveTo(Point p)

throws IllegalMoveException;

...

}

public Class King implements ChessPiece ...

public class TextUI{

public void printField(Point pos){

loop over all pieces p{

if (p.getPosition() = (x,y){

if (p.class.equals( ...){

System.out.print("K");

} else if .....

}

}

}

}

// controler parses a command string and applies the command to the pieces

public class Controller{

Map pieces;

public void parse(String command){

... do some parsing ...

try{

(Piece)pieces("King").moveTo(new Point(x,y);

} catch (IllegalMoveException e){

System.err.println("You are not allowed to make this move!");

}

}

}

For a graphical interface the view could be a JComponent

and the control a text box or a XXXListener, which waits for Drag'n'Drop events.

hth

Spieler

spieler at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 10

> Thank that sounds better that doing the interface way

> cause that still needs alot of reprogramming.

Ack ...

Take also a look to the Controller Part of the MVC, although java

tends to combine View & Controller e.g. in Swing.

The Controller encapsulates the input reaction of the system.

If you plan to implement many similar Views with similar input responsability,

it will be usefull to separate the Controller Part also.

cheers

micha

jerger at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 11
www.javaoop.org might help
chrishmorris at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 12

I'm actually doubtful whether Piece (and subclasses like Pawn, Bishop etc) is a helpful class for this application.

I think that a class Board, that represents the current game situation, is the main one, and in particular a method boolean isLegal(Move move). While you could put a method isLegal in Piece, the legality of a move depends a great deal on the context.

In an implementation of the viking game hnefatafl, I didn't use a Piece class at all. Admittedly, that only has two sorts of piece. In Chess, you might want a Piece class with getImage() and a few other methods. I would suggest that this could be a flyweight class - I don't see much need for it to contain state.

chrishmorris at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 13

> I think that a class Board, that represents the

> current game situation, is the main one, and in

> particular a method boolean isLegal(Move move). While

> you could put a method isLegal in Piece, the legality

> of a move depends a great deal on the context.

But it mainly depends on the piece that is to be moved, so I think a Piece class would probably be a good choice.

> I would suggest that this could be a flyweight class - I

> don't see much need for it to contain state.

The flyweight pattern is for situations where you have lots of objects sharing common state. I don't see how this could be usefull here...

ipreuss at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 14

> I think that a class Board, that represents the

> current game situation, is the main one, and in

> particular a method boolean isLegal(Move move). While

> you could put a method isLegal in Piece, the legality

> of a move depends a great deal on the context.

To me this is not OOP. This is procedural design. Yes the context is important and there needs to be a "referee" over the moves, however each piece has its own specific ways of moving. If you just have one class that contains all the different ways each piece can be moved for every peice AND all the contextual rules for the chess game the isLegal function is going to be very large and essentially procedural. I get dizzy just thinking of the number of conditional statements that would be required even if you have numerous helper functions.

The piece checks the move to see if it is ever valid. for example: pawn1.move ( back one space) returns false. If the move passes the first validation then ask the controller if the context is valid. Pawn2.move(forward diagonal 1 space) is possibly a valid move but contextual information is needed so the Pawn class asks the controller if there is an emeny piece in the space it wants to move to board.containsBlackPiece(space). If so then ask the controller if this move violates any other contextual rules. board.moveIsLegal(new space). If the move would put the king in check the board would refuse to allow the move to be made.

This is of course only one way to do this. Its really a hard call to say what does what. A castling move,for example, is extremely contextually dependent so in the method above, the rook would have to ask the board for a lot of info and also somehow cause the king to be moved. However whatever you do if you are trying to create an OO model, one big class that does everything is not the way to go.

dubwai at 2007-6-29 1:01:02 > top of Java-index,Core,Core APIs...
# 15

>Yes the context is important and there needs to be

>a "referee" over the moves, however each piece has its own specific ways of moving. ...

>The piece checks the move to see if it is ever valid. for example: pawn1.move ( back one space) returns false

I would guess that if one of the opponents could be a computer then the rule set size for deciding the best move will vastly overshadow the ruleset for deciding a legal move. And a single piece can't figure out the best move. Given that, it might be best if the ruleset contains the valid move rules as well as the rest of the rules.

jschell at 2007-6-30 21:43:10 > top of Java-index,Core,Core APIs...
# 16

> I would guess that if one of the opponents could be a

> computer then the rule set size for deciding the best

> move will vastly overshadow the ruleset for deciding a

> legal move. And a single piece can't figure out the

> best move. Given that, it might be best if the

> ruleset contains the valid move rules as well as the

> rest of the rules.

Huh? Why can't the algorithm just ask a piece about its legal moves?

ipreuss at 2007-6-30 21:43:10 > top of Java-index,Core,Core APIs...
# 17

> I would guess that if one of the opponents could be a

> computer then the rule set size for deciding the best

> move will vastly overshadow the ruleset for deciding a

> legal move. And a single piece can't figure out the

> best move.

This is actually a good reason for putting the legal moves in the piece object and the algorithm for picking the best one out of it in the AI object ...

anyway ... who came up with the idea of a computer oponent ... it is pretty much irrelevant to the original topic, isn't it?

Spieler

spieler at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 18
I think I'm going to implement a user class hierarchy aswell, since i need three types of users, Internet user, i.e a non local user, a local user and an AI user.Thanks for all the ideas. I have a better grasp on what to do now, and to do it properly...?
rwfocke at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 19

>Huh? Why can't the algorithm just ask a piece about its legal moves?

One simpler reason is because a piece can't be aware of its legal moves unless it is aware of the board. A king can move in 8 directions, but not if it is in the corner.

A more complex reason might be due to how modern chess programs play the game. It has been a while since I read about this, but if I remember correctly current games use the following stragegy. The game is broken into three parts: beginning, middle and end.

The beginning is always taken from playbook scripts. Essentially the pieces are scripted to be moved to a beginning position. It doesn't need to check for a legal move, because the moves are always legal. It might be several moves into the script before it even needs to check if the position is occupied. Of course checking if the position is occupied is not something a piece would ever do anyways. That would imply that it had knowledge of the board and or other pieces. If I remember correctly expanding the opening playbook significantly increases the ranking of the program.

The mid game, I believe usually devolves into a strength composition algorithm. Pieces are moved, the resulting position is given a number and the computation continues once again with a different piece. The algorithm uses a lookahead to produce a tree. The branch with the best number is used.

I can't remember how the end game works. But I suspect it is goal oriented. It might be a modification of the mid game with more emphasis on checkmate rather than taking pieces and board position. (But there might also be a playbook involved.)

As I said the beginning game does not need legal moves. The playbook defines the legal moves. The mid and end games do use legal moves, but I suspect that nothing is gained by abstracting that out into the pieces. A good mid-game algorithm is going to give more strength to a knight occupying a square than a pawn. But not if the pawn might be in a position to take a piece next turn. And the complexity of such decisions suggest that the rules engine itself must be aware of the legal moves, not just where to get the legal moves. And that to my mind suggests that the pieces are not the most likely place to keep the legal moves.

jschell at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 20

still doesn't makes a reason not to put the legal moves

into the pieces:

1. beginning:

If the Game Engine isn't using it, it doesn't matter

where it is ... right?

2. Well now the Game Engine needs the information,

why not getting it from the pieces?

There are the following criteria to look at to determine

a legal move:

- the type of piece (can be handled by the piece)

- the position on the board (might possible for the piece, depending on the implementation)

- the position relative the other pieces (to check against chess conditions, the 'weird' moves of pawns)

- the history of the game (for the exchange of tower and king)

The first two can perfectly be handled by rather simple piece classes and should so because its independent of all the other stuff handled by a AI or Board class (or whatever you call it)

Imagine the legal moves for a piece change (which actually happend in history a lot) ... if it's implemented

in the piece you have to change one rather simple class.

if it's implemented in the Board you have to change one class again ... but no one would call it simple ... right?

The only reason to put it in the board class I can see so far would be performance, in order to avoid method calls, but in a problem like this method calls are probably the smallest of your problems.

Spieler

spieler at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 21
Shouldn't the chesspieces know about the board anyway? They belong to the board so they should be able to inquire information from the board, because without the chessboard they aren't really chesspieces?
rwfocke at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 22

> Imagine the legal moves for a piece change (which

> actually happend in history a lot) ... if it's

> implemented

> in the piece you have to change one rather simple

> class.

> if it's implemented in the Board you have to change

> one class again ... but no one would call it simple

> ... right?

THis is exactly the main point of what I said earlier. Whether on not you find it prefferable, on main class is not OO design and if you want to program this way you don't need Java, use Fortran 77.

dubwai at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 23
> if you want to program this way> you don't need Java, use Fortran 77.which actually might be the better language for for a problem like this
spieler at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 24
> > if you want to program this way> > you don't need Java, use Fortran 77.> > which actually might be the better language for> for a problem like this> Because of ...?
ipreuss at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 25

Fortran is really powerfull and fast if it comes to

mathmatical stuff like huge arrays and the like.

Making a decision between the vast amount of options

in a game like chess sounds to me like a lot of numbers.

And the time the program needs to make a decission seems to be critical in this problem.

Spieler

PS: I worked a lot with Fortran and Java ... I hate Fortran and love Java but Fortran has it's good sides ...

PPS: I have only very limited knowledge about chess and computers playing chess

spieler at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...
# 26

OK, I admit I did not read the last 7 replies on this page, but here is my view:

I agree very much with Chris, in that the MVC architecture is mostly suitable for simpler (administrative) systems where the current state is held in e.g. a database. In the chess domain, you will find yourself wanting to model "proper" objects with both data and behaviour to enable a more "real world" like OO-model.

I participated in the development of a similar application a couple of years ago, and we ended up with a Domain model/View approach, modeling objects with data and behaviour to resemble the domain, and a separate set of classes to take care of the painting/GUI stuff. The GUI classes implemented interfaces that were specially designed to draw objects from the mentioned domain, and served their purpose again later, when we had to make a similar application (->reuse!).

Each domain object was given a reference to a GUI object that was responsible of drawing this particular domain object. This gave us the MVC update-ability where the model notified the GUI each time the state changed. However, the GUI objects were free to postopne drawing until the system fancied to redraw (with the backdraw that the state had to be stored two places, in the model and in the GUI).

The architecture was strongly inspired by the MVC architecture, but we realized that the controller would have to be extremely complicated to manage a large set of very complex business rules (as we were requried to implement).

Regarding inheritence of Drawable interfaces:

I do not like this approach at all. Inheritance implies an "is-a" relation to what you inherit, and taken into account that all your classes should model single key abstractions of your domain (that is: no class should implement behaviour of two or more entities in your system), being both a drawing-class and a chess-board, simply stinks.

Rather, the domain objects should use a drawing utility (a uses-relationship) to draw themselves.

DanielBakkelund at 2007-6-30 21:43:11 > top of Java-index,Core,Core APIs...