Copy of a piece

While reading the assignments i came across this part:

Copyability Every piece shall provide the method clone, which returns a deep copy of the piece. Note, this
means a deep copy of the two-dimensional array that represents the piece, has to be made. Therefore, every
value has to be copied, not just the reference to the array

This somewhat confuses me since I tought we could just use the method .getBody() to get a new array a use something like:
“PieceImp newpiece= new PieceImp;
newpiece.body = old.getBody();
(–rest of implementation–)”
(Given that we store the body of a given piece in a field called body of course).

Do I just not understand the instruction or why is my code example insufficent?

The line:

newpiece.body = old.getBody();

could mean that both the new piece and the old piece have a reference to the same body. That is not the desired effect. If something changes about the body of the old piece this will then also apply to the new piece, hence they are not distinct pieces at all. (This is of course assuming that getBody actually returns the same reference to the body that is also used in the implementation of piece which is the way getters usually work)

The deep copies are also needed for security reasons. If you take a look at AutoPlayer.java and MyTetrisFactory.java you will find that an AI only gets a TetrisGameView as its input and this game view provides methods for obtaining access to the current state of the board.
These methods do not simply return:

game.getBoard()

but rather:

game.getBoard().clone()

In the first variant the AI could call any of the public board methods on the board and change it to gain an advantage. For example it could call the getBoard method on the board it receives, hence giving it access to the underlying array of the board. Once you have that you could for example fill out holes caused by poor play or remodel the board so that every piece clears at least two rows.

In the second variant you get a board with the same number of rows and columns and the same entries as the old one but you do not get a reference to the old board or a reference to the board (double) array of the old board. (You could of course model the board differently, but as long as you use at least a single member field with a public setter method you will be allowing the recipient to write and not just read the board)

so TL;DR getBody() does not actually return an array of arrays of booleans but something like a pointer to such an array? such that thepseudocode:

a=p.getBody()
b=p.getBody()
assertTrue(a==b)

would be correct?( Keeping in mind that == returns true here if they are the exact same object)

does this only hold for certain types? or much rather do the basetypes (like int) have the same issue?
From my understandy something like
newpiece.width = old.getWidth();

would work since the field and the returntype of getWidth() are both int.

Hi there!

Unlike C, Java doesn’t have pointers, but other than that, you are pretty much correct. In Java we always have pass-by-value, so one would think that you always get copy of whatever you’re passing. However, when you’re dealing with objects, you’re not really handing over the whole object, but the reference, which gets passed-by-value.

so TL;DR getBody() does not actually return an array of arrays of booleans but something like a pointer to such an array? such that thepseudocode:
a=p.getBody()
b=p.getBody()
assertTrue(a==b)
would be correct?( Keeping in mind that == returns true here if they are the exact same object)

Try this out in your IDE:

int[] a = {0, 1};
int[] b = a;
b[0] = 2;
System.out.println(a[0]);

If the result confuses you you need to reread how Java handles references.

does this only hold for certain types? or much rather do the basetypes (like int) have the same issue?
From my understandy something like
newpiece.width = old.getWidth();
would work since the field and the returntype of getWidth() are both int.

This code would be perfectly fine.

I got confused reading this, so I googled a bit to verify that my understanding (but not my terminology) was correct. Here is an excellent explanation of why the language surrounding pass by value/reference is so confusing.

TL;DR: In Java, everything except for the primitive types “works like a pointer”. If you pass around an array, you are not actually copying the array all the time (this would be horribly inefficient), but pass around a reference (read: pointer). This means that other people can modify your array if you just return it without copying.