Solved

How to: Implement a linked list instead of a txt file...

Posted on 2008-10-04
4
620 Views
Last Modified: 2012-08-13
On my Hangman game, I used to read the words from a text file named "words.txt". Now I am trying to implement a linked list and use it instead of the text file. So far, I already created a node structure and modified my EnterWord(), SearchWord(), and PrintWords() methods, which are working well. However, I am unsure about how to read the words from the linked list instead of the text file on my NewWord() method. Perhaps my eyes are tired, but I also would like someone to review what I did and tell me if I can do it on a better way, if possible.
Thanks!
///////////////////////////////////////////////////////////////

Definition of class Engine.h

///////////////////////////////////////////////////////////////

#ifndef Engine_h

#define Engine_h
 

#include "Word.h"

#include "Graphics.h"

#include <map>

#include <sstream>

#include <fstream>

#include <string>

#include <cstdlib>

#include <ctime>

#include <iostream>

#include <set>

#include <vector>
 

class Engine

{

	public:

		struct node

		{

			string data;

			node *next;

		};
 

		Engine();

		//Default constructor

		~Engine();

		//Destructor

		void InitializeGame();

		//Function to initialize game mechanics

		void NewWord();

		//Function to read a word from database and select it as the new mystery word

		void NewWord(string playerEntry);

		//Function to read a word given by user and select it as the new mystery word

		void Guess(char attempt);

		//Function to determine if user fails an attempt to guess a letter

		void ContinueGame();

		//Function to keep a user making guesses until a result (win/lose) is obtained

		bool ExitGame(){return done;};

		//Function to determine if user quits during play

		void DisplayGuessed();

		//Function to display used letters

		bool InvalidEntry(string entry);

		//Function to determine whether a given input is invalid.

		void EnterWord();

		//Function to read and save a new word given by player

		void PrintWords();

		//Function to print the content of the database

		void SearchWord();

		//Function to search a word within the database

		
 

	private:

		string choice; //Variable to store choice

		bool done; //Variable to store a value if user quits "Play Game" mode

		Word current; // Object of type Word

		int numOfWords; //Variable to store number of words

		int numOfAttempts; //Variable to store number of attempts

		Graphics HangmanDoll; //Object of type Graphics

		vector <Dictionary> alphabet; // Vector of type Dictionary 

									  //It stores the letters of the alphabet

		string playerEntry; //Variable to store entry given by player

	

	protected:

		int count;

		node *first;

		node *last;

};

#endif
 

/////////////////////////////////////////////////////////////////

Implementation of class Engine.h

/////////////////////////////////////////////////////////////////

#include "Engine.h"
 

using namespace std;
 

Engine::Engine()

{

	for(int i=0; i<26; i++)

	{

		alphabet.push_back(static_cast<char>('a'+i));

	}
 

	first = NULL;

	last = NULL;

	count = 0;

}//end default constructor
 

Engine::~Engine()

{

	node *temp;

	while (first != NULL)

	{

		temp = first;

		first = first->next;

		delete temp;

	}
 

	last = NULL;

	count = 0;

}//end destructor
 

void Engine::InitializeGame()

{

	HangmanDoll.Clear();

	srand ( static_cast<unsigned int>(time(NULL)) );

	done = false;

	string line;

	try

	{

		ifstream infile ("words.txt");

		for(numOfWords = 0; !infile.eof(); numOfWords++)

		{

			getline (infile, line);

		}//end for

		

		infile.close();

		NewWord();

		numOfAttempts=0;

	}//end try

	

	catch(...)

	{

		cout << "File not found..." << endl;

	}//end catch

	

}//end method InitializeGame
 

void Engine::NewWord()

{

	string line;

	int wordnum = rand() % numOfWords;

	try

	{

		ifstream infile ("words.txt");

		for(int i = 0; i <= wordnum; i++)

		{

			getline (infile, line);

		}//end for
 

		current = line;

		infile.close();

		HangmanDoll.Clear();

		

		for(int i = 0; i < 26; i++)

		{

			alphabet[i].ClearGuess();

		}//end for

	}//end try

	

	catch(...)

	{

		cout << "File not found..." << endl;

	}//end catch

}//end method NewWord
 

void Engine::NewWord(string playerEntry)

{

	current = playerEntry;

	while(!current.Valid())

	{

		cout << "That word contains a character other than a letter. Please re-enter." << endl;

		cin >> playerEntry;

		current = playerEntry;

	}//end while

	HangmanDoll.Clear();

	for(int i = 0; i < 26; i++)

	{

		alphabet[i].ClearGuess();

	}//end for

}//end method NewWord(string playerentry)
 

void Engine::ContinueGame()

{

	system("CLS");

	current.DisplayWord();

	cout << endl;

	HangmanDoll.Draw();

	cout << endl;

	DisplayGuessed();

	cout << endl;

	cout << endl;

	cout << "What is your guess? (Press 0 and enter to exit.)" << endl;

	cin >> choice;

	if(choice[0] == '0')

	{

		done = true;

	}//end if
 

	else

	{

		while(InvalidEntry(choice))

		{

			system("CLS");

			current.DisplayWord();

			cout << endl;

			HangmanDoll.Draw();

			DisplayGuessed();

			cout << endl;

			cout << endl;

			cout << "That is an invalid entry. Please enter your guess. (Press 0 and enter to exit.)" << endl;

			cin >> choice;

			

			if(choice[0] == '0')

			{

				done = true;

			}//end if

			

			if(done)

			{

				break;

			}//end if

		}//end while

		

		if(!current.Guess(choice[0]))

		{

			HangmanDoll.Miss();

		}//end if
 

		for(int i=0; i<26; i++)

		{

			if(choice[0]==alphabet[i].GetLetter())

			{

				alphabet[i].Toggle();

			}//end if

		}//end for
 

		numOfAttempts++;

	}//end else

	

	HangmanDoll.Update();

	

	if(current.Complete())

	{

		system("CLS");

		current.DisplayWord();

		cout << endl;

		cout << endl;

		cout << "Congratulations! You guessed the word in " << numOfAttempts << " tries." << endl;

		cout << endl;

		system("PAUSE");

		numOfAttempts = 0;

		NewWord();

	}//end if
 

	else if(HangmanDoll.LoseGame())

	{

		system("CLS");

		current.Reveal();

		cout << "Sorry, you didn't guess the word in time! The word was:" << endl;

		current.DisplayWord();

		cout << endl;

		HangmanDoll.Draw();

		cout << endl;

		system("PAUSE");

		numOfAttempts = 0;

		NewWord();

	}//end if

}//end method Update
 

void Engine::DisplayGuessed()

{

	cout<<"Letters Guessed:"<<endl;

	for(int i=0; i<26; i++)

	{

		cout << " ";

		if(alphabet[i].IsGuessed())

		{

			cout<<alphabet[i].GetLetter();

		}//end if
 

		else

		{

			cout << " ";

		}//end else
 

		cout << " ";

	}//end for

}//end method DisplayGuessed
 

bool Engine::InvalidEntry(string entry)

{

	if(entry.length()>1)

	{

		return true;

	}//end if
 

	if((static_cast<int>(entry[0])<'a' || static_cast<int>(entry[0])>'z') && (static_cast<int>(entry[0])<'A' || static_cast<int>(entry[0])>'Z'))

	{

		if(entry[0] != '0')

		{

			return true;

		}//end if

	}//end if
 

	return false;

}//end method InvalidEntry(string entry)
 

void Engine::EnterWord()

{

	/*

	system("CLS");

	ofstream outfile;

	

	outfile.open("words.txt", ofstream::app); //ofstream used

	cout << "Please type a new word and press Enter: " << endl << endl;

	cin >> playerEntry;

	outfile << playerEntry << endl;

	NewWord(playerEntry);

	cout << endl;

	outfile.close();

	*/

	node *temp;

	temp = new node;
 

	system("CLS");

	cout << "Please type a new word and press Enter: " << endl << endl;

	cin >> playerEntry;

	temp->data = playerEntry;

	temp->next = NULL;

	

	if (first == NULL)

	{

		first = temp;

		last = temp;

		count++;

	}//end if

	else

	{

		last->next = temp;

		last = temp;

		count++;

	}

	

	NewWord(playerEntry);

	cout << endl;

}//end method EnterWord
 

void Engine::PrintWords()

{

	/*

	char str[2000];

	fstream outfile("words.txt",ios::in);

	

	while(!outfile.eof()) 

	{

		outfile.getline(str, 2000);

        cout << str << endl;

    }//end while         

	

	outfile.close();

	cout << endl;

	*/

	

	node *temp;

	temp = new node;
 

	temp = first;
 

	while(temp != NULL)

	{

		cout << temp->data << endl;

		temp = temp->next;

	}

	

	cout << endl;
 

}//end method PrintWords
 

void Engine::SearchWord()

{

	/*

	multimap<string,int> words;

	map<int,string> lines;

	string str;

	try

	{

		ifstream infile("words.txt");

		int i = 1;

		

		while(getline(infile,str))

		{

			istringstream in(str);

			string s;
 

			while(in>>s)

			{

				words.insert(make_pair(s, i));

			}//end while

			

			lines.insert(make_pair(i, str));

			i++;

		}//end while
 

		string search;

		cout << endl << "Enter a word to search: ";

		cin >> search;

	

		if (words.count(search) == 0)

		{

			cout << endl << "Word is not available in database." << endl;

		}//end if
 

		else

		{

			cout << endl << "The number of matches = " << words.count(search)<< endl;

		}//end else
 

		multimap<string,int>::iterator it1 = words.lower_bound(search);

		multimap<string,int>::iterator it2 = words.upper_bound(search);

	

		while(it1 != it2)

		{

			int x = it1->second;

			map<int,string>::iterator iter = lines.find(x);

			cout << endl << x << " ) " << iter->second << endl;

			it1++;

		

			while(true)

			{

				if(it1 != it2 && it1->second == x)

				{

					it1++;

				}

				else

				{ 

					break;

				}

			}//end while

		}//end while

	}//end try
 

	catch(...)

	{

			cout << "File not found..." << endl;

	}

	*/
 

	node *temp; //pointer to traverse the list
 

    temp = first; //set current to point to the first node in the list

	bool found = false;

	cout << endl << "Which word would you like to search? " << endl;

	cin >> playerEntry;
 

    while(temp != NULL && !found)		//search the list

        if(temp->data == playerEntry)     //the item is found

		{

			cout << endl << "The word was found on the list! " << endl;

			found = true;

		}

        else

		{

			temp = temp->next; //make current point to the next node

		}

     

}//end method SearchWord

Open in new window

0
Comment
Question by:psycho_blood
  • 2
  • 2
4 Comments
 
LVL 6

Accepted Solution

by:
RishadanPort earned 500 total points
ID: 22640270
I really don't understand why you are deciding to use a linked list for a hangman game. Your previous idea of using a file is much more efficient... There are loads of other ways to store data other then using a complicated linked list.
0
 
LVL 6

Expert Comment

by:RishadanPort
ID: 22640388
A word of advice, I would highly suggest that if you do plan on creating a linked list, that you seperate it from your main application's code. Create a seperate class for it. Your current implementation seems to tie the hangman game to the linked list. Maybe in the future you will want to reuse this linked list...
0
 

Author Comment

by:psycho_blood
ID: 22642471
I am doing this because I need to implement three data structures on my final project, and I already have implemented two (vectors and arrays). After looking at my code, I thought implementing a linked list to store words instead of a text file was easier to do than using other data structures, unless you have any suggestion.
About using a separate class to define and implement a linked list, I wanted to make sure that my methods actually work well, which is why I was modifying the code in my Engine class.
0
 

Author Closing Comment

by:psycho_blood
ID: 31502997
I just quit doing this project.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

919 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now