In the context of a 2 players game, I have a C function that does recursive calls and for each call, it does a memcpy
from a global array variable a current local array. Here's this C function ("game" array is declared as a global variable, outside the function) :
int game[8][8];
int recursive_function(int player, int *mx, int *my, int depth)
{
int x, y;
int eval, e;
int mx2, my2;
int game2[8][8];
// TERMINAL CASE
if (depth == 0) {
return 1;
}
memcpy(game2, game, sizeof(game));
eval = -INFINITY;
for (x = 0; x < 8; x++)
for (y = 0; y < 8; y++) {
if (isplayabe((x, y, player)) {
e = -recursive_function(OTHER(player), &mx2, &my2, depth-1);
}
if (e > eval) {
*mx = x; *my = y;
eval = e;
}
memcpy(game, game2, sizeof(game));
}
return eval;
}
Now, I would like to implement the same function in javascript.
I think I have to use object for reference passing. So I have created objects Hit
and HitTemp
with for each of them, coordinates of array as attributes :
Hit.coordPlaybles
are(x,y)
coordinates and makes the link as the equivalent ofgame
variable aboveHitTemp.coordPlaybles
are(x,y)
coordinates and makes the link as the equivalent ofgame2
variable above
From this, I tried with Object Hit
defined by :
// Player white and black
var playerWhite = ['white', 'black'];
var playerBlack = ['black', 'white'];
var Hit = {
currentPlayer: playerBlack,
coordPlayable: ['0', '0'],
coordCurrent: ['0', '0'],
};
The object Hit
is declared outside recursive_function (global variable) whereas HitTemp
is defined only into this function (local variable).
Here is what I did :
// Object Hit passed by reference
function recursive_function(Hit, depth) {
// Evaluation
var eval, e;
// TERMINAL CASE
if (depth == 0) {
return 1;
}
// Local Hit object : EQUIVALENT OF "memcpy" ??
var HitTemp = Object.assign({}, Hit);
eval = -infinity;
for (var x = 0; x < 8; x++)
for (var y = 0; y < 8; y++) {
if (isplayabe((x, y, HitTemp)) {
// CALL RECURSIVE WITH OPPOSITE PLAYER (SWITCHING PLAYER)
e = -recursive_function(OTHER(HitTemp.currentPlayer), depth-1);
if (e > eval) {
// HitTemp.coordCurrent[0] = *mx
// HitTemp.coordPlayable[0] = x
// HitTemp.coordCurrent[1] = *my
// HitTemp.coordPlayable[1] = y
HitTemp.coordCurrent[0] = HitTemp.coordPlayable[0];
HitTemp.coordCurrent[1] = HitTemp.coordPlayable[1];
eval = e;
}
// Final copy from HitTemp to Hitobject : Here also, equivalent to
// the final memcpy of C version ??
Hit = Object.assign({}, HitTemp);
}
return eval;
}
Unfortunately, the results between the 2 versions are quite different (I am sure that C version is working fine).
Could anyone tell me if the Javascript "assign
" method is the right method to reproduce the behavior of C "memcpy
" function ?
If not, could you give me some clues to fix it with recursive calls?
UPDATE 1 :
Thanks for your help. However, I have an issue with solution suggested by
@Siltaar . Indeed, if I do a deep copy with JSON.parse(JSON.stringify(HitCurrent))
as :
// Global variables : Player white and black
var playerWhite = ['white', 'black'];
var playerBlack = ['black', 'white'];
//Global variable Hit
var Hit = {
currentPlayer: playerBlack,
coordPlayable: ['0', '0'],
coordCurrent: ['0', '0'],
};
function recursive_function(HitCurrent, depth) {
// Deep copy
var HitTemp = JSON.parse(JSON.stringify(HitCurrent));
// Switch color for player
// BEFORE
console.log('BEFORE = ', HitTemp.currentPlayer);
// Switch
HitTemp.currentPlayer = (HitTemp.currentPlayer == playerBlack) ? playerWhite : playerBlack;
// AFTER : expected the opposite of BEFORE
console.log('AFTER = ', HitTemp.currentPlayer);
...
}
and I get with BEFORE
and AFTER
:
BEFORE =
Array [ "black", "white" ]
AFTER =
Array [ "black", "white" ]
As you can see, the value of "HitTemp.currentPlayer" is not switched, it seems that "HitTemp.currentPlayer == playerBlack
" is set to false whereas the "BEFORE
" value of "HitTemp.currentPlayer
" is set to "playerBlack
".
I must make notice that recursive_function
is called with the global object Hit
in the main(
) like :
//Global variable Hit
var Hit = {
currentPlayer: playerBlack,
coordPlayable: ['0', '0'],
coordCurrent: ['0', '0'],
};
// Main function
function main() {
recursive_function(Hit, maxDepth);
...
}
Has this issue a relation with the deep copy of HitCurrent
to HitTemp
object ?
UPDATE 2:
If I use only one "=" (and not two "==") like this :
console.log('BEFORE = ', HitTemp.currentPlayer);
HitTemp.currentPlayer = (HitTemp.currentPlayer = playerBlack) ? playerWhite : playerBlack;
console.log('AFTER = ', HitTemp.currentPlayer);
Then the switching works : What's the right syntax (one "=" symbol or two ) with the condition of ternary operator to test an equality ?