Welcome to Dream.In.Code
Getting C# Help is Easy!

Join 136,837 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 1,545 people online right now. Registration is fast and FREE... Join Now!




C# Recursion help (for indie game)

 
Reply to this topicStart new topic

C# Recursion help (for indie game), Need help to fix problem with a recursive function for an indie RTS ga

Celledor
3 Oct, 2008 - 12:50 AM
Post #1

New D.I.C Head
*

Joined: 3 Oct, 2008
Posts: 1


My Contributions
Hi,
I'm working on an indie RTS game (using Truevision 3D for anyone that is interested) where the player can build walls by placing a wall section.

I'm working on a function(s) that will alter the models of wall sections when you add new sections nearby. So that you automatically have corner section, center sections etc. based of if there is walls around and if so where.

This function is recursive and I seem to have a problem with it. I thinks it lacks a proper "end condition" but I'm not sure where or what that should be. I get a 'System.StackOverflowException' error.

The function works so that it checks the section you just placed and change it, it the checks all nearby sections if they need to be change, and they check their nearby sections and so on until all necesary section has changed. This works fine for the first section that is added nearby another.

Here is the code (the code in under development so there might be a better way to do this):

...And sorry for the long code but i'm not sure which bits are impotrant to show or not.

This first function checks if the player is placing an object and calls the "checkWallType" function.
CODE

private void placeNewObject() {
            // If the player is placing an object
            if (bIsPlacing == true){
                // Can't place when paning the camera or the mouse is over the menu
                if (B1 == true && B1pressed == false && Input.IsKeyPressed(CONST_TV_KEY.TV_KEY_LEFTSHIFT) == false && MX < (screenWidth - 210)){
                    TV_2DVECTOR vec;
                    bool isFull = false;

                    // Check if any grid(s) under the placemarker(s) is full or not
                    int c = 0;
                    for (int i = 1; i <= iPlaceWidth; i++){
                        for (int j = 1; j <= iPlaceHeight; j++){
                            c++;
                            // Convert position to grid vector
                            vec.x = (float)(System.Math.Round((mGridMarker[c].GetPosition().x / 64)));
                            vec.y = (float)(System.Math.Round((mGridMarker[c].GetPosition().z / 64)));
                            if (GridHandler.isGridVecFull(vec) == true) { isFull = true; }
                        }
                    }

                    // If not then place the object and make the grid(s) full
                    if(isFull == false){
                        c = 0;
                        // Make the grid(s) full
                        for (int i = 1; i <= iPlaceWidth; i++){
                            for (int j = 1; j <= iPlaceHeight; j++){
                                c++;
                                // Convert position to grid vector
                                vec.x = (float)(System.Math.Round((mGridMarker[c].GetPosition().x / 64)));
                                vec.y = (float)(System.Math.Round((mGridMarker[c].GetPosition().z / 64)));
                                GridHandler.addFullGridVector(vec);
                            }
                        }

                        // Also make the "special wall grid" full if the object is a wall section
                        // This is so that we don't need to check all grids when dealing with walls
                        if (mPlaceMarker.GetMeshName() == "Wall"){
                            // Convert position to grid vector
                            vec.x = (float)(System.Math.Round((mGridMarker[1].GetPosition().x / 64)));
                            vec.y = (float)(System.Math.Round((mGridMarker[1].GetPosition().z / 64)));
                            GridHandler.addFullWallGridVector(vec);
                            checkWallType(vec.x, vec.y, mPlaceMarker);
                        }

                        // Create and add the object to the object handler
                        clsObject elem = new clsObject(Scene, mPlaceMarker, Globals);
                        ObjectHandler.addObject(elem);

                        bIsPlacing = false;
                        B1pressed = true;
                    }
                }
                else if (B2 == true) { bIsPlacing = false; }
            }
        }


This function do's the check for nearby sections and determines is the model need to be changed. This is where the recursion occurs.

CODE

private void checkWallType(float X, float Y, TVMesh mModel)
        {
            if (mModel != null){
                // There are walls all around - make a center + Section
                if (checkWallsAround(true, true, true, true, X, Y))
                {
                    changePlaceMarker(mModel, "Four_wall.tvm", "Wall");
                    checkWallType(X + 1, Y, ObjectHandler.getObjectByGridVec(X + 1, Y));
                    checkWallType(X - 1, Y, ObjectHandler.getObjectByGridVec(X - 1, Y));
                    checkWallType(X, Y + 1, ObjectHandler.getObjectByGridVec(X, Y + 1));
                    checkWallType(X, Y - 1, ObjectHandler.getObjectByGridVec(X, Y - 1));
                }
                // There is three walls around - make a T section
                else if (checkWallsAround(true, true, true, false, X, Y))
                {
                    changePlaceMarker(mModel, "Three_wall.tvm", "Wall");
                    mModel.SetRotation(mModel.GetRotation().x, mModel.GetRotation().y + 0, mModel.GetRotation().z);
                    checkWallType(X + 1, Y, ObjectHandler.getObjectByGridVec(X + 1, Y));
                    checkWallType(X - 1, Y, ObjectHandler.getObjectByGridVec(X - 1, Y));
                    checkWallType(X, Y + 1, ObjectHandler.getObjectByGridVec(X, Y + 1));
                }
                ...
                etc.
               Have removed the other types to shorten the code but this just continues through all posibles types of sections
                ...
            }
        }


These two support functions are used by "checkWallType" to do the check.

CODE
private bool checkWallsAround(bool A, bool B, bool C, bool D, float X, float Y){
            // Check is the grid vecs around vec is ful or not acording A,B,C and D
            if (WVF(X + 1, Y) == A && WVF(X - 1, Y) == B && WVF(X, Y + 1) == C && WVF(X, Y - 1) == D){
                return true;
            }
            return false;
        }


CODE

private bool WVF(float X, float Y) {
            // "Wall Vector Full" Checks if the grid if full (only check wall grids)
            TV_2DVECTOR vec;
            vec.x = X;
            vec.y = Y;
            if (GridHandler.isWallGridVecFull(vec) == true){
                return true;
            }
            else { return false; }
        }


A note is that all works fine the first time. If I place two sections between each other they change to two "end section" opposing each other (as they should) but when I add a third one to create a corner the error shows.

(And why is the code part width not to a 100 %)
User is offlineProfile CardPM
+Quote Post

Fast ReplyReply to this topicStart new topic
Time is now: 12/3/08 04:59PM

Live C# Help!

C# Tutorials

Reference Sheets

C# Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month