I'm building a tower of Hanoi game to get used to react. I have a state property called "disks", which is an array consisting of 3 arrays of length N (N being the total number of disks). I also have defined a state property "history" which is supposed to contain the history of the disks array like this:
- intially: history = [disks(Initial config)]
- After 1 move: history = [disks(Initial config), disks(after 1 move)]
- After 2 moves: history = [disks(Initial config), disks(after 1 move), disks(after 2 move)] etc.
However, after M moves, the history array looks like this:
history = [disks(after M moves), disks(after M moves), ... , disks(after M moves)].
I can't find my mistake. Would appreciate it if anyone had an idea what's going wrong. Here is the relevant code:
constructor(props){
super(props);
let disks = [
[],
[],
[]
];
//Initially all disks in first tower
for(let i=0; i<props.numberOfDisks; i++){
disks[0].push(i);
}
this.state = {
disks : disks,
selected : null,
move: 0,
history: [disks]
};
}
handleClick(i){
const disks = this.state.disks.slice();
const history = this.state.history.slice();
let move = this.state.move;
let selected = this.state.selected;
//if user has not previously selected a tower or selects the same tower again
if(selected===null || i===selected){
selected = disks[i].length>0 && i!==selected ? i : null;
this.setState({
selected : selected
});
return;
}
//Check if move is legal
//index is at bottom is 0 and the largest disk has id 0
if(disks[i].length === 0 || disks[i][disks[i].length-1] < disks[selected][disks[selected].length-1]){
//perform move
disks[i].push(disks[selected].pop());
move++;
// I guess this is where it goes wrong, but I can't see why
this.setState({
history: history.concat([disks]),
disks: disks,
move: move
});
}
this.setState({
selected: null
});
console.log(this.state.history);
}
Please note that the game is otherwise working, meaning the disks array is updating properly etc... It's just the update of the history array that goes wrong somehow. I tried putting disks.slice() into the history.concat as it seemed to me that the history is somehow storing references to the disks array, but that didn't help.