#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
using namespace std;
#define MAXLENGTH 20
#define WORDLENGTH 20
enum dir { LEFT=0,UPLEFT,UP,UPRIGHT,RIGHT,BOTTOMRIGHT,BOTTOM,BOTTOMLEFT};
enum menu { LOAD=0,SOLVE,CREATE,QUIT };
struct WORD
{
char word[WORDLENGTH];
int length;
int row;
int col;
dir d;
};
typedef struct WORD word;
 
word wordlist[100];
char puzzle[MAXLENGTH][MAXLENGTH];
int nrow,ncol,nwords;
char direction[8][15]={"LEFT","UPPERLEFT","UP","UPPERRIGHT","RIGHT","BOTTOMRIGHT","BOTTOM","BOTTOMLEFT"};
int loaded;
enum menu readMenu();
int loadPuzzle();
int solvePuzzle();
int createPuzzle();
void printUnsolvedPuzzle();
int main()
{
menu menuItem;
loaded=-1;
while(1)
{
menuItem=readMenu();
if(menuItem==LOAD)
{
loaded=loadPuzzle();
}
else if(menuItem==SOLVE)
{
solvePuzzle();
}
else if(menuItem==CREATE)
{
createPuzzle();
}
else if(menuItem==QUIT)
{
cout<<"\nGood bye ! demo version by inadilemma";
cin.get();
return 0;
}
}
}
enum menu readMenu()
{
while(1)
{
fflush(stdin);
cout<<"\n\t\t**********************";
cout<<"\n\t\t* *";
cout<<"\n\t\t* FIND A WORD *";
cout<<"\n\t\t* *";
cout<<"\n\t\t**********************\n";
cout<<"\n1: Load Puzzle.\n2: Solve Puzzle.\n3: Create Puzzle.\n4: Quit.";
cout<<"\nEnter your choice: ";
char ch;
cin>>ch;
if(ch=='1')return LOAD;
if(ch=='2')return SOLVE;
if(ch=='3')return CREATE;
if(ch=='4')return QUIT;
cout<<"\nInvalid input !";
}
}
int loadPuzzle()
{
char filename[256];
int i;
cout<<"\nEnter filename : ";
cin>>filename;
ifstream fin(filename);
if(fin==NULL)
{
cout<<"\nInvalid filename \nPress any key...";
cin.get();
return -1;
}
fin>>nrow>>ncol;
nwords=0;
for(i=0;i<nrow;i++)
{
fin>>puzzle[i];
if(strlen(puzzle[i])!=ncol)
{
cout<<"\nInvalid puzzle \nPress any key...";
cin.get();
return -1;
}
}
while(1)
{
fin>>wordlist[nwords].word;
wordlist[nwords].length=strlen(wordlist[nwords].word);
wordlist[nwords].row=-1;
wordlist[nwords].col=-1;
nwords++;
if(fin.eof())break;
}
cout <<"\nPuzzle: "<< filename <<"\n\n";
printUnsolvedPuzzle();
fin.close();
return 0;
}
void printUnsolvedPuzzle()
{
int i,j;
for(i=0;i<nrow;i++)
{
for(j=0;j<ncol;j++) 
{
cout<<"\t"<<puzzle[i][j] <<" ";
}
cout<<"\n";
}
 
cout<<"\n\nWords :\n--------";
for(i=0;i<nwords;i++)
{
if(i%4==0)cout<<"\n";
cout<<wordlist[i].word<<"\t\t\t";
}
cout<<"\n";
cin.get();
}
int createPuzzle()
{
cout<<"\nPuzzle created";
cout<<"\nPress any key to continue...";
cin.get();
return 0;
}
int solvePuzzle()
{
if(loaded!=0)
{
cout<<"\nNo puzzle loaded";
cout<<"\nPress any key to continue...";
cin.get();
return -1;
}
int i,j,k,n,found=0;
for(i=0;i<nwords;i++)
{
found=0;
for(j=0;j<nrow;j++)
{
for(k=0;k<ncol;k++)
{
if(puzzle[j][k]==wordlist[i].word[0])
{
//left
if(wordlist[i].length<=(k+1))
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j][k-n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=LEFT;
}
}
//uppperleft
if(wordlist[i].length<=(k+1) && wordlist[i].length<=(j+1))
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j-n][k-n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=UPLEFT;
}
}
if(wordlist[i].length<=(j+1)) //up direction
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j-n][k])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=UP;
}
}
if(wordlist[i].length<=(ncol-k) && wordlist[i].length<=(j+1)) //upper right
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j-n][k+n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=UPRIGHT;
}
}
if(wordlist[i].length<=(ncol-k)) //right
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j][k+n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=RIGHT;
}
}
//bottom right
if(wordlist[i].length<=(ncol-k) && wordlist[i].length<=(nrow-j))
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j+n][k+n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=BOTTOMRIGHT;
}
}
if(wordlist[i].length<=(nrow-j))
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j+n][k])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=BOTTOM;
}
}
if(wordlist[i].length<=(nrow-j) && wordlist[i].length<= (k+1))
{
for(n=0;n<wordlist[i].length;n++)
if(wordlist[i].word[n]!=puzzle[j+n][k-n])break;
if(n==wordlist[i].length)
{
found=1;
wordlist[i].row=j;
wordlist[i].col=k;
wordlist[i].d=BOTTOMLEFT;
}
}
}
if(found==1)break;
}
if(found==1)break;
}
}
for(i=0;i<nwords;i++)
{
if(wordlist[i].row!=-1)
{
cout<<"\nFound "<<wordlist[i].word<<" at ("<<(wordlist[i].row+1)<<","<<(wordlist[i].col+1)<<")";
cout<<"\nDirection: "<<direction[wordlist[i].d];
cout<<"\nWordlength "<<wordlist[i].length<<"\n";
}
if((i+1)%5==0)
{
cout<<"\npress any key to continue";
cin.get();
}
}
return 0;
}

read in the puzzle.txt file

10
10
nxchtrtvrv
oakbeyqhlf
itmtpnbket
tpuedulcni
crnksdziju
nfehupiclk
uiufloathi
fqastructr
gfbmkhriec
xspiiifdef
;enum
float
function
include
int
main
namespace
return
struct
type

I search the word where is inside the word puzzle, put I don't know hot to output the puzzle again and only show the find word into upper case. as below

*******************************
* Find a Word * *******************************
1. Load puzzle
2. Solve puzzle
3. Create puzzle
4. Quit

choice: 2

Solved Puzzle: puzzle.txt

N . . . . R T . . .
O A . . E Y . . . .
I . M T P . . . . T
T . U E D U L C N I
C R N . S . . I . .
N . E . . P . . . .
U I . F L O A T . .
F . A S T R U C T .
. . . M . . . . E .
. . . . . . . . . .

Words:
enum float function include
int main namespace return
struct type

You have included the C++ string library in your code, so why don't you actually use it? C-Style strings (char[] and/or char* ) are considered 'bad' in C++ - They are just making your life harder, and your code less readable.

also, this line is bad (even in C, I believe this is a bad idea)

fflush(stdin);

instead, use std::cin.ignore(); to ignore the next character (probably just a newline char), or std::cin.ignore(INT_MAX, '\n'); to ignore all characters up to a newline.

I'm not totally clear what you want you mean by "output the puzzle again" output the puzzle after what?

Use std::toupper() from the <cctype> library to put a single character in uppercase.

To perform toupper on a string, you can either loop through each element of the string, or you can use the STL algorithm std::transform() another issue making your code less readable - you've got alot of repeated code in your solvepuzzle() function - maybe you could break that down into smaller sub-functions.

int solvePuzzle()
{
   if ( loaded!=0 )
   {
      cout<<"\nNo puzzle loaded";
      cout<<"\nPress any key to continue...";
      cin.get();
      return -1;
   }
   int i,j,k,n,found=0;
   for ( i=0;i<nwords;i++ )
   {
      found=0;
      for ( j=0;j<nrow;j++ )
      {
         for ( k=0;k<ncol;k++ )
         {
            if ( puzzle[j][k]==wordlist[i].word[0] )
            {
//left
               if ( wordlist[i].length<=(k+1) )
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j][k-n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=LEFT;
                  }
               }
//uppperleft
               if ( wordlist[i].length<=(k+1) && wordlist[i].length<=(j+1) )
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j-n][k-n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=UPLEFT;
                  }
               }
               if ( wordlist[i].length<=(j+1) ) //up direction
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j-n][k] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=UP;
                  }
               }
               if ( wordlist[i].length<=(ncol-k) && wordlist[i].length<=(j+1) ) //upper right
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j-n][k+n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=UPRIGHT;
                  }
               }
               if ( wordlist[i].length<=(ncol-k) ) //right
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j][k+n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=RIGHT;
                  }
               }
//bottom right
               if ( wordlist[i].length<=(ncol-k) && wordlist[i].length<=(nrow-j) )
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j+n][k+n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=BOTTOMRIGHT;
                  }
               }
               if ( wordlist[i].length<=(nrow-j) )
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j+n][k] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=BOTTOM;
                  }
               }
               if ( wordlist[i].length<=(nrow-j) && wordlist[i].length<= (k+1) )
               {
                  for ( n=0;n<wordlist[i].length;n++ )
                     if ( wordlist[i].word[n]!=puzzle[j+n][k-n] )break;
                  if ( n==wordlist[i].length )
                  {
                     found=1;
                     wordlist[i].row=j;
                     wordlist[i].col=k;
                     wordlist[i].d=BOTTOMLEFT;
                  }
               }
            }
            if ( found==1 )break;
         }
         if ( found==1 )break;
      }
   }
   for ( i=0;i<nwords;i++ )
   {
      if ( wordlist[i].row!=-1 )
      {
         cout<<"\nFound "<<wordlist[i].word<<" at ("<<(wordlist[i].row+1)<<","<<(wordlist[i].col+1)<<")";
         cout<<"\nDirection: "<<direction[wordlist[i].d];
         cout<<"\nWordlength "<<wordlist[i].length<<"\n";
      }
      if ( (i+1)%5==0 )
      {
         cout<<"\npress any key to continue";
         cin.get();
      }
   }
   return 0;
}

read in the puzzle.txt file


I not allow to using STL and String in this program. I oonly can using basic c++.

and I want to output the solve puzzle as look like below output

Before solve

**********************
* *
* FIND A WORD *
* *
**********************
1: Load Puzzle.
2: Solve Puzzle.
3: Create Puzzle.
4: Quit.
Enter your choice: 1
Enter file to load: puzzle.txt
Puzzle: puzzle.txt
n x c h t r t v r v
o a k b e y q h l f
i t m t p n b k e t
t p u e d u l c n i
c r n k s d z i j u
n f e h u p i c l k
u i u f l o a t h i
f q a s t r u c t r
g f b m k h r i e c
x s p i i i f d e f

Words :
--------
enum float function include
int main namespace return
struct type


After solve
*******************************
* Find a Word * *******************************
1. Load puzzle
2. Solve puzzle
3. Create puzzle
4. Quit

choice: 2

Solved Puzzle: puzzle.txt

N . . . . R T . . .
O A . . E Y . . . .
I . M T P . . . . T
T . U E D U L C N I
C R N . S . . I . .
N . E . . P . . . .
U I . F L O A T . .
F . A S T R U C T .
. . . M . . . . E .
. . . . . . . . . .

Words:
enum float function include
int main namespace return
struct type

I am not sure I understand you.
But if you want to replace found words in the puzzle with dots,
here goes :

first change :

char puzzle[MAXLENGTH][MAXLENGTH];

to

typedef struct
    {
    char  ch;
    int    isdot;
    }PUZZLE_S ;
PUZZLE_S   puzzle[MAXLENGTH][MAXLENGTH];

while reading the puzzle from the file, set isdot = 0.

for(i=0;i<nrow;i++)
    for ( j = 0 ; j < ncol ; ++j )
         {
         fin >> puzzle[i][j].ch;
         puzzle[i][j].isdot = 0;
         }

Now every time you find a word in the puzzle, set isdot to one.
And leave the filed ch unchanged. Because it might serve for
anthoer word.


Last print the puzzle with a function like this

int   print_ch(PUZLE_S *puzle)
{
if ( puzle->isdot)
   return('.');
else if (puzle->ch >= 'a' && puzle->ch <= 'z' )
   return(puzle->ch - 'a' + 'A');
return(puzle->ch);
}
This article has been dead for over six months. Start a new discussion instead.