I'm trying to create a shallow copy of a struct Board (a chessboard). Before saving a move to the board, I need to check if that move puts the mover in check.
To do so, within the Move method (method of a pointer), I dereference the pointer, update and check this possible board for Check. When I change the value of a single value of the Board type (such as possible.headers = "Possible Varient"
) the original b
Board is not changed.
But here when I call a method updateBoard() it updates both boards. I still receive the error (cannot move into check), but the main thread thinks b.board
(the board position) has been changed.
func (b *Board) Move(orig, dest int) error {
// validation
...
// Update
possible := *b // A 'shallow copy'?
possible.updateBoard(orig, dest, val, isEmpassant, isCastle)
king := possible.findKingPositionOfThePlayerWhoMoved()
isCheck := possible.isInCheck(king) // bool takes the king to check for
if isCheck {
return errors.New("Cannot move into Check")
}
b.updateBoard(orig, dest, val, empassant, isCastle)
return nil
Strangely, not all the the values updated by updateBoard()
change. So the b.toMove
value doesn't change, but the b.board
value does (the position of the pieces). This means if I pass possible := b
instead, the game will only ever be white's move (toMove is alternated in the updateBoard() method). With possible := *b
, turn alternation works until one moves into check. Then the move is applied to b.board
, but the error is thrown back and it remains the checked-players turn (meaning possible.updateBoard()
didn't update b.toMove.
Edit
As abhink pointed out, in Go Slices usage and internals,
Slicing does not copy the slice's data. It creates a new slice value that points to the original array.
b.board
, a []byte
, always points to its original value (even when the struct which holds it is dereferenced. abhink's answer uses the Go func copy(dst, src []Type) int
, https://golang.org/pkg/builtin/#copy , a shortcut for copying the values of the pointers.