Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chess in Java - Object orientation vs Efficiency

Tags:

java

oop

chess

I'm developing a chess program in Java and considering the following problem:

  • The Rook piece requires implementation for moving in straight lines.
  • The Bishop piece requires implementation for moving in diagonal lines.

However,

  • The Queen piece requires implementation for both of the above movement patterns.

I can't think of a clean solution to modelling this relationship, I have considered some but none of them are both compliant with good object-orientated design and code efficient.

  1. Java doesn't support multiple inheritance, so Queen cannot borrow implementation from Rook and Bishop

  2. If Rook and Bishop extended Queen, I'd need to extract the logic for each kind of movement into separate methods, this would serious bloat my current design for how movement is validated.

Neither of the above solutions seem elegant enough to beat just:

  1. Putting ALL of the movement implementation into the parent class of all the pieces, this way they all can share all of the common implementation (of which there is quite a bit)

I'm aware solution 3 is in violation of good Java design, but in this case, that design pattern seems to only be forcing bloated, inelegant solutions.

Probably this could be avoided with a complete restructuring of the program, but everything up to this point looks pretty efficient to me, does good OO design always come at the cost of directness of functionality and structure? Is my approach just wrong for the style of the language?

How would you solve this problem?

like image 792
David Wood Avatar asked Aug 27 '15 11:08

David Wood


1 Answers

While some classes might behave in a similar way, this does not automatically mean that they are in one hierarchy!

For example, both a Human and a Crab can move sideways, but it is silly for a Human to extend Crab.

If you really want to re-use movement code, you can use encapsulation, use a Movement type and make it like this:

class Human
{
   List<Movement> movements;
}

class Crab
{
    List<Movement> movements;
}

class MoveSideWays extends Movement
{
      move();
}

class MoveForward extends Movement
{
      move();
}

But it feels like over-engineering. I would have a Piece class with getPossibleMoves() and just implement it directly. There is not too much overlap and Rooks have specialized movements (Castling) as well.

class Rook extends Piece
{
   List<Move> getPossibleMoves()  {...}
}

class Queen extends Piece
{
   List<Move> getPossibleMoves() {...}
}
like image 190
Rob Audenaerde Avatar answered Oct 24 '22 07:10

Rob Audenaerde