Thread: for loop gone mad

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    for loop gone mad

    my understanding of for loops is it sets the variable to 10 say then counts up/down to the next instruction. for example
    Code:
    for (x = 10; x > 0; x--)
    {
         printf("%d ", x);
    }
    will print out 10 9 8 7 6 5 4 3 2 1 where as if i set x >= 0 in the above loop it would print a zero as well.

    why then does the last for loop in the below code count down to 0 when x is >= 0 but if tell it to run till x > 0 its an infinite loop.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int board[8][8], start_x_coordinate, start_y_coordinate, finish_x_coordinate, finish_y_coordinate, temp_x, temp_y;
        int route[20][20][1], route_count = 0, move = 1, found_branch = 0;
        int a, x, y;
        int player = 0, multiplyer_y = player ? -1 : 1;
        int count_loop = 0;
    
        start_x_coordinate = 2;
        start_y_coordinate = 0;
        finish_x_coordinate = 4;
        finish_y_coordinate = 6;
        temp_x = start_x_coordinate;
        temp_y = start_y_coordinate;
        // inistalize board
        for (y = 7; y >= 0; y--)
        {
            for (x = 0; x < 8; x++)
            {
                if ((y % 2 == 0 && x % 2 == 0) || (y % 2 != 0 && x % 2 != 0))
                {
                    board[x][y] = 0; //good square
                    printf("%d ", board[x][y]);
                }
                else
                {
                    board[x][y] = 5; //invalid square
                    printf("%d ", board[x][y]);
                }
            }
            printf("\n");
        }
    
        // work out routes
        a = 1;
        while (a)
        {
            count_loop++;
            //check the diagonal squares are still on the board
            if (((temp_x - 2 >= 0 && temp_x - 2 <= 7) && (temp_y + 2 * multiplyer_y >= 0 && temp_y + 2 * multiplyer_y <=7)) &&
                ((temp_x + 2 >= 0 && temp_x + 2 <= 7) && (temp_y + 2 * multiplyer_y >= 0 && temp_y + 2 * multiplyer_y <=7)))
            {
                //record branch
                route[route_count][move][0] = 2;
                move += 1;
                //jump left
                route[route_count][move][0] = 0;
                temp_x -= 2;
                temp_y += 2 * multiplyer_y;
                move += 1;
            }
            else if((temp_x - 2 >= 0 && temp_x - 2 <= 7) && (temp_y + 2 * multiplyer_y >= 0 && temp_y + 2 * multiplyer_y <=7))
            {
                // jump left from whites point of view
                route[route_count][move][0] = 0;
                temp_x -= 2;
                temp_y += 2 * multiplyer_y;
                move += 1;
            }
            else if ((temp_x + 2 >= 0 && temp_x - 2 <= 7) && (temp_y + 2 * multiplyer_y >= 0 && temp_y + 2 * multiplyer_y <=7))
            {
                //jump right
                route[route_count][move][0] = 1;
                temp_x += 2;
                temp_y += 2 * multiplyer_y;
                move += 1;
            }
            else
            {
                route[route_count][move][0] = -2;
                repeat:
                if (move >= 0)
                {
                    for (x = move; x > 0; x--)
                    {
                        printf("array at %d = %d\n", x, route[route_count][x][0]);
                        if (route[route_count][x][0] == 2)
                        {
                            //last branch in the route found
                            found_branch = x;
                            break;
                        }
                    }
                    if (found_branch != 0)
                    {
                        temp_x = start_x_coordinate;
                        temp_y = start_y_coordinate;
                        move = 0;
                        for (x = 0; x <= found_branch; x++)
                        {
                            if (route[route_count][move][0] == 0)
                            {
                                temp_x -= 2;
                                temp_y += 2 * multiplyer_y;
                                move++;
                            }
                            else if (route[route_count][move][0] == 1)
                            {
                                temp_x += 2;
                                temp_y += 2 * multiplyer_y;
                                move++;
                            }
                            else
                            {
                                // just increment move to preserve branch record
                                move++;
                            }
                        }
                        // move is pointing at the move after the last branch so decrement move by 1 then jump right
                        route[route_count][move - 1][0] = 1;
                        temp_x += 2;
                        temp_y += 2 * multiplyer_y;
                        move += 1;
                    }
                    else
                    {
                        printf("no more branches\n");
                        break;
                    }
                }
                else
                {
                    printf("move was less than 1\n");
                    break;
                }
            }
            if (temp_x == finish_x_coordinate && temp_y == finish_y_coordinate)
            {
                printf("route found\n");
                //copy old route into new route
                for (x = move; x >= 0; x--) //<---- this one here
                {
                    route[route_count + 1][x][0] = route[route_count][x][0];
                }
                found_branch = 0;
                route_count++;
                goto repeat;
            }
        }
        printf("took %d goes to find a route\n", count_loop);
        return 0;
    }
    coop

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Maybe because (in the case of "x > 0") it doesn't copy the [0][0] element? Just maybe...
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    [0][0] element isnt set but dont know what the solution is all i changed was add some printf statements to try and track what it was doing and it all worked regardless of x>=0 or x>0 then i changed the start and finish co-ordinates and back to infinite loops

    i give up. i haven't the expertise to make it behave and bugs like this that come and go for no apparent reason just make an impossible job 1000 times harder.

    trouble is i don't trust code blocks this is just another wiered example of me not changing anything and it working all of a sudden. or conversely working for days then all of a sudden deciding something is wrong. and eclipse is just a waste of time.

    so any recommendations on an ide for linux mint that actually works would be appreciated.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It is likely that all non-trivial software has bugs, so the saying that "a poor workman blames his tools" is perhaps a little harsh. Nonetheless, before blaming your IDE, I'd work on improving your own programming practices:

    You're still writing functions that are way too long. I'm loathe to impose a limit, but this is what I suggest: if you find yourself writing a function that's more than 60 lines long, do your best to break it up into smaller functions as a soft limit; ideally, keep them under 30 lines. As a hard limit, force yourself to never ever write a function that's more than 90 lines long. As you get better at this, eventually you'll know when these limits can be broken, but for now stick to them like your growth as a programmer depended on them.

    Likewise, I'm of the opinion that goto can be validly used in C: as part of an error handling technique and to break out of deeply nested loops. But for now, force yourself to never ever use goto (i.e., take the "goto considered harmful" mantra at face value). Write a loop or a function instead. In this case, it looks like you have a good candidate for a function and to change that last if statement into a loop.

    Quote Originally Posted by cooper1200
    all i changed was add some printf statements to try and track what it was doing and it all worked regardless of x>=0 or x>0 then i changed the start and finish co-ordinates and back to infinite loops
    That sounds like the result of undefined behaviour. What I would do is #include <assert.h> and place assertions to make sure that the array indices are always valid such that you never write to the array (or read from it) out of bounds. In fact, when you have broken up your code into smaller functions, you can use this technique to check that the pre-conditions have been satisfied before doing the work of the function.

    Additionally, if your aim is to have a deliberate infinite loop, either write:
    Code:
    while (1)
    or the traditional:
    Code:
    for (;;)
    Don't set a variable to 1 then use it as the condition of the while loop: readers will then have to check the body of the loop to see if the variable was modified.

    Also, why write this:
    Code:
    int route[20][20][1];
    An array consisting of a single element might as well not be an array. You could have simplified to:
    Code:
    int route[20][20];
    Last edited by laserlight; 05-09-2019 at 05:10 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Firstly, I'd like to say that I really admire the way you are sticking with your programme: It is refreshing to see that sort of commitment on here from someone new!

    (Like laserlight) I'm going to suggest that you (as an exercise) rewrite your code using at least 15 functions like this..
    Code:
    void InitaliseBoard(...) 
    {
      for(blah) 
        for(blah) 
          InitialiseSquare(blah) ;
    
    } 
    
    ect...
    You can then check to see if InitialiseSquare is working, then check to see if InitialiseBoard is working.

    I'll also add that I've been using codeblocks for a long time can honestly say that it is a great IDE.

  6. #6
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    the whole concept of trying to work out paths around a board from point a in jumps of 2 is beyond my ability (anything that actually works anyway) the way i work rightly or wrongly is write a function that does the whole task then break it into smaller pieces for example where i have repeated code with only one thing changed this way i find debugging easier as im not having to remember what variable is what in which function and what pointer is changing what variable and where etc etc. its all there in the debug window (provided that works properly and i can expand it). posting 100+ lines of code in one go is proberbly off putting to those that help

    it isnt only this time that i have had wiered things happen. before now i have had curly braces disappear but the compiler knew they were there and when i cut and pasted the code into here the brace was there. i have written scanf calls for the compiler to throw errors only to comment them out and rewrite them exactly the same and its excepted. in fact i had it again just now having re-written the take piece function so the player enters the co-ordinates of the piece to take it threw an error on if (valid_square(board, entered_x + 1 * multiplyer_x, entered_y + 1 * multiplyer_y) == true) said it had no meaning (words to that effect then threw an error on the else saying else with no if. however it was quite happy with if (valid_square(board, entered_x + (1 * multiplyer_x), entered_y + (1 * multiplyer_y)) == true) when i turned it back to the origonal it was still happy.

    coop

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    Quote Originally Posted by Click_here View Post

    I'll also add that I've been using codeblocks for a long time can honestly say that it is a great IDE.
    may i ask what you are running it on please
    i am running it on linux on a virtual machine hosted on windows. so i do wonder if that has something to do with the issues especialy the radom freezes (for example if i close a project i have been working on for an hour or so i dont get the splash screen come up wanting to know if i want to start a new project or open one etc etc). or is there some setting that i haven't set or unintentionally unset

  8. #8
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry i dont mean to be grumpy it just adds an extra helping of difficulty when somthing as simple as a for loop doesnt do as it should ie count between x to y

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by cooper1200
    the way i work rightly or wrongly is write a function that does the whole task then break it into smaller pieces for example where i have repeated code with only one thing changed this way i find debugging easier as im not having to remember what variable is what in which function and what pointer is changing what variable and where etc etc.
    Unfortunately, that is indeed a wrong way of doing things: if you stick to that, you will only ever be able to write small programs, and you will never be able to work in a team on a large program. At some point, you will find that the complexity of the program exceeds your ability to implement it as a "whole task" by itself, so you won't be able to later break it down into smaller pieces as you won't even get there.

    What programmers do is to take large problems and break it into smaller ones, then work on the smaller ones independently (or at least as independently as we can) from the other pieces of the puzzle. This is at the level of program design, i.e., it might mean determining that a small program should consist of a certain set of functions, or it might mean that a large program should consist of a certain set of components, each of which is basically a library of functions.

    While programming, we might refactor a large function into smaller helper functions, but that's more at implementation level rather than program design, and is still a Good Thing. Either way, you don't have "to remember what variable is what in which function" because each function does one thing and does it well: the implementation of these functions can thus be "hidden" from each other, as long as the purpose, parameters, return value, and side effects of the functions are well defined (i.e., spell out the function interface). Likewise, if you're working on a component of a large program, you shouldn't need to know the nitty gritty implementation details of the components that other team members are working on, as long as the interfaces between components have been well designed.

    By the way, don't write:
    Code:
    if (something == true)
    instead, write:
    Code:
    if (something)
    This will help you reduce your use of parentheses.

    Likewise, don't write:
    Code:
    if (something == false)
    instead, write:
    Code:
    if (!something)
    While this won't necessarily help you reduce your use of parentheses, you might find it less verbose.
    Last edited by laserlight; 05-09-2019 at 07:03 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Windows 10 and Raspbian (on a Raspberry Pi).

  11. #11
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry to harp on about arrays again but laserlight made a comment that i shouldn't have an array
    Code:
    route[20][20][1]
    I realise that it isnt clear from the decleration what i intend to do with it because of the magic numbers but am i right in thinking that if i declared it like this:
    Code:
     route[20][20]
    that would give me so positions of 20 elements rather than the former of 20 positions each with 20 posiions each holding 1 element in the case of above a code for left turn right turn or branch

    many thanks
    cpop

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This declares an array of 20 arrays of 20 arrays of 1 int:
    Code:
    int route[20][20][1];
    This declares an array of 20 arrays of 20 ints:
    Code:
    int route[20][20];
    In the former, you must use route[x][y][0] whenever you want to access an int, even though you will never ever write route[x][y][1]. In the latter, you only need to write route[x][y] to do the same, i.e., the former confers no advantage over the latter, unless you have a fetish for writing "[0]" everywhere.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    god i can be thick move ie the last 20 can still be implimented as an index ie route[route_count][move] = 1

    am i trying to bite off too much here because i don't seem to have fully grasped the fundamentals
    coop

  14. #14
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Relax coop - You're doing great.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-27-2017, 08:05 PM
  2. Replies: 3
    Last Post: 09-22-2016, 09:08 AM
  3. Replies: 1
    Last Post: 03-28-2015, 08:59 PM
  4. Help - Collect data from Switch loop inside While loop
    By James King in forum C Programming
    Replies: 15
    Last Post: 12-02-2012, 10:17 AM
  5. Replies: 23
    Last Post: 04-05-2011, 03:40 PM

Tags for this Thread