testMoveLeftAtLimit

public boolean moveLeft();
     * Moves the current piece to the right.
     * @return true if the piece can be moved to the right.

if I understand correctly movePiece should return true if current piece can be moved to the left does this mean I should return false if that is not the case? because now my canAddPiece function throws illegalArgumentExeption and the test is failing.

canAddPiece(Piece piece, int row, int column) {
-> piece == null -> illegalArgumentException
-> can add piece to board -> return true
-> can not add piece to board -> return false
} 

addPiece(Piece piece, int row, int column) {
 -> canAddPiece(piece,row,column) = true -> add the piece to the board
 -> canAddPiece(piece,row,column) = false -> throw illegalArgumentException
}

thats the general “structure” of my methods (pseudo code).

So I think that each of the move methods (left,down,right) should return false if the add/remove method throws an illegalArgumentException. You have to catch this exception.

(Correct me if I am wrong)

1 Like

The method should

  • if the piece can be moved: move the piece and return true
  • if the piece can not be moved: observable do nothing and return false
  • if something unexpected occurs / an error is encountered: throw a suitable exception

Depending on your internal logic, this is one way to do it.
This would be exception style programming / exception control flow.
This way of programming is not necessarily bad, but is often considered bad style as

  • exceptions indicate an error / unplanned exceptional situation
  • usually an exception is considered to not occur
  • there is overhead for raising, catching, and handling the exception depending on the context

Another solution would be to either have a informative return type (I) or checker methods (II).

(I) is the case with moveLeft for instance.

  • (Informative Return (our case)) moveLeft does nothing if the move was impossible and tells that to the user with a boolean value false. If the move is possible, it is performed as expected and true is returned.
  • (Exception style) There is no checking method and an exception is thrown if the move was not possible. The only way to check for the caller is to catch (and expect) the exception (usually bad style).
  • (Checker) One could have a void moveLeft method accompanied by a canMoveLeft method and leave it to the caller to make sure if the left move was possible. An exception is thrown if moveLeft is called although it was not possible. An advantage is that the user might be separately be interested in canMoveLeft.

To write moveLeft, you could play with exceptions or make sure (using checks like canAdd) whether you can move.

Note regarding boolean return type:
The situation to return a boolean is not ideal.
Usually, the programmer forgets after some time whether true was

  • yes it can be moved, or
  • yes, the new place is occupied, and the piece and not be moved.

This phenomenon is known as boolean blindness.
A way to prevent it would be a more informative type isomorphic to bool like a two-values enum.
In some languages like Java, this is a bit of unnecessary overhead and is usually not done.
But in functional languages where algebraic types are cheap and easy to define on the go, a boolean return type would usually be considered bad style.

Another forum post regarding exception style programming:

1 Like

Yes.
I should have mentioned that I do catch the exception if it occurs, however, due to my structure, it can only occur in extremely rare cases. It can only occur if the piece is not on the board or the row/column is not correct and this should not occur as long as my game implementation is correct or as long as it works as expected.
But this concerns my implementation and I am not the topic creator :smiley:

1 Like

I think I got it to work somehow but as Marcel said try catch is not best possible solution and I will try to fix that but same as you my functions kind of lead me to catch the exeption in rare cases, thanks for your suggestion!

In exceptional cases that should not occur, an exception is the right way to go.
If a null piece should be moved or the piece to be moved is not even on the board, the method(s) should throw exceptions.
But these should not be caught in the methods themselves because they constitute an erroneous situation to the outside.

1 Like

No, I am trying to catch it in moveLeft() function so the function always returns true or false, is that what you mean?

There are three cases.
If something is wrong (like the piece to be moved is not on the board), the method can/should throw an exception.

1 Like

Could you please specifiy which methods you mean with this sentence?

I am throwing exceptions in:

addPiece() -> if canAddPiece returns false ;
canAddPiece() -> if piece == null ;
removePiece() -> if canRemovePiece returns false ;
canRemovePiece() -> if piece == null ;

and that should fulfill the specification given in the comments of the Board-Interface.

In my move methods (moveRight(...), moveDown(...), moveLeft(...) I am using canAddPiece(..) and canRemovePiece() to make sure addPiece(...) and removePiece(...) won’t throw an exception.
But still canAddPiece(..) and canRemovePiece() are able to throw exceptions. That’s why I try to catch them, even if the case can’t occur. But currently I am overthinking this structure.

And (looking at the first quote in this post) I understand this statement to mean that I should throw the exception in this case so that the incorrect behavior is displayed to the outside?

Edit:
I would like to add that I do not throw an exception in any of my move-methods. It returns true or false. I only catch the exceptions from the “board methods” in my move-methods.