Jump to content

Recent Comments

April 2017 »

23242526 27 2829
- - - - -

A Complete Graphics-less Game #5 - World Map Part 2

text text based game game development beginners
4: Adsense

It's been a while since I've had a chance to update this. I've started working on another project with an old friend of mine and 3 others so I haven't had the time to really focus on this project, but I'll try to keep it up. I think this is a good project for me. As I dive deeper into it, I feel that I'll be able to explore some interesting concepts. So what have I been working on?

World Map Part 2
You don't have to be a genius to see that the game is very limited. I thought this was as good a time as any to try to load the world map from a file. In all of my recent programs, I haven't been using C++ streams to do any file loading. It's been years since I've done anything with it. Honestly, even using "std::cout" feel like weird to me. I grew up on printf and all it's derivatives, but I will try my best to use streams now. Remember, I'm making this program as a learning experience. I want to show that programmers don't have to jump into graphics programming from the beginning. They can instead test basic concepts and refine their skills using console applications.

Long story short, I'm going to build a loader to load the world map. As I said before, towns and the world map will use the same basic system as everything is really just locations connected by links. That's why do code uses the name AreaMap and not WorldMap. Here's a sample of the world map. I'm using text files for now as they are easy by hand.
"Washington"   1 3
"Frederick"    0 2 3 
"Pittsburgh"   1 4
"Baltimore"    0 1 4 5
"Philadelphia" 2 3 5
"Camden"       3 4 6
"Newark"       5 7
"New York"     6 8
"Boston"       7
I think this format is simple enough. It's merely the name of the location followed by a list of the links. The loader will perform minimal error checking so the file should be in the proper format.

Input File Streams in C++
Input file streams in C++ are quite simple. Just include the <fstream> header. I'll use the std::ifstream type because this is only for input. There are two ways to open the file: specifying the file in the object constructor or by using the open() method. Here's an example:
std::ifstream m_file_stream;
m_file_stream.open("test.txt", std::ios::in);

// or

std::ifstream m_file_stream("test.txt", std::ios::in);
After opening a basic text file, you can use it just like std::cin.

Loading the Area Map
For this loader, I decided to create a loader class that will handle loading the file. I decided to make it a class because to load the file in a clean way, I needed to use multiple function calls. Putting it in a single class made everything fit nicely. I also had to make some changes to the CAreaMap class so I can add links to a location after the location in the map has been created.

Here's the class definition:
// forward declaration of for the CAreaMap class
class CAreaMap;

/// \brief return values for the loader
enum LoaderResult
    LOAD_OK		= 0,
    LOAD_EOF	= 1,
    LOAD_FAIL	= 2

/// \brief Class for loading an area map
/// An Area map can represent all the places in a town or it can be used as a
/// higher level world map.
class CAreaMapLoader
        /// \brief Loads the Area Map from a file
        /// @param szFile the file name
        /// @param the_area_map the area map to load the data to
        /// @return the result of the load
        LoaderResult LoadFromFile(const char *szFile, CAreaMap &the_area_map);

        // Helper function to parse a line
        LoaderResult ReadLine(CAreaMap &the_area_map);

        // Helper function to search a string for a quoted sub-string
        LoaderResult GetNextStringToken(const std::string &inputline, size_t start, std::string &out, size_t &next);

        // Helper funtion to search a string for an int
        LoaderResult GetNextIntToken(const std::string &inputline, size_t start, int &out, size_t &next);

        // Helper funtion to search for the next numeric character
        size_t findNum(const std::string &in, size_t start);

        std::ifstream m_file_stream;
I made some helper functions to help me parse the file. Here's the code from LoadFromFile() and ReadLine():
LoaderResult CAreaMapLoader::LoadFromFile(const char *szFile, CAreaMap &the_area_map)
    // create the stream and open the file
    m_file_stream.open(szFile, std::ios::in);

    // check for success
    if(m_file_stream.fail()) return LOAD_FAIL;

    // read the lines
    LoaderResult result;
        result = ReadLine(the_area_map);
    } while(result == LOAD_OK);

    if(result == LOAD_EOF)
        // this isn't failue, we just processed all of the data
        result = LOAD_OK;

    // close the file

    return result;

LoaderResult CAreaMapLoader::ReadLine(CAreaMap &the_area_map)
    // read the first line, it should be the number of places
    std::string file_line;

    // check for eof before getting the line otherwise if the last line ends with eof, it won't be processed
    if(m_file_stream.eof()) return LOAD_EOF;

    // get the next line
    std::getline(m_file_stream, file_line);

    // check for blank lines
    if(file_line.size() < 1) return LOAD_OK;

    if(m_file_stream.fail()) return LOAD_FAIL;
    if(m_file_stream.bad()) return LOAD_FAIL;

    size_t cursor = 0;
    std::string location_name;

    // get the location name
    GetNextStringToken(file_line, cursor, location_name, cursor);

    // create the location without any links
    LocationIndex loc_index = the_area_map.AddLocation(location_name, 0);

    // get the links
    LoaderResult link_result = LOAD_OK;
    int link;
        link_result = GetNextIntToken(file_line, cursor, link, cursor);
        if(link_result == LOAD_FAIL) return LOAD_FAIL;
        else if (link_result == LOAD_OK)
            // add the links
            the_area_map.AddLocationLink(loc_index, link);
    } while(link_result == LOAD_OK);

    return LOAD_OK;
The code is very simple. I read an entire line from the string and then scan the line for the information that I need. Since I broke the code up into smaller sections, it's not some big convoluted mess.

Loading the map is as simple as this:
CAreaMapLoader map_loader;
map_loader.LoadFromFile("testmap.txt", m_WorldMap);
That's it. You can check the full source to see it working and as always, let me know if you have any problems compiling it.

Attached Files

Jun 16 2013 06:59 PM

I have also been experimenting on graphic-less game design as a throw back to the MUD era.

Jun 16 2013 11:09 PM
I think it's a good learning process and a way to explore other aspects of making games. I'm surprised more people don't try it.
Jun 18 2013 07:43 PM

Have you looked at pbbg.org? I am not sure if it fits your game, but it seems like this site does a fair amount of promoting.

Jun 19 2013 08:18 AM
Thank you for the information, but I don't think any of my projects qualify.
Jun 19 2013 07:35 PM

Ah, is your game a single player game?

Jun 20 2013 12:11 AM
I've made multiplayer games before, but I haven't decided how I will do this one yet as it's more of a side project. My main project is a multiplayer PC game that can use Direct X 9 or 11. I think for pbbg, the game needs to be browser based, but I haven't done any browser based work since college.

Note: GameDev.net moderates comments.