|
Trying to follow bitwise operations - Vivace Tutorial |
AceBlkwell
Member #13,038
July 2011
|
I'm trying to track the bitwise operation on a section of code. The author tells what the bits are as the code executes. The code works so obviously it's right. However, I can't follow it. It appears ALLEGRO_KEY_DOWN returns a bool status. Could that status be used to populate an array? Meaning would a true condition for ALLEGRO_KEY_DOWN make Assuming it does, then why would this section be needed? KEY_SEEN == 1. So ANDing it with zeros for the other 227 array elements seems like a waste and key[85] would already have a 1 in the last bit. Thanks |
DanielH
Member #934
January 2001
|
If you only want to know if a key is up or down, then yes, you could just use boolean. The Vivace code, however, tracks key presses not only ups or downs. What happens when a key is pressed and released before the next set of logic instructions? It would not recognize that a key was pressed at all. Once, logic is done, this code is processed: for(int i = 0; i < ALLEGRO_KEY_MAX; i++) key[i] &= KEY_SEEN; It resets the "released" state of all keys, but keeps the "seen" state. Meaning any key that is still being pressed will remain seen. ---- |
AceBlkwell
Member #13,038
July 2011
|
Daniel, Thanks for the explanation. I get the purpose of the loop now. By ANDing KEY_SEEN (00000001) with KEY_RELEASE | KEY_SEEN (00000011) we are resetting the KEY_RELEASE aspect of the number. Makes sense now. I'm still not understanding the original assignment to the array. I know this if statement checks to see if the pressed button is ALLEGRO_KEY_DOWN. if(key[ALLEGRO_KEY_DOWN]); but does it place the true condition (00000001) in the key array? In short would key[85] == 1 or 00000001? |
DanielH
Member #934
January 2001
|
Maybe it's me, but I don't understand what you are asking. 1 is the same thing as 00000001 1//1. at start memset
2key[ALLEGRO_KEY_DOWN] = 0
3
4//2. if it was pressed, it sets
5key[ALLEGRO_KEY_DOWN] = (KEY_SEEN | KEY_RELEASED)
6//key[ALLEGRO_KEY_DOWN] = 3
7
83. if it was released
9key[ALLEGRO_KEY_DOWN] &= KEY_RELEASED
10// key[ALLEGRO_KEY_DOWN] = 2 if it was pressed (3 & 2) = 2
11// key[ALLEGRO_KEY_DOWN] = 0 if it was not (1 & 2) = 0
12
134. after logic
14key[ALLEGRO_KEY_DOWN] &= KEY_SEEN
15// key[ALLEGRO_KEY_DOWN] = 1 if it was seen (1 & 1) = 1
16// key[ALLEGRO_KEY_DOWN] = 0 if it was only released (2 & 1) = 0
----- AceBlkwell said: I know this if statement checks to see if the pressed button is ALLEGRO_KEY_DOWN. if(key[ALLEGRO_KEY_DOWN]); This statement checks to see if the key is pressed or was pressed since last logic check. Quote: but does it place the true condition (00000001) in the key array? This question is where I'm confused on what you are asking. The code toggles the 1st and 2nd bits. It's true if any bit is set. zero = false |
AceBlkwell
Member #13,038
July 2011
|
Thanks for your patience Daniel. I think I see the source of my confusion. The if statements are only evaluating as the loop processes. The key array is updated by the EVENT_KEY lines. 1
2 switch(event.type)
3 {
4 case ALLEGRO_EVENT_TIMER:
5 if(key[ALLEGRO_KEY_UP])
6 y--;
7 if(key[ALLEGRO_KEY_DOWN]) //Only evaluates. It doesn't alter content of key[85]
8 y++;
9 if(key[ALLEGRO_KEY_LEFT])
10 x--;
11 if(key[ALLEGRO_KEY_RIGHT])
12 x++;
13
14 if(key[ALLEGRO_KEY_ESCAPE])
15 done = true;
16
17 for(int i = 0; i < ALLEGRO_KEY_MAX; i++)
18 key[i] &= KEY_SEEN;
19
20 redraw = true;
21 break;
22
23 case ALLEGRO_EVENT_KEY_DOWN:
24 key[event.keyboard.keycode] = KEY_SEEN | KEY_RELEASED; // the assignment of 00000011 done here
25 break;
26 case ALLEGRO_EVENT_KEY_UP:
27 key[event.keyboard.keycode] &= KEY_RELEASED;
28 break;
29
30 case ALLEGRO_EVENT_DISPLAY_CLOSE:
31 done = true;
32 break;
33 }
I think my confusion came from the if statement preceding the assignment statement. I assumed if we were looking at key[ALLEGRO_KEY_DOWN], it had the potential to have a value other than 0. First time through it wouldn't. Thanks again. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
This is not a good explanation of bitwise operations. First you need to know what each bitwise operator does. & 0 1 0 0 0 1 0 1 | 0 1 0 0 1 1 1 1
Bitwise AND only returns a 1 bit if both arguments are 1s. I don't know what 'seen' is supposed to mean, but I guess it is tracking key presses and not just key down. My input library does all this for you and more. For example, key presses and releases are tracked automatically, and all you have to do is check a boolean array. if (input_key_released(EAGLE_KEY_X)) { /// User let go of x key } if (input_key_press(EAGLE_KEY_Y) { /// user just pressed y } if (input_key_held(EAGLE_KEY_LCTRL) { /// L CTRL is held } // etc... I accomplish the same thing by using a dual array of keys. if (!oldkey[ALLEGRO_KEY_SPACE] && key[ALLEGRO_KEY_SPACE]) { /// space key was just pressed }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
DanielH
Member #934
January 2001
|
Bitwise AND returns a 1 if you're only ANDing the last bit. KEY_SEEN and KEY_RELEASED should be renamed to KEY_HAS_BEEN_PRESSED and KEY_HAS_BEEN_RELEASED As I said, you can do it your way if you're only concerned with key downs or not. I do. This is the first time looking at the Vivace tutorials. Had to read it twice to understand what was doing with those bits. |
AceBlkwell
Member #13,038
July 2011
|
Edgar, Being a bitwise novice, in my first attempt to follow the bit changes in the tutorial I came up with different results. The code worked so I knew I was misunderstanding it. I thought the if statements were doing multiple things in one line of code. Capturing the keystroke and then evaluating it some how. Looking back I see it was a crazy thought. No matter how you formulate it whatever is between a set of array [brackets] is just an index of the array. Daniel, I think I'm understanding the AND & OR part a little better. I was just getting confused on when the bits were actually changing. In my opinion the tutorials are pretty good. I think they "take the long way around" to allow the reader to see how things function. Normally I don't work so hard to understand every little thing. I copy/paste code then learn from the altering to fit my code. I allow for the fact there are things going on behind the scenes I'll never understand. |
DanielH
Member #934
January 2001
|
Ask away if you have any more questions Bitwise operations work on each bit. Bitwise AND if (value & mask_bits) // process if value and mask have one or more bits in common
Bitwise OR value |= set_bits; // set certain bits in value to 1
Bitwise XOR value ^= toggle_bits;
Bitwise NOT |
AceBlkwell
Member #13,038
July 2011
|
One last question on the subject. Are bitwise operators worth the effort? I can see the benefit if you are coding the next Elder Scrolls but I'm not seeing it with small console type games or something the average programmer would do. From a novice stand point, the benefit is for program run speed and minimizing memory usage. With today's machines is that as big a concern as it originally was? Just curious. |
Dizzy Egg
Member #10,824
March 2009
|
Bitwise will always be faster than + - / * etc, but whether or not to use them would be a design decision. As you say, on a massive multiplayer network game it would save valuable processing time. For small personal games I rarely use them, but there's no right/wrong answer, comes down to how comfortable you are using them, and whether the design demands their usage IMHO.
---------------------------------------------------- |
DanielH
Member #934
January 2001
|
They have their uses, but not for everything. For instance, Allegro uses them for setting flag options. I use either bitwise operations and/or bit fields to simplify things and decrease overhead. If forget what game it was, but years ago I made a map system. I wanted a more precise collision system then checking if the whole tile was blocked or not. I broke the tile down into smaller squares chunks. A segment was blocked if that bit was set or not. In my map editor, I could set/unset the entire tile or individual chunks. |
AceBlkwell
Member #13,038
July 2011
|
Thanks for the input guys. Since my programming projects have always been small and just to learn something new, I haven't developed a need for some of the programming advances that the more hard core programmers have. When learning something new (C to C++) I often see the advancements as unnecessarily complicated. So the benefits are not always obvious to me. |
DanielH
Member #934
January 2001
|
AceBlkwell said: unnecessarily complicated Yes! That's what we do. Regular programming is boring. We try a tweak it and make it harder. Something like tictactoe. You could make a simple int grid[9], but why? 1enum SQUARE_TYPE
2{
3 CELL_EMPTY = 0x00,
4 CELL_X = 0x01,
5 CELL_O = 0x10
6};
7
8typedef struct grid
9{
10 union
11 {
12 uint32_t ivalue;
13 struct svalue
14 {
15 uint32_t s0 : 2;
16 uint32_t s1 : 2;
17 uint32_t s2 : 2;
18 uint32_t s3 : 2;
19 uint32_t s4 : 2;
20 uint32_t s5 : 2;
21 uint32_t s6 : 2;
22 uint32_t s7 : 2;
23 uint32_t s8 : 2;
24 uint32_t fluff : 14;
25 };
26 };
27} grid;
|
AceBlkwell
Member #13,038
July 2011
|
Yeah I haven't had much exposure to unions. I've read about them a little. My code isn't as organized, especially on smaller projects. My TicTacToe didn't look anything like the section you had. I often get an idea or think "wonder if I could do...." and address that goal. Afterwards I create additional code to complete the program, test the section code, or error proof it . Ends up being "layered" approach. If I plan on using the code or displaying it, I'll clean it up by trying to take some of the clutter out. Add some comment lines etc. Not quite spaghetti code but just this side sometimes. I often get to the end of a problem and look at the complete code and think "man that looks awfully busy, there has to be a more direct approach". I've uploaded my TicTacToe program (cpp files). I couldn't think of systemic checks for win/lose status so I ended up checking each possible condition individually. You'll have to be lenient in your evaluation. I can't remember what I was trying out, and it did work at the time. Even beat me a few times . |
DanielH
Member #934
January 2001
|
The code I posted before was just a concept I've been working in my head. I planned to add another video to my library making TicTacToe. I SHOULD make it simple and use the brute force approach. However, I don't like simple. In school for by Bachelor's Degree, I took an AI class. In it we had to write a tictactoe game in Java. In it, we also had to implement some simple AI using the minmax algorithm. Not particular hard to do. need a function to evaluate a grid. When it was the computers turn, it looked at all available moves for O. For each move, evaluate the grid. Pick the minimum values (might have multiple minimums). If the grid value was -10, it won. It the minimum grid value was zero, then it would do another layer deeper. This time it would calculate all possible moves for X and find the maximum value. If any grid values were again zero, then go another layer deeper. Repeat until win/lose or no more moves To the point: each layer and iteration requires a copy of the previous. While an array of 9 integers is not much. 1 integer is better. |
Dizzy Egg
Member #10,824
March 2009
|
There’s a lot to be said for unit testing and OO design, at least where A5 is concerned. The trial and error approach of A4 seems way to popular whilst being way too archaic for me. I’ve had a few beers.
---------------------------------------------------- |
AceBlkwell
Member #13,038
July 2011
|
As you say Dizzy I often take a trial-and-error approach which has its pitfalls. When I went to college the languages offered were Cobal & Fortran. I even took two semesters of IBM’s RPG. I don’t recall any PC style languages like C being offered. From what I could tell most were mainframe based. The learning I’ve done has been on my own with no real demand for my programs. Like a self-taught musician, I’m sure I’ve developed bad habits that are now crippling when trying to expand how I think / pseudo code programs. Daniel, I’ve never had the luxury to mess with AIs. Sounds like it would be cool. I do try to get the computer to generate objects automatically / mathematically when I can figure out how to. However, there are times (TicTacToe) where I just write in the possible conditions and have the computer compare. Example, my most recent game was a board game with a maze aspect. I tried for days to figure out how to get the computer to generate the maze automatically. This would allow it to be more random. I was close I could feel it. Eventually I gave up and created 20 maps within the code. With the 20 maps and 81 potential starting points the chance of duplication seems minimal. Again, manually doing something that could be done automatically. But I digress . |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Premature optimization is evil. Make it correct first, then worry about how fast it will be. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|