Beginner Exercises

Pages: 1... 89101112... 16
Mar 16, 2010 at 12:16pm
At least its wrong and I can feel good about not cheating myself from learning it :P

How are you Helios? been awhile :)
Mar 16, 2010 at 4:37pm
closed account (S6k9GNh0)
http://codepad.org/BGYvyUef

Took me awhile (about an hour and half) to make it but it works i guess....
It's also quite a bit sloppy. If anyone wants to clean up and add some functionality for a better example, please do so. I also didn't have the traps and treasure move although it should be relatively simple to add.
Last edited on Mar 16, 2010 at 4:41pm
Mar 16, 2010 at 10:28pm
I've modified your code quite a bit. I added comments here and there and modified some. I tried to emulate your coding style.

http://codepad.org/Rpx51Bi7

Also, although 508 lines looks like a lot, according to cloc only 375 of those are code; so I've only really added 140 lines (cloc says your original version is 235 lines of actual code).

I don't understand one major bug; the ClearScreen() function only works the first time it is called for me (on Arch Linux). I don't know how the windows version will fare for those of you on windows (credit to Duoas for both versions). It looks a lot better if you create a custom board by passing -e on the command-line...

Also, what's with the messages? I changed them if that was OK (if not, just change them back).
Serves you right, mate. Anyone with more money than me is bound to be cursed. That's why our world sucks.
Congrats, you win, rich bastard. Buy me a new computer!.
Last edited on Mar 17, 2010 at 3:08am
Mar 17, 2010 at 5:31am
Does that 500 line monster have graphics or is it just text 0_o
Mar 17, 2010 at 8:17am
It's just text. Bear in mind that it's only really 375 lines of executable code. The rest is comments and blank lines. I'll try and fix it up a little.
Last edited on Mar 17, 2010 at 8:23am
Mar 17, 2010 at 8:27am
Man, mine was like what.. 180 lines? (I think it was closer to 250) but still... what am I missing?
Mar 17, 2010 at 8:38am
474 lines: http://codepad.org/SQ29RzwB

Took away the command-line arguments thing. It was a useless extra feature.
Mar 17, 2010 at 8:57am
Still seems to be overkill, but whatever :)
Mar 18, 2010 at 12:31am
closed account (S6k9GNh0)
Blitz Coder, graphical games can get up to thousands upon thousands of lines of code.
Plus, the excessive amounts of lines in C++ comes through declarations instead of actual implementation. Procedural is smaller normally in this sense. The extra size doesn't make it slower. In this case, it just adds functionality and perhaps makes the executable a bit bigger.

1) I SUCK at naming classes. Actor in this context is simply something that does something visually in the game. Change it if you wish.

2) The inherited classes were going to have some extra functionality with bHasTreasure and bDead. Moving them of course is a lot of trouble and I figured I'd leave it like that for when I decided to do it. You can change it to typedefs if you want.

3) The Move<insertdirectionhere> functions pose a problem for a few reasons. One being that they don't use a user to move, they call the default user inside of the main class. I mentioned making it multiplayer and for that to happen, you'd need to pass a user.

But doing this also requires that the person implementing main create his own users which is fine if they really want to. The Move() function I think is more flexible and lets you do this though so I left them both in there.

4) The parameter _user for Board() and user, the member object, are different. What you pass to Board() is actually the character that represents the user. In order for the game to be single player or multiplayer, the most dynamic way to do it is to actually let the person implementing main instantiate his own User objects and then pass it to Board which is possible but not tested or do I know if it works.

5) And I made this out of boredom and relatively fast. Most of the goofy stuff came from my boredom lol

Things I think I could have done better:

I really think that I could have come up with a better positioning system. For instance, it's not that difficult to make the grid fit to that of the Cartesian grid. It would also be good to implement a 2D vector class and then pass that around. Really though, it's an example, and I thought I was getting to advanced lol. Good work chris.

Minor Changes: http://codepad.org/LgxU2Sjv

You can change whatever you want. I honestly don't care. Most of the functionality I added was random and is strange also made for a good wake up call for around 8 o'clock in the morning.
Last edited on Mar 18, 2010 at 1:06am
Mar 18, 2010 at 1:45am
closed account (S6k9GNh0)
This is a major bug fix: http://codepad.org/pnE7FXVe

* Fixed the error message on whole words.
* Added parameter to move functions.
* Fixed awkward silence if nothing is entered.
* Fixed bug where the user would disappear if attempting to move off the edge.

Next up, force the traps and treasure to move.
Last edited on Mar 18, 2010 at 1:46am
Mar 18, 2010 at 7:03am
closed account (S6k9GNh0)
Some new code that does some of what I wanted: http://codepad.org/usIaozvp
Uses ncurses coordinates which helps easily implement my coordinate plane.
I suppose I could get rid of it though, I wanted it mainly to fix the problem with screen clearing. In this case, we don't even refresh, we just move directly to the users, traps, and treasures locations and add them to the grid.

Not finished of course. Since this is a little bit beyond a beginners challenge now, I don't know if I'm going to even finish it lol.
Last edited on Mar 18, 2010 at 7:04am
Mar 18, 2010 at 8:29am
That was a good idea, using curses. I started writing my own; maybe I'll use ncurses too. I virutally the whole thing inside of 40 minutes, I haven't done the dungeoncrawl::draw() function yet, though, so nothing is printed. I also have internal support for multiple players but I can't think of a way of choosing a character. There has to be a limit or we'll end up with X being a player and X being treasure.

@computerquip,
I realised yesterday that the ClearScreen function I added had a bug. I copied Duoas' code wrong (so it's not his fault). Lines 220 and 221 (in the original code) should swap.

Anyway, let's do the graduation program now :D
Mar 18, 2010 at 10:26am
Graduation... your daring :P I will honestly say I am not at that point yet, but kudos to those who can do it :)
Mar 18, 2010 at 1:17pm
I probably can't but it's worth a shot.
Mar 18, 2010 at 6:30pm
closed account (S6k9GNh0)
It's taking me longer than I thought it would. Been working on it for about 2 hours now. Keep getting distracted.

http://codepad.org/owYMHecf

EDIT: noticed the error. Honestly haven't a clue why that's an error. I can't get my own compiler maxed out with error parameters to reproduce it.

EDIT2: Accounted for RadioactiveMutanVampireBunny.
Last edited on Mar 18, 2010 at 7:02pm
Mar 18, 2010 at 6:37pm
You like your enumerations, don't you?
Mar 18, 2010 at 7:04pm
closed account (S6k9GNh0)
Well, no, but I feel that that's the most proper way to get it done.
You have a better solution that helps with readable code?
Last edited on Mar 18, 2010 at 7:15pm
Mar 18, 2010 at 7:15pm
No. I was just commenting. Actually, I'm using a pair of enums too. It's a good way of replacing #define here.

Is the linked-list meant to be singly or doubly linked? I'm assuming doubly.

Edit: I don't know if this is the best way of creating a bunny:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
 * bunny(): construct a new bunny and assign it a random name
 */
bunny()
{
        /* Read in the list of names */
        std::ifstream bunny_name_file;
        bunny_name_file.open(BUNNY_NAME_FILE);

        std::vector <std::string> names = new std::vector<std::string>();

        if (bunny_name_file.is_open()) {
                while (bunny_name_file.good()) {
                        std::string line;
                        std::getline(bunny_name_file, line);
                        names.push_back(line);
                }

                bunny_name_file.close();
        } else {
                delete names;
                return;
        }

         /* Choose the name */
            size_t name_line = get_random<size_t>(0, names.size());

        /* Set up the new bunny */
        gender = get_random<gender_t>(MALE, FEMALE);
        colour = get_random<colour_t>(COLOUR_WHITE, COLOUR_SPOTTED);
        age = 0;
        name = names.at(name_line);

        back  = new node;
        if (back->prev)
            back->prev->next = back;
        else
            front = tail;

        /* Cleanup */
        delete names;
}

What do you think?
Last edited on Mar 18, 2010 at 7:27pm
Mar 18, 2010 at 7:35pm
closed account (S6k9GNh0)
@Names: To prevent using resources, I made a static vector that's accessible by the bunny class. So when you create a new bunny, it can access an already made list of names. The only downside is you have to call InitNames before you construct any bunny which is hardly a downside and easy to fix, but it's a one time thing and it will never have to be called again. After that, you can do: name = names[rand() % names.size()]; This one line accounts for the size of the name list, grabs a random name, and assigns each bunny a name.

@List: For now, I'm just using a std::list, although it's not difficult to implement my own.

@Duplicate names: Another problem I came across is stopping duplicate names. For now I'm allowing it since the challenege doesn't say anything about it but I thought up a few solutions to it.

1) Have two lists, a first name list, and a last name, lowering the probability of duplicate names exponentially.
2) Make a vector of used names and iterate through the list, restarting when the list is filled.

@Output: I decided to use tied ostreams to give output to files and console. I'm having a problem with it which I'm probably making a dunce mistake with, shown in the codepad post given below.

http://codepad.org/774jP38p
Last edited on Mar 18, 2010 at 7:49pm
Mar 18, 2010 at 7:49pm
Well, my name list is 15.3 kiB. That's why I DMA'd the name list. People are too bläse about memory usage; although it's hard to decide whether it's better to read 15k several times and never store it for more than how ever long it takes to do an std::vector::at and a string assignment, or if I should read it once and store it once. It's the memory usage vs. CPU usage battle.

I think I'll use an std::list to store my bunnies too. I can't be asked to implement my own; it means I have to write push_back, push_front, etc. etc. versions.

Is there an std::ringbuffer or something similar? That would be useful for memory wastage.

Edit: your rand % 99 should be rand % 101 for the 2% randomness thing.

@Output,
I created (with help) a little while ago my own implementation for this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* outlog: log output to two streams (a file, and std::cout or std::cerr)
 * The file is left open */
class outlog {
        private:
        	std::ofstream logfile;
                bool use_cout;
        public:
                outlog(std::string filename, bool __use_cout = true)
                {
                        logfile.open(filename.c_str());
                        
                        use_cout = __use_cout;
                }
    
                template <class T>
                outlog& operator<<(const T& out)
                {
                        ((use_cout) ? std::cout : std::cerr) << out;
                        logfile << out;
    
                        return *this;
                }
};


Also,
computerquip wrote:
GetSex()

If only this function existed in real life...
Last edited on Mar 18, 2010 at 8:26pm
Pages: 1... 89101112... 16