I don't know what your getting me into Deadron, I haven't had problems yet but I get fun lines of code like this when I use client vars instead of global ones:
client.challenger.client.battle_layer = null
Brings back memories of a large (and mainly useless) program we had to write for my C++ class using structs, of structs, of structs, and so on. We had lines like: town.store.history.inventory.tools
What fun :p
ID:193425
Jan 14 2002, 8:17 pm
|
|
In response to Deadron
|
|
My C programming teacher said she's basically met two kinds of programmers. Cowboys and Accountants. Cowboys fling code out of the blue, come up with original ways of doing things, and generaly get the code to work anyway they can. Accountants sit down, write out a plan of what they're going to do and how they're going to do it before they even get on the computer. I used to be mostly Cowboy where I would have huge functions and unexplained variables everywhere to get things to work but I'm becoming more of an accountant.
Here's one more step to a little more sanity in my code, thanks again for the tip. |
In response to English
|
|
My DM code is insane; as for C/C++ I suck with that, I don't know enough of it for it to be 'insane', back to DM, I sit down and code like lightning, maybe 1,000 lines, get bored and start over, I lack motivation to get anything done, my code isn't as messy as it used to be, it's mostly organized into procs, and multiple code files.
|
In response to Nadrew
|
|
Ahhh you to felt the horrors and evils of C++.
|
In response to Gojira
|
|
No, actually it's not that hard (yet).
|
In response to Nadrew
|
|
I sit down and code like lightning, maybe 1,000 lines, get bored and start over Deadron's advice on this subject is excellent. I'm slowly learning to correct my own aesthetic sins without throwing out everything I've worked so hard on. For example, if I'm disgusted with an ugly proc like this: proc/Bla() var/veeblefetzer/V = new() //Initialize the veeblefetzer bla bla bla //Power up the veeblefetzer bla bla bla ...I'll change it like this: proc/Bla() var/veeblefetzer/V = new() V.Initialize() V.PowerUp() Much tidier, and I don't lose my messy old work... I just hide it where I don't have to look at it until I want to. |
In response to Gughunter
|
|
It's not that I don't like my work, I just get bored with it and try something else, if I find my work ugly I comment it out and move on, then come back to it later, and redo it.
|
In response to Nadrew
|
|
The only thing that can scare me about C++ is recursion. We had to make a binary tree that alphabatizes text from a file, then prints it out in alphabetical, and reverse orders all with recursion.
The code itself is relatively simple but it can get really difficult to follow what is going on to diagnose problems. Chew on this for a bit (ok, so this is C not C++, but the ideas are the same, just different syntax): struct node { char word[MAX]; char cnt; char cnt2; struct node *lptr; struct node *rptr; }; struct node *insert(struct node *tree, char treeTemp[]) { struct node *temp; temp = malloc(sizeof(struct node)); strcpy(temp -> word, treeTemp); temp -> lptr = NULL; temp -> rptr = NULL; temp -> cnt = '0'; temp -> cnt2 = '1'; if(flag_dbf) printf("Function insert started\n"); if(tree == NULL){ tree = temp; } else if (strcmp(treeTemp, tree -> word) < 0){ if (temp != tree) free(temp); tree -> lptr = insert(tree -> lptr, treeTemp); return tree; } else if (strcmp(treeTemp, tree -> word) > 0){ if (temp != tree) free(temp); tree -> rptr = insert(tree -> rptr, treeTemp); return tree; } else if (strcmp(treeTemp, tree -> word) == 0){ if (temp != tree) free(temp); if(tree -> cnt2 == '9') { tree -> cnt2 = '0'; tree -> cnt++; } else tree -> cnt2++; } return tree; } Here's what prints it out: void printScreenList(struct node *tree) { if(flag_dbf) printf("Function printScreenList started\n"); if (tree != NULL) { printScreenList(tree -> lptr); printf("%s ", tree -> word); if(tree -> cnt > '0') printf("%c", tree -> cnt); printf("%c\n", tree -> cnt2); printCount++; if(printCount % 10 == 0) sleep(1); printScreenList(tree -> rptr); } } I'll try it like this, if it gets messed up when I post it I'll edit it. |
In response to English
|
|
English wrote:
The only thing that can scare me about C++ is recursion. We had to make a binary tree that alphabatizes text from a file, then prints it out in alphabetical, and reverse orders all with recursion. Recursion can be equally troublesome in any language, pretty much! However C/C++ make things much worse with all the pointer dereferencing crap. When I took a C class (one of the few things that combined to allow me to have my current career), one entire page of the midterm or final -- half the test -- was a set of questions based on more and more complicated pointer dereferencing. The kicker being, if you got question #3 wrong, then you couldn't answer #4 - #12 correctly because the answer to one was the start to the next. Afterward I called my partner and told him I couldn't possibly have gotten better than a C on the test, because there is no way I got all that right. By some miracle I was wrong -- I had gotten them all right! I have no idea how. |
In response to English
|
|
English wrote:
My C programming teacher said she's basically met two kinds of programmers. Cowboys and Accountants. I would describe myself as in between the two, really very close to the XP (Extreme Programming) model: I get the big picture in my head without worrying about too many details, then choose to work on the chunk I can get done most easily and pretty much start coding it, striving for as much simplicity as possible. When done with that I move on to the next chunk...if I find something getting complicated or unclear, I try to revise it until it is simple. One thing I've learned is not to stress too much...if you are in the middle of 20 lines of tough code and can't figure out a better way to do it, don't stop...keep going and finish the other 20 lines! Then, once the mess is working, and this is critical, immediately revisit it and try to break it down into simpler chunks. Don't wait, because later you'll forget how that 40 line mess works and you won't want to touch it or fix a problem in it. But always strive for as much clarity and simplicity as possible...your future self will love you for it when you return to the code. Guy also has a good lesson: You can make things better without having to rewrite every line. If you are revisiting old ugly code, just make the things better that you need to for now, the rest can come when it comes. Whatever you do, in most cases don't decide to throw it all out and rewrite it or you get into a vicious circle. There is a big exception to that: About 20% of code modules have cancer...they cause 80% of the bugs for the game. If you realize that you are working on a cancerous module that is just hopeless, then toss it out and start it from scratch. |
In response to Deadron
|
|
Eep. I'm learning Java at the moment, and for some reason Java has a convention of making all variables in a class private, so you're supposed to write accessor functions like that for everything. I personally find it repulsive. I completely understand and appreciate the use in it for this particular case, but for all cases... thats just annoying.
-AbyssDragon |
In response to Deadron
|
|
"There is a big exception to that: About 20% of code modules have cancer...they cause 80% of the bugs for the game. If you realize that you are working on a cancerous module that is just hopeless, then toss it out and start it from scratch."
I've had to do that several times, especially when I'm wading in new concepts. I usually end up commenting that block of code out, I'm a bit of a pack rat, and don't delete it until I've completely redone the new attempt. Trying to transfer parts of my code from the single player version of Shining into the multi-player one has taught me the value of making simple proc's and verbs that can pretty much stand alone. I used to think they were a waste of space, I don't anymore :p |
In response to Deadron
|
|
Pointers can get pretty messy, especially pointers to pointers, and arrays of pointers to structs and such. I suppose programming is something I love to hate. There's just something about it compiling and seeing "0 errors and 0 warnings." *Smacks himself across the cheek* Ok, I'm awake now.
Our C teacher mainly spared us from using too many pointers on the final, she had pitty on us after that project. Although, she did throw in a large section where we had to write the exact output of the program, she even had boxes to make sure we included every space. I got one of the outputs wrong about 80% through it and it threw off the rest of my output. It was only a comma, one stinking comma :( Well, at least she retired last year :) |
In response to AbyssDragon
|
|
AbyssDragon wrote:
Eep. I'm learning Java at the moment, and for some reason Java has a convention of making all variables in a class private, so you're supposed to write accessor functions like that for everything. I personally find it repulsive. I completely understand and appreciate the use in it for this particular case, but for all cases... thats just annoying. I basically support that approach, though have to admit that I stopped doing it everywhere in my own code (I was doing that for a while). Certainly it's a valuable technique if you are providing a library. By making everything accessor-based, you allow people subclassing portions of your library much greater flexibility in adding their own behavior. If they need to, say, add extra layer/density checking to your library's movement routines, then they may need to always be able to intercept calls for various values so they can modify them. Since you can't anticipate what they might need to do, your library should use accessors everywhere, including within its own functions. In other words, if the library needs to get a value, it must get the value through the accessor and not by going directly to the variable. |
In response to Deadron
|
|
Certainly it's a valuable technique if you are providing a library. By making everything accessor-based, you allow people subclassing portions of your library much greater flexibility in adding their own behavior. If they need to, say, add extra layer/density checking to your library's movement routines, then they may need to always be able to intercept calls for various values so they can modify them. Since you can't anticipate what they might need to do, your library should use accessors everywhere, including within its own functions. In other words, if the library needs to get a value, it must get the value through the accessor and not by going directly to the variable. You know what the worst thing is about me and coding in C++? DM is helping me learn C++... C++ is helping me keep DM clean. =P I still don't have any Get/Set functions in BYOND, however. But I'm only beginning to get into classes in C++ -- eventually it might become second nature for me in BYOND. (It's funny... I never understood pointers until I saw the line int* pnumber = &number; in the Wrox Press C++ Tutorial that shipped with my copy of MSVC++ 6.0 Std. My computer science teacher taught me that the & symbol gave a reference to an object rather than creating a duplicate, but he never actually told me why! Thank goodness I looked into it myself, because that one line affirmed my knowledge... *and* I just read that one line three days ago. =) ) |
In response to Spuzzum
|
|
Spuzzum wrote:
*and* I just read that one line three days ago. =) ) You could have saved some memory and copying time by using & right there... |
In response to Air Mapster
|
|
You could have saved some memory and copying time by using & right there... I don't have my hard drive set up as a web-host. =P |
I try hard to avoid this sort of thing a couple of ways...
If you are usually working within a mob, then you might want to add accessor functions...so let's say you are getting the client.challenger a lot, you might create a mob function to return that:
Then the code would look like:
var/client/challenger = ChallengerClient()
challenger.battle_layer = null
Or you can go further, so you never have to think about that client stuff, and put it all in accessor/convenience functions...like:
So then the code becomes:
That's the way I prefer it...boil all the nastiness down to one clear call that you will always understand immediately. And it means if you move the challenger var from the client to elsewhere in the future, you just have to change the function, you don't have to change all the rest of your code.