Answers in this post are>>
int score = 656; char scorestring[50]; snprintf(scorestring, sizeof(scorestring), "%d", score); int scorelength = strlen(scorestring); for (scoredigit = 0; scoredigit < scorelength; scoredigit++) { textprintf_ex(activepage, font, 0 + (scoredigit * 17), 0, makecol(255, 255, 255), -1, "%i", scorestring[((scorelength - 1) - scoredigit)] - 48); }
also replacing the snprintf(scorestring, sizeof(scorestring), "%d", score); with
itoa(score, scorestring, 10);
will do the same thing. But it is considered non standard.
Original question.
I am using a new numbering system in my game where as before I just put the text on the screen. What I can not figure out is how to.
1. Find out how many places my score uses. I.E. If score was 1423 it would be 4 places
2. How to take just 1 number from the score. I.E. 1423 is the score and I wanted just the 3rd number I would have 4.
I used to have an old program in Qb that a Binary number and made it decimal. Dont know how acurate it was but it did what I am looking for or close to it.
DIM BinNum(1 TO 300) AS STRING, NStringNum(1 TO 300) AS LONG CLS INPUT "Binary String:_ ", BinNum$ FOR LoopStart = 1 TO LEN(BinNum$) BinNum$(LoopStart) = MID$(BinNum$, LoopStart, 1) NStringNum(LoopStart) = VAL(BinNum$(LoopStart)) NEXT FOR LoopStart = 1 TO LEN(BinNum$) DecimalNum = DecimalNum + NStringNum(LoopStart) * (2 ^ (LEN(BinNum$) - LoopStart)) NEXT PRINT DecimalNum
other then the example I don't know what it is called if even pointed in the correct direction I could do a little research on it. But I never really learned more then the basics of C/C++ and when straight into allegro.
sprintf(someChar, "%i", score)?
And then work with someChar to get the lengths and digits.
int digit_count = (int)log10(num) + 1;
Just don't try it on 0.
Thanks that was what was needed
digit_count = (int)log10(score) + 1;
digit_value = (int)(score / pow(10, 1)) % 10;
textprintf_ex(active_page, font, 0, 0, makecol(255, 255, 255), -1, "Digits in score %i Digit Value %i", digit_count, digit_value);
Only thing is if score is 0 digit_count returns a large negitive number but that is easy to get around with a simple check if the number is not positive just post a 0 score.
Thanks a lot.
Well at the very beginning of the game the score is going to be 0 so that value will be returned until the score is >0
Finished Result:
digit_count = (int)log10(score + totalscore) + 1; for (scoredigit = 0; digit_count > scoredigit; scoredigit++) { draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15); } digit_count = (int)log10(lives) + 1; if ((int)log10(lives) + 1 < 0) draw_sprite(active_page, numbers[0], 275, 15); for (livesdigit = 0; (int)log10(lives) + 1 > livesdigit; livesdigit++) { draw_sprite(active_page, numbers[(int)(lives / pow(10, livesdigit)) % 10], 100 - livesdigit *17, 15); }
I have one last problem with this though if score + totalscore = 1000 it passes 0000 and if score + totalscore = 2000 it passes 1000 till 10000 it passes 19000 for some reason the 4th digit doesn't display properly until the score = 1001 and so on. I don't see where the problem is any one else?
Some where in here is the problem I just can't seem to isolate it.
digit_count = (int)log10(score + totalscore) + 1; for (scoredigit = 0; digit_count > scoredigit; scoredigit++) { draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15); }
I wondered if you were doing something like this. It seems to me that you are reinventing the printf function:
myfont = load_font("font.bmp"); textprintf_right_ex(active_page, myfont, 275,15, -1, -1, "%d", score);
The above assumes a multi-color font. Replace the first -1 by the color if your font is a solid color.
If you really must do your own thing here (and I doubt it), I'd stick with the sprintf way because it's easier to read:
char score_str[100]; sprintf(score_str, "%i", score); int x = 275, y = 15; for (int i=strlen(score_str)-1; i>=0; --i) { int digit_value = score_str<i> - '0'; draw_sprite(active_page, numbers[digit_value], x, y); x-= 17; }
| 1 | //cant remember header file c++ |
| 2 | |
| 3 | |
| 4 | extern string NumberToString(int Number) |
| 5 | { |
| 6 | ostringstream converter; |
| 7 | converter << Number; |
| 8 | return converter.str(); |
| 9 | } |
| 10 | |
| 11 | int num= 346; |
| 12 | |
| 13 | if(NumberToString(num)[0]=='0') |
| 14 | { |
| 15 | |
| 16 | } |
| 17 | if(NumberToString(num)[0]=='1') |
| 18 | { |
| 19 | |
| 20 | } |
Edit: wow i type slow 3 post came out of nowhere
Edit2: i think my way is better because you can get ohold of the 1st 2nd and nth numbers
Edit3:
the 4th digit doesn't display properly until the score = 1001 and so on. I don't
i think your bug lie in the (int) casting
i think your bug lie in the (int) casting
explaing please.
Whats odd is that if I
draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, 3)) % 10], 275 - scoredigit *17, 15);
instead of...
draw_sprite(active_page, numbers[(int)((score + totalscore) / pow(10, scoredigit)) % 10], 275 - scoredigit *17, 15);
It shows the value as correct and if I use
it also shows the correct values but when I use the variables only the thousands place is messed up and only when the value is exact 1000,2000,10000 ect.
Hey Circle , this might help.
Until I decide to write my own function to convert integers into strings , I've been using Itoa
Link to usage at cplusplus.com
http://www.cplusplus.com/reference/clibrary/cstdlib/itoa.html
Example
| 1 | int score = 12345; |
| 2 | char numberstring[50]; |
| 3 | for (x = 0 ; x < 50 ; x++) {numberstring[x] = '\0';} |
| 4 | |
| 5 | itoa(score , numberstring , 10); |
| 6 | |
| 7 | // Now "12345" is stored in numberstring |
| 8 | // use strlen to find out it is 5 digits |
| 9 | // then access the digit like this |
| 10 | int score_length = strlen(numberstring); |
| 11 | |
| 12 | // example if you want the hundreds digit this will access it |
| 13 | numberstring[((score_length - 1) - 2)]; |
| 14 | |
| 15 | // If you are looking for the 10^x digit place this should do it |
| 16 | numberstring[((score_length - 1) - x)]; |
| 17 | // x = 0 is ones place and so on. |
Then if you wanted to convert the digit you found from numberstring use
atoi (in stdlib.h) to change it back to an integer.
Hope this was helpful.
Ok BIG thanks for all the help from everyone you all are great.
Ended up with
itoa(score + totalscore, scorestring, 10); itoa(lives, livesstring, 10); int score_length = strlen(scorestring); int lives_length = strlen(livesstring); for (scoredigit = 0; scoredigit < score_length; scoredigit++) { draw_sprite(active_page, numbers[scorestring[((score_length - 1) - scoredigit)]- 48], 275 - scoredigit *17, 15); textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%i ", scorestring[((score_length - 1) - scoredigit)]- 48); } for (livesdigit = 0; livesdigit < lives_length; livesdigit++) { draw_sprite(active_page, numbers[livesstring[((lives_length - 1) - livesdigit)]- 48], 100 - livesdigit *17, 15); }
Works fantastic now and the 4th digit errors are gone. Odd I am still using all the same variables. Besides digit_value and digit_count but they were just replaced with lives_length and score_length and either way still worked with the iota. I also decided to skip a lot of work and just subtract 48 from the itoa value to get the correct numbers I needed.
I suggest you use snprintf() instead of itoa(). itoa() is non-standard. Plus, you get some extra memory safety you wouldn't get otherwise.
[EDIT]
You're transforming the digit into ASCII, then transforming it into an integer, and then printing it (which will, again, transform it into ASCII). Just print it as a char instead.
textprintf_ex(screen, font, SCREEN_W/2 - (4*19) - scoredigit * 30, SCREEN_H/2, makecol(255,255,255), -1, "%c", scorestring[(score_length - 1) - scoredigit]);
And might I suggest you stop draw directly to the screen? Use a buffer of some kind.
the part that posts to the screen is my test line. It is removed when things are working correctly. every thing else uses buffers.
I am using bitmaps to place the numbers on the screen instead of dealing with fonts.
You can have an allegro font and replace the digit bitmaps in that font with your own digit bitmaps. That would save you the hassle of rewriting the functionality (well, too late now
), but it may also be faster.
I suggest you use snprintf()
Please, please, please, follow this advice.
And use qualifiers on the snprintf call. For example, if you want to display a score acrade-style, with a maximum of 8 digits, and leading zeroes, you'd do:
snprintf(buf, "%08.8i", score);
itoa() is non-standard.
Nooo!! My whole world just collapsed...
Only one problem the snprintf makes no sence to me in
int snprintf (char *buffer, size_t n, const char *format, ...);
format. I was for some reason never able to completely understand those. How ever if you have a small example I seem to understand those easier.
| 1 | itoa(score + totalscore, scorestring, 10); |
| 2 | itoa(lives, livesstring, 10); |
| 3 | itoa(mouseh, mousehstring, 10); |
| 4 | int scorelength = strlen(scorestring); |
| 5 | int liveslength = strlen(livesstring); |
| 6 | int mousehlength = strlen(mousehstring); |
| 7 | for (mousehdigit = 0; mousehdigit < mousehlength; mousehdigit++) |
| 8 | { |
| 9 | stretch_sprite(activepage, numbers[mousehstring[((mousehlength - 1) - mousehdigit)] - 48], 500 - mousehdigit * 10, 12, 10, 10); |
| 10 | } |
| 11 | for (scoredigit = 0; scoredigit < scorelength; scoredigit++) |
| 12 | { |
| 13 | draw_sprite(activepage, numbers[scorestring[((scorelength - 1) - scoredigit)] - 48], 275 - scoredigit *17, 15); |
| 14 | } |
| 15 | for (livesdigit = 0; livesdigit < liveslength; livesdigit++) |
| 16 | { |
| 17 | draw_sprite(activepage, numbers[livesstring[((liveslength - 1) - livesdigit)] - 48], 100 - livesdigit *17, 15); |
| 18 | } |
currently this is what I am using and it works. Maybe there is something else besides itoa that I can use and keep much this same code?
lease, please, please, follow this advice.
And use qualifiers on the snprintf call. For example, if you want to display a score acrade-style, with a maximum of 8 digits, and leading zeroes, you'd do:
snprintf(buf, "%08.8i", score);
You've missed a parameter there.
I was for some reason never able to completely understand those. How ever if you have a small example I seem to understand those easier.
<snip code sample>
currently this is what I am using and it works. Maybe there is something else besides itoa that I can use and keep much this same code?
Replace the first two lines with:
The first parameter of snprintf() is the character array (string) you're writing to, the second parameter is the maximum number of characters to write (though, it will actually copy this ammount minus one characters, since it appends a null terminator). From there after, you write a format specifier, and supply additional variables, as you would to any of the printf() variants.
The first parameter of snprintf() is the character array (string) you're writing to, the second parameter is the maximum number of characters to write (though, it will actually copy this ammount minus one characters, since it appends a null terminator). From there after, you write a format specifier, and supply additional variables, as you would to any of the printf() variants.
Now that I understand. ^^
But actually it would be
works great and easier to understand. Thanks. Why is the mouseh given a &d instead of %d in your example and livesstring getting the value from score + totalscore. Although I like the mistakes. I think it gave me an error because my int wasn't given enough space to hold &mouseh. and when the score and lives went up at the same time that was just a given.
Why is the mouseh given a &d instead of %d in your example
Because it was 2am, and I'd been drinking for a couple of hours.
They should of course both be %d, as you figured out.
and livesstring getting the value from score + totalscore.
Same as above.
I think it gave me an error because my int wasn't given enough space to hold &mouseh.
There was no &mouseh in my example. The line I wrote should have just given you a warning about having too many format arguments.
Well anyways it was tons of help. Thanks.