Problem with vector inside a class - arrays

I have this code inside a class:
void SendStones()
{
int currenthole = hole;
int lastplace = 0;
for(int i=0;i<stns.size();i++)
{
while(1)
{//Calculate new currenthole
if(currenthole == 13) { currenthole = 7; break;}
if(currenthole == 14) { currenthole = 6; break;}
if((currenthole<=12 && currenthole > 7) || (currenthole<=6 && currenthole > 1)) { currenthole--; break;}
}
lastplace = stns.size()-1;
hole[currenthole]->ReciveStone(stns[lastplace]);//PROBLEM
stns.pop_back();
}
}
vector<Stones*> stns;
so it makes this error:
invalid types `int[int]' for array subscript
what's the problem?i don't understand.
Thanks.

It looks like hole is a simple int, and you're trying to subscript it. Is that what you mean to do? Where is hole declared?

Hole is a really big class,
SendStones is a function member in the class.
I won't send the whole file but i can say that
hole[currenthole] is a Hole *hole[14];
It's a big program and project so i sent the related code needed.
Here's the code of the ReciveStones function:
void ReciveStone(Stone *rcvstone)
{
stns.push_back(rcvstone);
}

Based on what you said in your answer, hole is a pointer to n Hole objects. That means your code isn't doing what you think it's doing.
int currenthole = hole;
This is storing an address value pointing to the first object in your array collection, which means that this code
if(currenthole == 13) { currenthole = 7; break;}
if(currenthole == 14) { currenthole = 6; break;}
if((currenthole<=12 && currenthole > 7) || (currenthole<=6 && currenthole > 1)) { currenthole--; break;}
is probably nonsense.
It doesn't explain why you're getting the "invalid types `int[int]' for array subscript" error. Are you sure that there's not a second declaration of type int named hole?
--Actually, re-reading what you wrote, I'm even more certain you're not doing what you think you're doing. SendStones is a member of the class Hole, correct? Check that your Hole class doesn't have a hole member variable inside it. That is probably the problem, since it will be found before any global variable called hole (if I remember my scoping rules correctly).

Related

connect four - comparison of evaluation - c

I try to implement the minimax algorithm into my connect four game.
I´m done with the evaluation-function and halfway done with the algorithm-function.
I just can`t find the solution for the "last" problem. Here are my functions:
void minimax(field f){
int i;
field c;
convert_1D_to_2D(f, c);
for(i=0;i<COLS;i++) {
if(can_throw(c, i) == 0) {
throw(f, i);
convert_1D_to_2D(f, c);
if((is_winner(c) == 0) && (is_board_full(f) == 0)) { //no winner, board not full
minimax(f);
}
else if(is_winner(c) == 1) { //there is a winner
evaluate_turn(f);
//compare evaluation
undo_turn(f);
}
else if(is_winner(c) == 0 && (is_board_full(f) == 1)) { //no winner, board full
evaluate_turn(f);
//compare evaluation
undo_turn(f);
}
}
}
The field is an array with f[COLS*ROWS+1], where f[0] is the depth and the other elements save in which columns were thrown. the "c"-board represents the "graphical" board with 0 for free, 1 for player 1 and 2 for player 2.
static int evaluate_turn(field f) {
field c;
convert_1D_to_2D(f, c);
if (((f[0] % 2) == 1) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, max for him || +1
return 1;
}
else if (((f[0] % 2) == 2) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, max for him || +1
return 1;
}
if (((f[0] % 2) == 1) && (current_player == 2) && (is_winner(c) == 1) ) { //player 2 won, counting for 1 || -1
return -1;
}
else if (((f[0] % 2) == 2) && (current_player == 1) && (is_winner(c) == 1) ) { //player 1 won, counting for 2 || -1
return -1;
}
else if ((is_board_full(f) == 1) && (is_winner(c) == 0)) { //draw || 0
return 0;
}
So my problem is, that i can't think of a clean solution to compare the evaluation bottom to top. I really think, that I don't need to introduce a new datastructure (which would get way too big). It's like the solution is right in front of me but i can't grab it.
Is it possible to just compare the evaluation on the "way back" of the recursion? If yes, how?
Or do I really need to introduce something new more complex? Or maybe I'm missing off something completely?
Thanks!
Or do I really need to introduce something new more complex? Or maybe
I'm missing off something completely?
Unfortunately the answer is the latter. Minimax is not a void function. It returns the value of the node that it represents. That is how evaluation is compared. You are also missing another fundamental concept. Your function only considers terminal nodes to be those where the game is won or the board is full. While this is technically true, no real minimax function works that way. The number of nodes would be around 7^48, so your function would literally take upwards of ten years to terminate on a modern pc. What real world minimax functions do is set a maximum depth for the search to reach (unless you add tree pruning expect this to be 5 or 6), and consider all nodes at that depth to be terminal and evaluate them using a heuristic (inexact guess) evalation function. In connect four this could be based on something like the number of three in a rows. Another mistake you made is calling your eval function if you know there is a winner. If you know which player won than return the proper value straight out, no need to call the expensive eval function. You also cannot stream line your function for both min and max as you did. You must either create a seperate function for min and max, or use the negamax variant.
My advise: It seems you don't really understand how the algorithm should be implemented. Read up on minimax and negamax psuedocode.

Alternative syntax of combining multiple condition check

I am implementing a simple if statement in c, where I am comparing the value of integer 'tile' to four other integers: w, a, s and d.
Here is my code:
if(tile == w || tile == a || tile == s || tile == d )
{
printf("legal\n");
return true;
}
While the above is correct, the syntax is tiresome. Is there a more elegant way of writing the condition "'tile' is one of the following integers..."
I'm a novice in programming so I apologise as I suspect the answer is very obvious. I've failed to find it addressed elsewhere though.
While eyalm's answer is maybe the one you're looking for, just wanted to chime in to point you to a more important factor here (as you mentioned, "I'm a novice in programming"), which is "Write code which is easier for humans to understand".
While the bitwise approach is shorter, it generally appears to be more difficult to understand a maintain, as it grows.
A cleaner approach will be (while it takes more effort to write the code), stick to the if ( a || b || c) syntax, or a fall-though switch case. It gives better readability.
In case your options grows longer (that you may need a horizontal scroll bar), you can consider adding a function to get the required value checked and use the return value in the condition in the if statement.
The bottom line is, there is no right or wrong way, only choose the way which make the code more readable and maintainable.
Two options i can think of...
bitwise
#define TILE_W 0x0001
#define TILE_A 0x0002
#define TILE_S 0x0004
#define TILE_D 0x0008
if (tile&(TILE_w|TILE_A|TILE_S|TILE_D))
{
printf("legal\n");
return true;
}
switch-case
switch (tile)
{
case w:
case a:
case s:
case d:
printf("legal\n");
return true;
default:
return false;
}
Solution for improvement can depend on values which you compare with.
If w, a, s and d are integer numbers that have consecutive values (e.g. 10, 11, 12 and 13), if-statement can use condition for boundaries:
if( tile >= w && tile <= d) { printf("legal\n"); }
If values are disparate (e.g. 6, 32, 142, 55), you can use switch..case construction, like
switch (tile)
{
case w:
case a:
case s:
case d:
printf("legal\n");
break;
default:
printf("ILLEGAL\n");
break;
}
Also you can use setting flag in one or multiple if as
int legal = 0;
// checking can be in different places of code
if (tile == w)
legal = 1;
if (tile == a || tile == s)
legal = 1;
if (tile == d)
legal = 1;
if( legal )
{
printf("legal\n");
}
And consider storing w, a, s and d values as array of valid values, so loop can be used for checking:
int valArr[] = {101, 151, 333, 7}; // you can add any number of values here
int i;
int legal = 0;
for(i = 0; i < ( sizeof(valArr)/sizeof(valArr[0]) ); i++)
{
if(valArr[i] == tile)
{
legal = 1;
break;
}
}
if( legal )
{
printf("legal\n");
}
else
{
printf("ILLEGAL\n");
}

Slot Machine Game In C - Printing Reels Issue

I'm trying to create a small slot-machine game that has three reels and four possible symbols for each reel (bell, orange, cherry, and horse).
I started by generating a random value between 1-4 and now I'm trying to get the first reel to print out the text associated with the generated values.
Here is the code, I hope someone can help and point out why it doesn't work and how I can fix it. From the code below I was expecting the program to print out 3 different pieces of text that were associated with the generated numbers but instead "Cherry" prints out three times.
// Generates 3 different random values between 1-4 and stores them within the slotVal array.
int slotVal[3], counter;
srand(time(NULL));
for (counter = 0; counter < 3; counter++) {
slotVal[counter] = rand() % 4 + 1;
}
// Checks generated values and prints associated text.
for (counter = 0; counter < 3; counter++) {
if (slotVal[counter] = 1) {
printf("Cherry");
}
else if (slotVal[counter] = 2) {
printf("Bell");
}
else if (slotVal[counter] = 3) {
printf("Orange");
}
else
printf("Horseshoe");
}
Your if statements are wrong, you are assigning(=) not comparing(==):
// Checks generated values and prints associated text.
for (counter = 0; counter < 3; counter++) {
if (slotVal[counter] == 1) {
printf("Cherry");
} else if (slotVal[counter] == 2) {
printf("Bell");
} else if (slotVal[counter] == 3) {
printf("Orange");
} else {
printf("Horseshoe");
}
}
If you do if(something = 1) the condition evaluated will be the 1 because the assignment operator returns the assigned variable. Since 1 evaluates to true, your first condition would be met and the other else blocks would be ignored.
Some useful tips to avoid this particular error are:
Do if(1 == variable) instead of if(variable == 1), because the first raises a compilation (if you only use one = sign) error and the second doesn't;
Define a name for the comparison, for example: #define EQUALS == which will allow you to do if(variable EQUALS 10)
When you program in C, always enable all compiler warnings that you can find. C is not a beginner-friendly language, and it provides you with plenty of ways to shoot yourself in the foot. Enabling compiler warnings protects against a few of these ways.
When you use GCC, at least enable the -Wall -Wextra warnings. They will warn you that in the if conditionals, you are using the assignment operator = instead of the comparison operator ==.

C Struct read/ write garbage value to file

I am diving into C after long time and struggling with reading and writing struct to the simple text file. I debuged this prog and I found out its reading and writing garbage value to the file. Can someone help me. Here is my code
#define MAX_UserName_LEN 16
#define MAX_Password_LEN 8
#define MAX_FileName_LEN 32
struct userDetails
{
char userName[MAX_UserName_LEN];
char password[MAX_Password_LEN];
};
int registration(struct userDetails userInfo)
{
FILE *userDb;
userDb= fopen("UserDataBase.txt","a");
if(fwrite(&userInfo,sizeof(userInfo),1,userDb))
{
fclose(userDb);
return 1;
}
else
{
return 0;
}
}
int authenicate(struct userDetails userInfo)
{
FILE *userDb;
struct userDetails temp;
userDb = fopen("UserDataBase.txt","r");
while(!feof(userDb))
{
fread(&temp,sizeof(temp),1,userDb);
if (temp.userName==userInfo.userName && temp.password==userInfo.password)
{
printf("Logged In Sucessfully");
return 1;
}
}
return 0;
}
In main function, I an just declaring one struct variable and accepting user input into that struct and passing it to both above mentioned functions.
The first major problem I see is here:
if (temp.userName==userInfo.userName && temp.password==userInfo.password)
You are trying to compare strings with ==. You need to use strcmp() instead:
if (strcmp(temp.userName, userInfo.userName) == 0 &&
strcmp(temp.password, userInfo.password) == 0)
I'm not sure if this has anything to do with the "garbage" you're getting, but it's definitely an error.
As your code stands right now, it will never enter the if-statement.
Write a short code, which prints the userlist, so you'll see wheter the file contains garbage or not.
Anyway, passwords should be scrambled somehow. Even a dumb solution is better than nothing, just to make it non-readable for human eyes. Say, for (n = 0; n < strlen(pwd); n++) pwd[n] ^= 0x55;.

not declared in this scope creating a loop

I am tying to make a loop that repeats itself for 100 seconds, but I keep on getting the same error and I am getting so frustrated that even if it is the most basic thing I will not notice, could someone please tell me what I am doing wrong? I would really appreciate, thanks.
void loop(void) {
for ( int i = 0; i <= 100; i++) {
getFingerprintIDez();
delay (50)
}
}
uint8_t getFingerprintID() {
uint8_t attmpet = data.getImage();
switch (attempt) {
case FINGERPRINT_OK:
break;
case FINGERPRINT_NOFINGER:
Serial.println("No fingerprint detected");
return attempt;
delay (500);
}
attempt = data.image2Tz();
switch (attempt) {
case FINGERPRINT_OK:
Serial.println("Image converted");
break;
case FINGERPRINT_IMAGEMESS:
Serial.println("Image too messy");
return attempt;
}
attempt = data.fingerFastSearch();
if (attempt == FINGERPRINT_OK) {
Serial.println("Found a print match!");
} else if (attmpt == FINGERPRINT_NOTFOUND) {
Serial.println("Did not find a match");
return attempt;
}
Serial.print("Found ID #"); Serial.print(data.fingerID);
Serial.print(" with confidence of "); Serial.println(data.confidence);
return data.fingerID;
}
int getFingerprintIDez() {
uint8_t attempt = data.getImage();
if (attempt != FINGERPRINT_OK) return -1;
attempt = data.image2Tz();
if (attempt != FINGERPRINT_OK) return -1;
attempt = data.fingerFastSearch();
if (attempt != FINGERPRINT_OK) return -1;
Serial.print("Found ID #"); Serial.print(data.fingerID);
Serial.print(" with confidence of "); Serial.println(data.confidence);
return data.fingerID;
delay (1000);
}
The message I keep getting is:
exit status 1
'getFingerprintIDez' was not declared in this scope
Thank you all
In general, your indentation is a mess, and that's making it hard for you to see where the problem is. It looks to me like this line:
int getFingerprintIDez()
is a likely culprit for the error you're getting. I haven't counted braces, but I think your getFingerprintIDez() function might actually be defined inside the loop() function, and C doesn't allow that sort of thing.
So take care in formatting your code so that the various blocks are carefully indented the right amount -- C doesn't care about indentation, but it'll make it easier for you to see what blocks are inside what other blocks. Count open and close braces if you need to, and make sure that the definition of loop() ends before the definition of getFingerprintIDez() begins.
missing ; after delay(50)
unused variable 'attmpet'
'attmpt' was not declared in this scope
read the error messages from the first, not the last. the last error is only a consequence of the previous errors

Resources