Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Input routine works, then does not

Credits go to torhu for helping out!
This thread is locked; no one can reply to it. rss feed Print
Input routine works, then does not
Bob Keane
Member #7,342
June 2006

I am trying to write a battleship clone. I have an input routine using allegro ustrs and have a weird issue.

Input routine:

#SelectExpand
1#include "my_includes.h" 2 3void validate_input(ALLEGRO_USTR* str); 4void print_board(char board, ALLEGRO_FONT * script); 5void test_input(int height, ALLEGRO_FONT *font) 6{ 7 8 bool finished = false; 9 ALLEGRO_USTR* my_string; 10 my_string = al_ustr_new(""); 11 int position; 12 bool redraw = false; 13 extern bool invalid; 14 invalid = false; 15 ALLEGRO_EVENT_QUEUE * event_queue = NULL; 16 17 event_queue = al_create_event_queue(); 18 if(!event_queue) { 19 fprintf(stderr, "failed to create event_queue!\n"); 20 return; 21 } 22 23 al_register_event_source(event_queue, al_get_keyboard_event_source()); 24 25 26 al_draw_text(font, white, 0, height, ALLEGRO_ALIGN_LEFT, "Enter the coordinates: "); 27 while(!finished){ 28 29 ALLEGRO_EVENT ev; 30 al_wait_for_event(event_queue, &ev); 31 switch(ev.type){ 32 33 case ALLEGRO_EVENT_KEY_CHAR: 34 if(ev.keyboard.unichar >= 32){ 35 al_ustr_append_chr(my_string, ev.keyboard.unichar); 36 position = (int)al_ustr_size(my_string); 37 redraw = true; 38 }//ev.keyboard.unichar 39 40 else if(ev.keyboard.keycode == ALLEGRO_KEY_BACKSPACE){ 41 al_ustr_truncate(my_string, position - 1); 42 redraw = true; 43 }//keycode == backspace 44 45 else if(ev.keyboard.keycode == ALLEGRO_KEY_ENTER){ 46 finished = true; 47 validate_input(my_string); 48 redraw = true; 49 }//allegro_key_enter 50 51 else if(ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 52 finished = true; 53 }//switch ev.type 54 55 if(redraw){ 56 if(!invalid){ 57 redraw = false; 58 invalid = false; 59 al_clear_to_color(black); 60 al_draw_textf(font, white, 0, height, ALLEGRO_ALIGN_LEFT, "You entered %s", al_cstr(my_string)); 61 print_board('s', font); 62 al_flip_display(); 63 }// !invalid 64 65 else{ 66 finished = false; 67 redraw = false; 68 al_clear_to_color(black); 69 al_draw_textf(font, white, 0, height, ALLEGRO_ALIGN_LEFT, "Invalid input: %s", al_cstr(my_string)); 70 print_board('s', font); 71 al_flip_display(); 72 al_rest(1.0); 73 al_ustr_truncate(my_string, 0); 74 al_clear_to_color(black); 75 al_draw_text(font, white, 0, height, ALLEGRO_ALIGN_LEFT, "Enter the coordinates: "); 76 print_board('s', font); 77 al_flip_display(); 78 79 }//invalid 80 }//redraw 81 }//not finished 82 83 al_ustr_free(my_string); 84 al_destroy_event_queue(event_queue); 85 86 al_rest(1); 87 88}//test_input

Validate routine:

#SelectExpand
1 2#include "my_includes.h" 3void validate_input(ALLEGRO_USTR* str) 4{ 5 extern bool invalid; 6 int string_size; 7 string_size = (int)al_ustr_size(str); 8 int my_char = al_ustr_get(str, 0); 9 int my_int = al_ustr_get(str, 1); 10 int my_int2 = al_ustr_get(str, 2); 11 12 if(string_size < 2 || string_size > 3) 13 invalid = true; 14 15 if(my_char < 'a' || my_char > 'j') 16 invalid = true; 17 18 if(my_int < '1') 19 invalid = true; 20 21 if(my_int > '9') 22 //invalid = true; 23 24 if(my_int2 > '0') 25 invalid = true; 26 else 27 if(my_int > '1') 28 invalid = true; 29}

The bug appears to be line 22 in the validate_input function. When I run the program with the line uncommented, it rejects any input other than a1. Commented it works okay. Any ideas?

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
If we get apple juice from squeezing apples, and we get prunes from drying out plums, where does prune juice come from?
Hi Randall Monroe.

torhu
Member #2,727
September 2002
avatar

What are the valid values of my_int2? And why are you doing if(my_int > '1') at the end there?

I would write it more like this:

#SelectExpand
1#include "my_includes.h" 2 3// Returns true if input is valid, false otherwise 4bool validate_input(ALLEGRO_USTR* str) 5{ 6 size_t string_size = al_ustr_length(str); 7 int32_t my_char = al_ustr_get(str, 0); 8 int32_t my_int = al_ustr_get(str, 1); 9 10 if(string_size < 2 || string_size > 3) 11 return false; 12 13 if(my_char < 'a' || my_char > 'j') 14 return false; 15 16 if(my_int < '1' || my_int > '9') 17 return false; 18 19 if(string_size > 2 && al_ustr_get(str, 2) > '0') 20 return false; 21 22 // Is this right? 23 if(my_int > '1') 24 return false 25 26 return true; 27}

Bob Keane
Member #7,342
June 2006

my_int2 should be the third character of input, if my understanding of ustr points are correct. I am weak on size_ts so I am going my way for simplicity.


 23
 24    if(my_int2 > '0')
 25        invalid = true;
 26    else
 27        if(my_int > '1')
 28        invalid = true;

The above code was my way of making sure the user was not entering values like 20 or 39. Looking at it now, I think I see the problem. I think I need to flush the queue as well. Thanks for the reply.

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
If we get apple juice from squeezing apples, and we get prunes from drying out plums, where does prune juice come from?
Hi Randall Monroe.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Make sure the encoding of the USTR is utf-8 before comparing with ascii like that....

The thing about comparing code points to char values will only work if your encoding is UTF-8 and is therefore compatible with ascii.

Go to: