-
July 3rd, 2010, 11:30 PM
#1
Need some tips and suggestions on program
Would someone please review and judge my program? I need someone to tell me the good and bad practices that I should continue or end, and give me some feedback and tips for my future programs. Anything would be helpful.
Here is the code:
Code:
#include<fstream>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class wsb //word search board
{
// V H-0 1 2 3
// 0 0 1 2 3
// 1 4 5 6 7
// 2 8 9 10 11
// 3 12 13 14 15
public:
wsb(int xx, int yy, char fchar='~'); //fchar=filler char
wsb(void); //MAY OR MAY NOT BE DELETED
void setchars(char inchar='~'); //sets all the characters to an identical value
char* refval(int hor, int ver); //returns a character address via horizontal and vertical units
void printboard(int spacing=1);
void experiment() // this lets me do what ever I want
{
//wsbd[14]='s';
}
protected:
bool isinit;
void init(int xx, int yy, char fchar='~'); //constructor calls this
int hl; //WATCH OUT is not a -1!
int vl; //WATCH OUT is not a -1!
std::vector<char> wsbd; //WATCH OUT is not a null! also wsbd=wsb-data
};
class wsbfun : public wsb //fun=fuctions word search board with funtions
{
public:
wsbfun(string filename); //deafault "wsbtxt.txt" is in funtion rather that declaration
wsbfun(int xx,int yy);
~wsbfun(); //don't worry ~wsb was called even though not apparent
class word
{
public:
word();
enum directtype {U,UR,R,DR,D,DL,L,UL,UD=-1};
enum statetype {F,NF,US=-1};
int locx;
int locy;
statetype state;
directtype direct;
string worddata;
void changeword(string input);
};
std::vector <word> vocab;
void searchword(word &searchme);
void printword(word &printme);
protected:
bool filecheck(string filename);
int dirspot(int x, int y,string tobechk);
};
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
int main()
{
cout<<"Emmanuel's console word search v 1.0"<<endl<<endl;
cout<<"To begin you must have a board. Type in the name of a file in the same dierctory of the executable to import it. Otherwise you can just type wsbtxt to load the deafault file."<<endl;
string first;
cin>>first;
wsbfun file(first);
char states;
file.printboard();
cout<<"For help type h"<<endl;
while(states!='q')
{
cout<<"awaiting command: ";
cin>>states;
switch (states)
{
case 'p':
{
int spacing;
cout<<"type the spacing.(recomended is 1)";
cin>>spacing;
file.printboard(spacing);
break;
}
case 'h':
{
cout
<<"print board p"<<endl
<<"quit program q"<<endl
<<"add word a"<<endl
<<"experiment x"<<endl
<<"search word s"<<endl
<<"remove word r"<<endl
<<"list vocab l"<<endl;
break;
}
case 'r':
{
cout<<"type the vocab # for the word you want to remove(MAKE SURE # IS IN LIST!)";
int a;
cin>>a;
file.vocab.erase(file.vocab.begin()+a);
break;
}
case 'a':
{
cout<<"add word: " ;
string inputword;
cin>>inputword;
file.vocab.resize(file.vocab.size()+1);
file.vocab[file.vocab.size()+-1].changeword(inputword);
cout<<"search it? (y)";
char a;
cin>>a;
if (a=='y')
{
int searchnum=file.vocab.size()+-1;
file.searchword(file.vocab[searchnum]);
if (file.vocab[searchnum].state==wsbfun::word::F)
{
file.printword(file.vocab[searchnum]);
}
else
cout<<file.vocab[searchnum].worddata<<"was not found"<<endl;
}
break;
}
case 'l':
{
cout<<"the vocab is:"<<endl;
for(int i=0;i<file.vocab.size();i++)
{
cout<<"# "<<i<<" "<<file.vocab[i].worddata;
switch((int)file.vocab[i].state)
{
case -1:
{cout<<"UNKNOWN";break;}
case 0:
{cout<<"FOUND";break;}
case 1:
{cout<<"NOT FOUND";break;}
}
cout<<endl;
}
break;
}
case 's':
{
cout<<"all? (y)";
char yn;
cin>>yn;
if (yn=='y')
{
for(int i=0; i<file.vocab.size(); i++)
{
file.searchword(file.vocab[i]);
if (file.vocab[i].state==wsbfun::word::F)
{
file.printword(file.vocab[i]);
}
else
cout<<file.vocab[i].worddata<<"was not found";
cout<<endl;
}
}
else
{
cout<<"what word do you want to search for?(give vocab #)"<<endl;
int searchnum;
cin>>searchnum;
if (searchnum+1>file.vocab.size()||searchnum<0)
cout<<"Uhoh. You typed in an invalad number."<<endl;
else
{
cout<<"you are searching for "<<file.vocab[searchnum].worddata<<endl;
file.searchword(file.vocab[searchnum]);
if (file.vocab[searchnum].state==wsbfun::word::F)
{
file.printword(file.vocab[searchnum]);
}
else
cout<<file.vocab[searchnum].worddata<<"was not found"<<endl;
}
}
break;
}
case 'x':
{
}
default:
{
}
}
}
return 0;
}
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
wsb::wsb(void)
{
isinit=false;
}
wsb::wsb(int xx, int yy, char fchar)
{
init(xx,yy,fchar);
}
void wsb::init(int xx, int yy, char fchar)
{
wsbd.resize(xx*yy);
hl=xx;
vl=yy;
isinit=true;
setchars(fchar);
}
char* wsb::refval(int hor, int ver) //returns a character address via horizontal and vertical units
{
if (isinit)
{
if ((hor<0||hor>hl-1)||(ver<0||ver>vl-1))
{
return NULL;
}
return &(wsbd[(hor)+ver*hl]);
}
else
{
cout<<"wsb never declared(refval)";
return NULL;
}
}
void wsb::printboard(int spacing)
{
if (isinit)
{
for(int v=0; v<vl; v++)
{
for(int h=0; h<hl; h++)
{
cout<<*(refval(h,v));
for(int i=0; i<spacing; i++)
{
cout<<' ';
}
}
cout<<endl;
}
}
else
{
cout<<"wsb never declared(printboard)";
}
}
void wsb::setchars(char inchar)
{
if (isinit)
{
for(int i=0; i<hl*vl ; i++)
{
wsbd[i]=inchar;
}
}
else
{
cout<<"wsb never declared(setchars)";
}
}
/**********************************************************************/
/**********************************************************************/
/**********************************************************************/
wsbfun::wsbfun(int xx,int yy)
:wsb(xx,yy)
{
}
wsbfun::wsbfun(string filename)
:wsb()
{
if(filename.empty())
{
filename="wsbtxt";
}
ifstream imfi;
imfi.open( filename.c_str());
if(filecheck(filename)) //if it passed the test it will begin importing the file
{
int hl=0; //horizontal length
int vl=0; //vertical length (IMPORTANT TO BE SET TO ZERO)
bool goonce=true;
imfi.seekg(0,ios::beg);
while(imfi)
{
string mesline;
getline(imfi, mesline);
if(goonce) //this part creates the horizontal direction
{
hl=mesline.length();
goonce=false;
}
if(!(mesline.length()==0)) //this part counts the vertical dimension
{
vl++;
}
}
imfi.clear();
imfi.seekg(0,ios::beg);
init(hl,vl);
if (1) //just for structure
{
for(int vpos=0;vpos<vl;vpos++) //these loops set the character valus
{
for(int hpos=0;hpos<hl;hpos++)
{
char a;
imfi.get(a);
*refval(hpos,vpos)=a;
}
imfi.get();
}
}
isinit=true;
}
else
{
isinit=false;
}
}
bool wsbfun::filecheck(string filename)
{
ifstream chkstrm(filename.c_str());
bool valad=true; //value will be tested for valadness across the next section of code
if (valad) //first section (checks whether all lines are the same length)
{
bool runonce=true; //for the part that finds the firstlen
int firstlen=-1; //intitialized to -1 for good practice
bool nozero=true;
int count=0;
while (chkstrm)
{
count++;
string strInput;
getline(chkstrm, strInput);
if (runonce) //this part only runs to find the length of the first line
{
firstlen=strInput.length();
runonce=false;
}
else //this part tests if all the lines are equal eccept if the last line is 0 length
{
if (firstlen!=strInput.length())
{
if(strInput.length()==0)
{
firstlen=0;
}
else
{
valad=false;
break;
}
}
}
}
}
if (valad) //2nd section JUST IN CASE... if no case exists delete.
{
}
return valad;
}
wsbfun::~wsbfun()
{
}
void wsbfun::searchword(word &searchme)
{
bool endit=false;
if ((searchme.worddata.length()!=0)&&(isinit)) //Checks if word and board are valad
{
for(int v=0; v<vl; v++)
{
for(int h=0; h<hl; h++)
{
if(*(refval(h,v))==searchme.worddata.at(0))
{
int dircar=dirspot(h,v,searchme.worddata);
switch (dircar)
{
case -1:
{searchme.state=word::NF; break;}
case 0:
{searchme.state=word::F; searchme.direct=word::U; endit=true; break;}
case 1:
{searchme.state=word::F; searchme.direct=word::UR; endit=true; break;}
case 2:
{searchme.state=word::F; searchme.direct=word::R; endit=true; break;}
case 3:
{searchme.state=word::F; searchme.direct=word::DR; endit=true; break;}
case 4:
{searchme.state=word::F; searchme.direct=word::D; endit=true; break;}
case 5:
{searchme.state=word::F; searchme.direct=word::DL; endit=true; break;}
case 6:
{searchme.state=word::F; searchme.direct=word::L; endit=true; break;}
case 7:
{searchme.state=word::F; searchme.direct=word::UL; endit=true; break;}
default:
cout<<"error";
}
if (endit)
{
searchme.locx=h;
searchme.locy=v;
}
}
if (endit)
break;
}
if (endit)
break;
}
}
}
wsbfun::word::word()
{
state=US;
direct=UD;
worddata="default";
locx=-1;
locy=-1;
}
void wsbfun::word::changeword(string input)
{
worddata=input;
state=US;
direct=UD;
locx=-1;
locy=-1;
}
int wsbfun::dirspot(int x, int y, string tobechk)
{
if (*(refval(x,y))!=tobechk.at(0)) //checks first char
{
return -1;
}
int retvalue=-1;
bool verf=1;
////////////U
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x,y+-i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x,y+-i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=0;
verf=1;
////////////UR
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+i,y+-i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+i,y+-i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=1;
verf=1;
////////////R
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+i,y)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+i,y))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=2;
verf=1;
////////////DR
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+i,y+i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+i,y+i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=3;
verf=1;
////////////D
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x,y+i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x,y+i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=4;
verf=1;
////////////DL
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+-i,y+i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+-i,y+i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=5;
verf=1;
////////////L
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+-i,y)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+-i,y))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=6;
verf=1;
////////////UL
for(int i=1; i<tobechk.length(); i++)
{
if (refval(x+-i,y+-i)==NULL)
{
verf=0;
break;
}
else if (*(refval(x+-i,y+-i))!=tobechk.at(i))
{
verf=0;
break;
}
}
if (verf)
retvalue=7;
verf=1;
////////////////////////
return retvalue;
}
void wsbfun::printword(word &printme)
{
int itx; //iterate x
int ity; //iterate y
switch ((int)printme.direct)
{
case -1:
{cout<<"Word has not been searched yet. OR word was not found"; break;}
case 0:
{itx=0;ity=-1;break;}
case 1:
{itx=1;ity=-1;break;}
case 2:
{itx=1;ity=0;break;}
case 3:
{itx=1;ity=1;break;}
case 4:
{itx=0;ity=1;break;}
case 5:
{itx=-1;ity=1;break;}
case 6:
{itx=-1;ity=0;break;}
case 7:
{itx=-1;ity=-1;break;}
default:
{cout<<"there is something very wrong"<<endl;}
}
for(int v=0; v<vl; v++)
{
for(int h=0; h<hl; h++)
{
bool chkval=false;
for(int i=0; i<printme.worddata.length();i++)
{
if((v==printme.locy+i*ity) && (h==printme.locx+i*itx))
{
chkval=true;
}
}
if (chkval)
cout<<*(refval(h,v));
else
cout<<'#';
cout<<' ';
}
cout<<endl;
}
}
-
July 4th, 2010, 10:11 AM
#2
Re: Need some tips and suggestions on program
I'd get in the habit of hitting the spacebar every once in a while. They must be teaching that space is bad in school or something.
Other than that, the indentation looks good. I didn't go through the logic, but I did see you're using states without initializing it first.
-
July 6th, 2010, 12:10 PM
#3
Re: Need some tips and suggestions on program
- Don't use abbreviations for class names or variables names. They make your code very very difficult to understand. Also using a naming convention to distinguish class names, function names, and member variable names at different scope can be very helpful.
- Try to avoid public member variables. Make them private instead and, if needed, provide accessor functions.
- You don't have to specify void to define a function with an empty argument list in C++. Just put nothing in between the brackets.
- Prefer to use the initializer list to initialize member variables in constructors.
- Prefer to pass non-POD objects, such as std::string, by const reference instead of by value.
- Put each class definition into a separate header file, the implementation of the member functions into separate .cpp files and the main function also in a separate .cpp file. Use #include directives to include the header files in other header files or .cpp files.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
July 6th, 2010, 12:52 PM
#4
Re: Need some tips and suggestions on program
For things like this:
Code:
for(int i=1; i<tobechk.length(); i++)
It's more efficient to do it this way
Code:
for(int i = 1, tobechk_len = (int)tobechk.length(); i < tobechk_len; ++i)
Because otherwise it will call length() over and over again. You only want to do that if it's possible that the length will change. For string it's not much of a problem because length is O(1), but you should get in the habit of that.
Learn how to properly use iterators, they are much more efficient that referencing by indexes.
White space, spaces are ignored by the compiler and make code much easier to read.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|