-
Dec 6th, 2014, 05:40 PM
#1
Problem understanding how an array is initialized
I have this code which I cut out of a much larger function and have removed a lot of code lines and variables from both the .h file and the .c file just so I have only what is significant for this question.
The code loops as long as there are characters remaining in char const strFen. As it processes each character in the string it calculates some values and they are placed in an array, argpi[][] which is in the structure pcon.
argpi[][] is a 2D array of type PI which contains the following members:
Bool bInit;
int pc;
int co;
BOOL fDead;
int isq;
int val;
I'm trying to figure out how member ppi->isq gets organized into the 2D array, argpi[][]. There is a code line ppi->isq = IsqFromRnkFil(rnk, fil); which I have made it bold and red in the code that generates all the values for ppi->isq. As I stepped through the code I see that the ppi->isq values are generated in the following order:
Code:
ppi->isq values generated in following order:
112 113 114 115 116 117 118 119 96 97 98 99 100 101 102 103
16 17 18 19 20 21 22 23 0 1 2 3 4 5 6 7
However, these value are not put into the 2D array in that order. The order the values appear in the 2D array are as following:
Code:
isg values arranged in argpi[][] array:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0 | 4 |17 |18 |19 |20 |21 |22 |23 | 0 | 1 | 2 | 3 |16 | 5 | 6 | 7 |
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
1 |116|113|114|115|112|117|118|119|96 |97 |98 |99 |100|101|102|103|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
which brings me to my problem: Where in the code are these values placed into the 2D array in the order as shown above and how does it work.
.h file code
Code:
#include <stdio.h>
#include <string.h>
typedef int BOOL;
#define fFALSE 0
#define fTRUE 1
typedef unsigned __int64 U64;
#define filA 0
#define filMAX 8
#define filIBD 16
#define rnk8 7
#define rnkMAX 8
#define coMAX 2
typedef struct tagPI
{
BOOL bInit;
int pc;
int co;
BOOL fDead;
int isq;
int val;
}
PI, *PPI;
#define cpiMAX (filMAX * 2)
typedef struct tagSQ
{
BOOL bInit;
PPI ppi;
int isq;
}
SQ, *PSQ;
#define csqMAX (rnkMAX * filIBD)
#define cfMAX 16
typedef U64 HASHK, * PHASHK;
#define HashkSwitch(hashkDst) ((hashkDst) ^ 0x21D420B884CD6731)
typedef struct tagSTE
{
BOOL bInit;
int coUs;
}
STE, *PSTE;
typedef struct tagCON
{
BOOL bInit;
PI argpi[coMAX][cpiMAX];
int argcpi[coMAX];
SQ argsq[csqMAX];
}
CON, *PCON;
#define IsqFromRnkFil(rnk, fil) ((rnk) * filIBD + (fil))
void Test();
.c file code
Code:
void Test()
{
static CON s_con;
PCON pcon = &s_con;
char const strFen[56] =
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
char const *szFen = strFen;
int rnk;
int fil;
int i;
pcon->argcpi[0] = 0;
pcon->argcpi[1] = 0;
fil = filA;
rnk = rnk8;
for(;; szFen++)
{
if(*szFen == ' ')
{
szFen++;
break;
}
switch(*szFen)
{
PPI ppi;
int pc;
int co;
case 'p':
pc = 0;
co = 1;
lblSet:
ppi = &pcon->argpi[co][pcon->argcpi[co]++];
if((pc == 5) && (pcon->argcpi[co] > 1))
{
PI pi = pcon->argpi[co][0];
*ppi = pi;
pcon->argsq[ppi->isq].ppi = ppi;
ppi = &pcon->argpi[co][0];
}
ppi->fDead = fFALSE;
ppi->pc = pc;
ppi->co = co;
ppi->isq = IsqFromRnkFil(rnk, fil);
pcon->argsq[ppi->isq].ppi = ppi;
fil++;
break;
case 'P':
pc = 0;
co = 0;
goto lblSet;
case 'n':
pc = 1;
co = 1;
goto lblSet;
case 'N':
pc = 1;
co = 0;
goto lblSet;
case 'b':
pc = 2;
co = 1;
goto lblSet;
case 'B':
pc = 2;
co = 0;
goto lblSet;
case 'r':
pc = 3;
co = 1;
goto lblSet;
case 'R':
pc = 3;
co = 0;;
goto lblSet;
case 'q':
pc = 4;
co = 1;
goto lblSet;
case 'Q':
pc = 4;
co = 0;
goto lblSet;
case 'k':
pc = 5;
co = 1;
goto lblSet;
case 'K':
pc = 5;
co = 0;
goto lblSet;
case '/':
fil = filA;
rnk--;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
fil += *szFen - '0';
break;
}
}
}
Last edited by jmsrickland; Dec 7th, 2014 at 12:22 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 7th, 2014, 05:24 AM
#2
Re: Problem understanding how an array is initialized
Code:
ppi = &pcon->argpi[co][pcon->argcpi[co]++];
...
ppi->isq = IsqFromRnkFil(rnk, fil);
ppi is a pointer to the address in memory of a struct of type PI. The isq element of this struct is set to the value returned from the macro. So the statement that sets the value of ppi determines where in the 2D array the value is placed.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
Dec 7th, 2014, 12:22 PM
#3
Re: Problem understanding how an array is initialized
Thanks, 2kaud, but I pretty much already know these things. I pointed out in my post the same thing.
What I am asking is not so much where but how do the values get re-arranged in the array. They are not in the same order as they are generated so something has to be taking place to place the values in a different order that the order of them being generating. You say ...the statement that sets the value of ppi determines where in the 2D array the value is placed. . Well, that I know but what is taking place that actually places the isq value in it's particular position in the array.
Values are generated like
112 113 114 115 116 117 118 119 96 97 98 99 100 101 102 103
but as they are being collected in the array something is causing them to be placed in a different order, like
116 113 114 115 112 117 118 119 96 97 98 99 100 101 102 103
So, for example, what is making the 116 to appear first in the array and 112 to appear where the 116 ought to be
And for the other string of values they are generated as
16 17 18 19 20 21 22 23 0 1 2 3 4 5 6 7
but wind up in the array as
4 17 18 19 20 21 22 23 0 1 2 3 16 5 6 7
but as you can see the 16 and the 4 are switched in the array. What is doing this?
EDIT: Here's something I found that has an influence on the values in the array
1st time through the loop the array is all 0's. I'm interested in the row 1 values
Code:
argpi[1] [0] [1] [2] [3] [4] [5] [6]....etc
0 0 0 0 0 0 0.....etc
112 0 0 0 0 0 0.....etc
112 113 0 0 0 0 0.....etc
112 113 114 0 0 0 0.....etc
112 113 114 115 0 0 0.....etc
See how the values are being placed in the array on each pass through the loop
in the same order as they are generated. Now, after it passes through
the loop on the 6th time it will enter the if((pc == 5) && (pcon->argcpi[co] > 1))
and do some things that I don't understand but as a result of this the
array now looks like this:
112 113 114 115 112 0 0 0.....etc
Note that instead of the expected value of 116 in the 4th array position
it places 112 there. Now as it goes back to the top of the loop and executes
the ppi = &pcon->argpi[co][pcon->argcpi[co]++]; line the array now looks
like this:
116 113 114 115 112 0 0 0.....etc
And the value of 116 is placed in element 0 of the array. After this
the rest of the array is populated in order
116 113 114 115 112 117 0 0.....etc
116 113 114 115 112 117 118 0.....etc
This is what my problem is. What is it, what is taking place, that causes the 112 to be placed in the 4th array position and the 116 to be placed in the 0 element and also the 16 and 4 being switched. What is doing this?
EDIT EDIT
I found in the code where part of the placement is done but I do not have the slightest clue how it works
From the code I posted in my 1st post:
Code:
if((pc == 5) && (pcon->argcpi[co] > 1))
{
PI pi = pcon->argpi[co][0];
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115| 0 | 0 | Array looks like this when if clause 1st entered
// +---+---+---+---+---+---+
// Now let's make a pointer (*ppi) to structure pi
*ppi = pi;
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115|112| 0 | After above line (*ppi = pi;) array
// +---+---+---+---+---+---+ now has 112 in the 4th element
pcon->argsq[ppi->isq].ppi = ppi;
ppi = &pcon->argpi[co][0];
}
Last edited by jmsrickland; Dec 8th, 2014 at 08:50 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 8th, 2014, 10:47 PM
#4
Re: Problem understanding how an array is initialized
The line *ppi=pi does not create a pointer. It is assigning to the address pointed to by ppi.
Pointers are 'created' using the address-of operator &.
This might help:
Code:
int numbers[4] = {1,2,0,0};
int *num = &numbers[3];
*num = 99; // numbers is now {1,2,0,99}
I don't understand the intention of the code, to be honest (is it a chess game?)
-
Dec 9th, 2014, 12:03 AM
#5
Re: Problem understanding how an array is initialized
I understand your example but I don't see anything like that in the code snippet I posted previously. All I see is
Code:
PI pi = pcon->argpi[co][0];
// pi equals argpi[co][0] where co = 1 so we have argpi[1][0]
// which is the PI structure in element 1,0 of the array.
// argpi[1][0] is:
//
// +-----+
// |bInit|
// |pc | 3
// |co | 1
// |fDead|
// |isq | 112
// |val |
// +-----+
//
// And then I see this:
*ppi = pi;
If there was something like *ppi = &argpi[1][4] I could see how the value winds up in row 1, col 4 of argpi based on your example but there is no such thing and what I think it is doing is
as though it was *ppi = &argpi[1][0] so how then does it get in 1,4
Last edited by jmsrickland; Dec 9th, 2014 at 12:06 AM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 9th, 2014, 04:26 AM
#6
Re: Problem understanding how an array is initialized
pi is a PI structure at pcon->argpi[1][0]
ppi I assume points to argpi[1][4]
So *ppi = pi is copying the structure at index 0 to index 4.
The assignment of ppi appears to be here:
Code:
ppi = &pcon->argpi[co][pcon->argcpi[co]++];
At the time in question, the value of pcon->argcpi[co] must be 4.
It's kind of hard to follow the code; it's spaghetti (more than zero goto instructions).
Last edited by penagate; Dec 9th, 2014 at 04:52 AM.
-
Dec 9th, 2014, 11:06 AM
#7
Re: Problem understanding how an array is initialized
ppi = &pcon->argpi[co][pcon->argcpi[co]++]; would be same as
&pcon->argpi[1][pcon->argcpi[1]]; at the time it hits the if statement and the contents of
argcpi[1] is 5
When the if((pc == 5) && (pcon->argcpi[co] > 1)) clause is entered, co = 1 and the value in pcon->argcpi[co] is 5
So in the if clause it has
PI pi = pcon->argpi[co][0]; where co is 1 so it is referencing argpi[1][0] and I posted what is in the array element in my post #5
Then the next line
*ppi = pi;
I do not see how argpi[1][4] is initialized with the same data that is in argpi[1][0]. Based on your statements it should wind up in argpi[1][5] but it doesn't and that is what confuses me
In your example you explicitly reference element [3] with int *num = &numbers[3]; but in the code I have that is not the case.
Yes, I agree, it is spaghetti code and the entire C project is one of the most complicated bunch of crap code I have ever seen but it works and it is one of the best chess engines I have found. I need to understand how a lot of the stuff works as I am trying to convert it over to VB6. I have already converted more than 75% of the C code to VB6 code but I run into a lot of weird stuff, like this example, now and then and before I can convert to VB I have to understand how it works in C first
Last edited by jmsrickland; Dec 9th, 2014 at 11:37 AM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 9th, 2014, 11:21 AM
#8
Re: Problem understanding how an array is initialized
Code:
// Now let's make a pointer (*ppi) to structure pi
*ppi = pi;
This doesn't 'make a pointer'. This says put the contents of variable pi into the memory pointed to by variable ppi.
Code:
if((pc == 5) && (pcon->argcpi[co] > 1))
{
PI pi = pcon->argpi[co][0];
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115| 0 | 0 | Array looks like this when if clause 1st entered
// +---+---+---+---+---+---+
//**************************************************
//WHAT IS THE MEMORY ADDRESS OF ELEMENT 112 IN ABOVE
//WHAT IS THE VALUE OF ppi
//WHAT IS THE CONTENT OF THE STRUCT REFERRED TO BY pi
//**************************************************
// Now let's make a pointer (*ppi) to structure pi
*ppi = pi;
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115|112| 0 | After above line (*ppi = pi;) array
// +---+---+---+---+---+---+ now has 112 in the 4th element
pcon->argsq[ppi->isq].ppi = ppi;
ppi = &pcon->argpi[co][0];
}
I've asked some questions in the above.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
Dec 9th, 2014, 01:05 PM
#9
Re: Problem understanding how an array is initialized
The code, when it comes across "k" or "K" sets pc to 5.
In the array setting code it is looking for that 5, and if it sees it, it will move the first piece of the same color (if there is one) into the slot the King was going to go into, and insert the King in the first slot instead.
Code:
//This line assignes the current "slot" in the array to ppi, and increments the count of pieces of this color (pcon->argcpi[co]).
//So, in your example ppi points to slot 4, while pcon->argcpi[co] as been post incremented to 5 (4th slot is the 5th piece)
ppi = &pcon->argpi[co][pcon->argcpi[co]++]
//If the current piece is a King and there is at least one piece in the array of the same color (if not King is first where we want it)
//(We've already counted the King as a piece, so that is why it is checking > 1, not >= 1)
if ((pc == pcKING) && (pcon->argcpi[co] > 1)) {
//Set pi to point to the first piece of this color added to the array (ipiKING = 0)
PI pi = pcon->argpi[co][ipiKING];
//Set the position where the King was going to go, to this first piece
*ppi = pi
//Also update the square info's pointer to this pieces information
pcon->argsq[ppi->isq].ppi = ppi;
//Set ppi to now point to the first piece position, so the new piece (the King) will be stored there
ppi = &pcon->argpi[co][ipiKING];
}
//Continue creating the new piece (King or otherwise)...
Last edited by passel; Dec 9th, 2014 at 01:27 PM.
-
Dec 9th, 2014, 01:17 PM
#10
Re: Problem understanding how an array is initialized
Originally Posted by 2kaud
Code:
// Now let's make a pointer (*ppi) to structure pi
*ppi = pi;
This doesn't 'make a pointer'. This says put the contents of variable pi into the memory pointed to by variable ppi.
Already stated by pentagate in post #4
Originally Posted by 2kaud
Code:
if((pc == 5) && (pcon->argcpi[co] > 1))
{
PI pi = pcon->argpi[co][0];
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115| 0 | 0 | Array looks like this when if clause 1st entered
// +---+---+---+---+---+---+
//**************************************************
//WHAT IS THE MEMORY ADDRESS OF ELEMENT 112 IN ABOVE
//WHAT IS THE VALUE OF ppi
//WHAT IS THE CONTENT OF THE STRUCT REFERRED TO BY pi
//**************************************************
// Now let's make a pointer (*ppi) to structure pi
*ppi = pi;
//
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 |112|113|114|115|112| 0 | After above line (*ppi = pi;) array
// +---+---+---+---+---+---+ now has 112 in the 4th element
pcon->argsq[ppi->isq].ppi = ppi;
ppi = &pcon->argpi[co][0];
}
I've asked some questions in the above.
Questions:
1) WHAT IS THE MEMORY ADDRESS OF ELEMENT 112 IN ABOVE
2) WHAT IS THE VALUE OF ppi
3) WHAT IS THE CONTENT OF THE STRUCT REFERRED TO BY pi
Answers:
1) Don't know but what difference does it make. Wouldn't it be the base address of the
structure plus it's offset in the structure and isn't ppi the pointer to this structure
2) 0x004247AC is what my C IDE Editor says
3) See my post #5 and it is also listed in the .h file contents
Last edited by jmsrickland; Dec 9th, 2014 at 01:26 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 9th, 2014, 01:44 PM
#11
Re: Problem understanding how an array is initialized
1) ppi is the pointer to where memory is going to changed by the assignment. It probably isn't the memory address of element 112 and this is probably how 112 is getting into the 4th element.
2) This address is only useful if you also know the address asked for 1)
3) Sorry I wasn't clear. You have posted the pi struct definition previously - but I was asking for the values of pi struct at that point in the code.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
Dec 9th, 2014, 02:20 PM
#12
Re: Problem understanding how an array is initialized
OK, I gave you the values of the pi struct in my post #5 and also in post #3. It is not important to know the values of all members of the struct as long as you know that the isq member is 112 which I have stated many times. When I illustrate the values in the tables I have drawn I am only showing the values of the isq member because that is all I need to know. When you start asking about addresses and other technical things then I get confused and I am not sure what yo want to know or I don't know the answer anyway.
Wouldn't it be a lot easier than instead of asking me a lot of questions which I more than likely don't know the answers since I don't really understand what is going on and don't understand the questions to just take the code I posted which is the entire code for this problem and it works and compile and run it then you can see exactly what is happening then you would see the answers to your questions. That's what I would do if I was the one helping someone else.
Last edited by jmsrickland; Dec 9th, 2014 at 02:25 PM.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 9th, 2014, 02:45 PM
#13
Re: Problem understanding how an array is initialized
Did you read post #9?
Do you have any questions about it?
Although, I didn't try to compile the code you posted and comment on it. Don't have a good debug environment setup that I'm familiar with when it comes to C++, unfortunately.
-
Dec 9th, 2014, 03:57 PM
#14
Re: Problem understanding how an array is initialized
No, I missed it. Got to say that gives a lot of info about what is going on. Now I need to digest the comments and see if I can relate them to the actual instruction code line. If I have any questions about it I will get back here but first I need to try to fully understand your comments, which are very good, and get it straight in my head what is taking place.
Thanks a lot, passel, really appreciate your help here. Also, thank you 2kaud and penagate for your help too.
Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.
-
Dec 9th, 2014, 05:57 PM
#15
Re: Problem understanding how an array is initialized
Perhaps to help you digest, an illustrated version of post #9.
Code:
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
The loop is processing this string, so let's generalize and use the character from the string to represent the structures being manipulated
ppi points to each slot in turn as you go through the loop
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | | | | | |
// +---+---+---+---+---+---+
ppi/
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | | | | |
// +---+---+---+---+---+---+
ppi/
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | | | |
// +---+---+---+---+---+---+
ppi/
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | q | | |
// +---+---+---+---+---+---+
ppi/
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | q | | |
// +---+---+---+---+---+---+
ppi/ but we have a "k" and we want that in the first slot (for some reason)
PI pi = pcon->argpi[co][0];
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | q | | |
// +---+---+---+---+---+---+
pi= r ppi/ pi is a copy of the structure in the first slot
A nuance here is that while ppi is a pointer, pi is not. pi is a variable of the PPI structure type
*ppi = pi set what ppi is pointing to pi
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | q | r | | slot 4 now contains a copy of what was in slot 0
// +---+---+---+---+---+---+
ppi/
//Note that ppi is still pointing to slot 4, but slot 4 is now a copy of what was in slot 0 so is referencing PPI structure with r in it
//The square that pointed to the r in slot 0, now needs to point to the r in slot 4
pcon->argsq[ppi->isq].ppi = ppi;
ppi = &pcon->argpi[co][0]; 'have ppi now point at slot 0
// 0 1 2 3 4 5
// +---+---+---+---+---+---+
// 1 | r | n | b | q | r | |
// +---+---+---+---+---+---+
ppi/
//Now the code continues as before to finish adding the new piece, k, to slot 0.
//The next time around the loop, assuming we're working the same color, it will pick up again with slot 5 (since pcon->argcpi[co] = 5)
Last edited by passel; Dec 9th, 2014 at 06:01 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|