Unexpected repeating of my output function

T

Tom Lam lemontea

Hi all,
This is my very first post here, I've seriously tried some programming
on C, and shown below is my very first program(So you can expect it to
be very messy) that I wrote after I've learned the basics. However,
the output function I wrote seems to repeat unneedingly for 2 times.
My trial on solving it myself have failed. Anyone willing to point out
where the problem lies will be greatly appreciated. Thanks.

**** Source code ****

/****************************************
* Log: *
* 8/13/2004 11:05pm *
* So, finally, after hours and hours of *
* programming and debuging, this *
* program is at last playable.(Runs off *
* to play) *
****************************************/
#include <stdio.h>

int randn();
int findzero();
void adj();
int count();
void swaparray();
int checksolve();
void output();

main()
{
printf("Welcome to the slider puzzle Alpha Version! \n");
printf("Press enter to start, or press q then enter to exit. \n");
char command;
int enter;
scanf("%c",&command);
if (command=='q') enter=0;
else enter=1;

while (enter==1)
{
int length=3;
int i;
int puzzle[9]={1,2,3,4,5,6,7,8,0};
printf("Initialising...please wait...");
int scramble=randn(200)+200;
for (i=0; i<scramble; ++i)
{
int a,b,temp,data[5];
a=findzero(puzzle);
adj(length,a,data);
temp=randn(12) % data[4] + 1;
b=count(data,temp);
swaparray(puzzle,a,b);
}
int moves=0;
while (!checksolve(puzzle,length))
{
output(puzzle,moves,length); //Seems to have problem here
scanf("%c",&command);
if (command=='q')
{
enter=0;
break;
}
int a,b,position,data[5];
a=findzero(puzzle);
adj(length,a,data);
int invalid=0;
switch (command)
{
case 's':
position=0;
break;
case 'd':
position=1;
break;
case 'a':
position=2;
break;
case 'w':
position=3;
break;
default:
invalid=1;
}
if (invalid==0)
{
if (data[position]==9) continue;
b=data[position];
swaparray(puzzle,a,b);
++moves;
}
}
if (enter==0) break;
printf("Congrat!You solved it in %d moves. \n",moves);
printf("Would you like to play again?(1 for Yes and 0 for No)
\n");
scanf("%d",&enter);
}
printf("Goodbye!");
}


int randn(int n)
{
return rand()%n+1;
}

int findzero(int *array)
{
int i=0;
while (1==1)
{
if (*(array+i)==0) return i;
++i;
}
}

void adj(int length,int position,int *array)
{
int last=0;
if (position<length) *array=9;
else
{
*array=position-length;
++last;
}
if (position%length==0) *(array+1)=9;
else
{
*(array+1)=position-1;
++last;
}
if ((position+1)%length==0) *(array+2)=9;
else
{
*(array+2)=position+1;
++last;
}
if ((position+length)>=(length*length)) *(array+3)=9;
else
{
*(array+3)=position+length;
++last;
}
*(array+4)=last;
}

int count(int *array,int num)
{
int i=0,count=0;
while (count!=num)
{
if (*(array+i)!=9) ++count;
++i;
}
return *(array+i-1);
}

void swaparray(int *array,int a,int b)
{
int temp;
temp=*(array+a);
*(array+a)=*(array+b);
*(array+b)=temp;
}

int checksolve(int *array,int length)
{
int i=0,correct=0;
while (i<(length*length))
{
if (*(array+i)==i+1) ++correct;
++i;
}
if (correct==(length*length)-1) return 1;
else return 0;
}

void output(int *array,int moves,int length)
{
int i=0;
printf("\nNumber of moves: %d \n",moves);
while (i!=(length*length))
{
printf("[%d]",*(array+i));
++i;
if (i%length==0) printf("\n");
}
printf("Your move:");
}

**** Sample Output ****
Welcome to the slider puzzle Alpha Version!
Press enter to start, or press q then enter to exit.

Initialising...please wait...
Number of moves: 0
[2][3][8]
[4][0][1]
[6][7][5]
Your move:a

Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:
Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:



Yours faithfully,
Tom Lam
 
P

Pedro Graca

Tom said:
This is my very first post here, I've seriously tried some programming
on C, and shown below is my very first program(So you can expect it to
be very messy) that I wrote after I've learned the basics. However,
the output function I wrote seems to repeat unneedingly for 2 times.
My trial on solving it myself have failed. Anyone willing to point out
where the problem lies will be greatly appreciated. Thanks.

**** Source code ****
while (!checksolve(puzzle,length))
{
output(puzzle,moves,length); //Seems to have problem here
scanf("%c",&command);

printf("\n\nDEBUGGING ... command is [%c]=(%d)\n\n", command, command);

if (command=='q')
{
enter=0;
break;
}
<snip>


There are a few more things wrong with your code
main is incorrectly declared
main doesn't return a value
mixed declarations and code
you don't have the declaration for rand()
you used a C++ comment to indicate the error

Solve them too!


Happy Coding :)
 
L

lemontea.Tom

Hi,

Pedro said:
printf("\n\nDEBUGGING ... command is [%c]=(%d)\n\n", command, command);

I've added this, and something real funny comes out! (See the end of
this post for the new sample output)
There are a few more things wrong with your code
main is incorrectly declared

I've added type int in front of main(I hope my memories on the faq
concerning giving types to main is correct)
main doesn't return a value

Added return;
mixed declarations and code

Sorry, but I didn't understand this. Can you be more specific?
you don't have the declaration for rand()

Isn't it built-in at the standard library?
you used a C++ comment to indicate the error

Well, I didn't know that was a c++ comment, but I perfer to use // for
inline small comment and /* */ for larger comment.
Solve them too!


Happy Coding :)

**** New Sample Output ****
Welcome to the slider puzzle Alpha Version!
Press enter to start, or press q then enter to exit.

Initialising...please wait...
Number of moves: 0
[2][3][8]
[4][0][1]
[6][7][5]
Your move:a


DEBUGGING ... command is [a]=(97)


Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:

DEBUGGING ... command is [
]=(10)


Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:

So, what should I do next? Thanks you very much again.
Yours faithfully,
lemontea
 
P

Pedro Graca

Hi,

Pedro said:
printf("\n\nDEBUGGING ... command is [%c]=(%d)\n\n",
command, command);

I've added this, and something real funny comes out! (See the end of
this post for the new sample output)

What happens if, instead of pressing 'w', 'a', 's', or 'd', you press
Added return;

return 0; /* program completely succesfully */
return not_zero; /* program completed with errors */
Sorry, but I didn't understand this. Can you be more specific?

In C89 you cannot have declarations mixed with code (you can do that in
C99)

int main(void) {
int count; /* declares 'count' */
count = 0; /* initializes 'count' -- first "real" code */
int age; /* declares 'age' -- incorrect for C89 */

return 0;
}

For that program to be C89 compatible you have to move the
line "count = 0;" after all declarations.
Isn't it built-in at the standard library?


Well, I didn't know that was a c++ comment, but I perfer to use // for
inline small comment and /* */ for larger comment.

// comments are valid for C99, invalid for C89

**** New Sample Output ****
Welcome to the slider puzzle Alpha Version!
Press enter to start, or press q then enter to exit.

Initialising...please wait...
Number of moves: 0
[2][3][8]
[4][0][1]
[6][7][5]
Your move:a

'a' ' said:
DEBUGGING ... command is [a]=(97)


Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:

DEBUGGING ... command is [
]=(10)

This is the said:
Number of moves: 1
[2][3][8]
[4][1][0]
[6][7][5]
Your move:

So, what should I do next?

'k' said:
Thanks you very much again.

You're welcome.
 
P

Peter Shaggy Haywood

Groovy hepcat Tom Lam lemontea was jivin' on 22 Oct 2004 01:02:04
-0700 in comp.lang.c.
Unexpected repeating of my output function's a cool scene! Dig it!
This is my very first post here, I've seriously tried some programming
on C, and shown below is my very first program(So you can expect it to
be very messy) that I wrote after I've learned the basics. However,
the output function I wrote seems to repeat unneedingly for 2 times.

I know, with about 80% certainty, what the problem is without even
looking at your code yet. This is addressed by the FAQ
(http://www.eskimo.com/~scs/C-faq/top.html), which you should have
read before posting. I'll give you a clue: it's to do with your input.
When you are inputting, how many keys do you actually press to enter
one single-letter command to your program?
My trial on solving it myself have failed. Anyone willing to point out
where the problem lies will be greatly appreciated. Thanks.

#include <stdio.h>

You need the following too, for rand().

#include said:
int randn();
int findzero();
void adj();
int count();
void swaparray();
int checksolve();
void output();

All the above function declarations are K&R style. This is not the
best. It's better to make them prototypes. A prototype is a function
declaration that specifies the number and types of all its parameters.
For example:

void output(int *array, int moves, int length);

Note that the names of the parameters are optional, and don't have to
match the names in the function definitions. So, you could, for
example, use:

void output(int *, int, int);
or
void output(int *foo, int bar, int baz);

(It's best to use the same names, though, to avoid confusion.)

Get in the habbit of writing "int main(void)". This was always
(stylistically) better than just "main()", but in C99 the return type
must be specified, at least.

int main(void)
{
printf("Welcome to the slider puzzle Alpha Version! \n");
printf("Press enter to start, or press q then enter to exit. \n");
char command;

You cannot declare variables after statements (unless the
declarations are within an inner block) in C90. You can in C99, but
it's a good idea to try to support both C90 and C99, for maximum
portability. So, all block scope declarations should go at the top of
the block in which they appear - before any other statements.
int enter;
scanf("%c",&command);
if (command=='q') enter=0;
else enter=1;

while (enter==1)
{
int length=3;
int i;
int puzzle[9]={1,2,3,4,5,6,7,8,0};
printf("Initialising...please wait...");
int scramble=randn(200)+200;
for (i=0; i<scramble; ++i)
{
int a,b,temp,data[5];
a=findzero(puzzle);
adj(length,a,data);
temp=randn(12) % data[4] + 1;
b=count(data,temp);
swaparray(puzzle,a,b);
}
int moves=0;
while (!checksolve(puzzle,length))
{
output(puzzle,moves,length); //Seems to have problem here

C++ style comments do not exist in C90. They were adopted in C99.
But it is best not the use them, especially when posting here. They
tend to wrap, if long, and break the code.
Besides, that's not where the problem is. The problem is in the way
you handle input. I'll leave it as an exercise for you to determine
what's wrong by reading the FAQ.
scanf("%c",&command);
^^^^^^^^^^^^^^^^^^^^^
Here's the real culprit. And it's just as I thought.
if (command=='q')
{
enter=0;
break;
}
int a,b,position,data[5];
a=findzero(puzzle);
adj(length,a,data);
int invalid=0;
switch (command)
{
case 's':
position=0;
break;
case 'd':
position=1;
break;
case 'a':
position=2;
break;
case 'w':
position=3;
break;
default:
invalid=1;

To give you another clue what the problem is, try putting the
following statement here:

printf("Invalid input '%c' (%d)\n",
command, command);

Yes, this is similar to what Pedro Graca told you to do. But doing it
here may just give you an extra idea what's going on, if you use a
brain cell or two.
}
if (invalid==0)
{
if (data[position]==9) continue;
b=data[position];
swaparray(puzzle,a,b);
++moves;
}
}
if (enter==0) break;
printf("Congrat!You solved it in %d moves. \n",moves);
printf("Would you like to play again?(1 for Yes and 0 for No)
\n");
scanf("%d",&enter);
}
printf("Goodbye!");
}


int randn(int n)
{
return rand()%n+1;

Not the best way to go about it. See the FAQ.

I've given you enough to go on with for now. I haven't looked at the
rest of your code. But if there are problems with it, no doubt they'll
make themselves known in due course.

[Snip the rest of the code.]

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
L

lemontea.Tom

Hi,
Thank you very much for all your help!
Since I don't have as much free time I focused only on the "major"
error--the problem with scanf.
After searching and thinking for a good while, I decided the best way
to solve it is to understand scanf fully--so I searched C++ reference
guide-those things, and decided that

scanf(" %c",&command);

(Note the white space between " and %)
May work, and at least, the "repeated output" problem have gone now.
If this is the correct answer, please reply, or else, please point me
out the answer.

Once again,thank you,Pedro Graca, and Peter " Shaggy" Haywood also.
Yours faithfully,
lemontea
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top