Thread: Crossword Puzzle Program

  1. #1
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84

    Crossword Puzzle Program

    I am trying to redo a crossword puzzle program I made a few years ago in java and convert it to C++. I am about to go crazy. The purpose of the program is to have a text file that contains the files where the puzzle will be created. Below each text file there is a word list where the words will be searched within that file. I haven't gotten that far yet. I am still trying to put the crossword together. For instance:

    Code:
    filenames.txt
    
    1.txt
    2.txt
    3.txt
    4.txt
    -------------------------------------------------
    1.txt
    
    1 1 
    1 1
    
    some words to search for down here
    -------------------------------------------------
    2.txt
    
    2 2 
    2 2
    
    some words to search for down here
    -------------------------------------------------
    3.txt
    
    3 3 
    3 3
    
    some words to search for down here
    -------------------------------------------------
    4.txt
    
    4 4 
    4 4
    
    some words to search for down here
    
    combining all of these into one crossword should yield:
    
    1 1 2 2 
    1 1 2 2 
    3 3 4 4
    3 3 4 4
    Well needless to say this one works for my program, but when I try to extend it, it doesn't work. I am currently trying to do a 6x6 (9 files with 2x2 matrices in them). I have error stepped through my program and the error is that I am putting the wrong characters in the wrong part of the array. I am printing out the location I want to put the character in (0,0) format and it's correct but on certain iterations it's putting the same character in multiple spots when it shouldn't be.

    It's a little convoluted right now since I have been printing out tons of information for debugging purposes. I now have it printing out what it's trying to put, where it's trying to put it and what the overall puzzle looks like at each iteration. Here's some example output with my comments added:

    Code:
    ***********
    AAAAAA  //I initialized every character inthe puzzle to A so I can see changes
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    1 1        //this is the first line of the first file
    
    temp.length(): 4 //length of the string I read in
    j=0,i=0 (0,0)       //loop paramters that don't make sense without seeing code
    putting:1 at (0,0) //says I am putting a 1 at puzzle[0][0]
    
    ***********
    1AAAAA   //now it shows the array with the 1 put in the correct location
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    j=0,i=0 (0,1)
    putting:1 at (0,1)
    
    ***********
    11AAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    1 1
    
    temp.length(): 4
    j=0,i=0 (1,0)
    putting:1 at (1,0)
    
    
    //this is where things screw up. It says I am putting a 1 at puzzle[1][0] which it does
    //but for seemingly no reason it also puts a 1 at puzzle[0][4]
    ***********
    11AA1A
    1AAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    j=0,i=0 (1,1)
    That's an isolated example of the problem. It repeats several times throughout the program and is always the same so it isn't some fluke; it's an error in my program.

    main.cpp
    Code:
    #include <cstdlib>
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <vector>
    #include <cmath>
    
    
    //this function builds the entire puzzle via getting the number of characters 
    //per puzzle, total number of puzzles wide, and a list of the files to read from 
    //std::vector buildPuzzle(int charsPerPuzzle, int puzzleWidth, std::vector fileList);
    void buildPuzzle(char (*a)[4], int charsPerPuzzle, int puzzleWidth, std::vector<std::string> fileList);
    
    
    template <typename Any>
    void display(Any a, int size);
    
    
    
    int main(int argc, char *argv[])
    {
        //name of the file that contains the files
        char fileName[50];
        int lineCount = 0;
        //vector to store all of the files to build the crossword
        std::vector<std::string> fileList;
        std::string temp;
        //number of non-whitespace characters on each line of the puzzle
        const int charsPerPuzzle = 2;
        
    /****************************************************************
       the first thing we need to do is get the list of files that 
       will be used to build the crossword puzzle.
     ****************************************************************/   
    
        
          
        //get the file name and open up an input stream
        std::cout<<"Enter the name of the file that contains the files "
                 <<"used to solve the puzzle.\n";
        //std::cin>>fileName;
        //std::ifstream in ("allpuzzlelist.txt");
        std::ifstream in ("file.txt");
        //make sure the file was able to be opened
        if(!in.is_open())
        {
            std::cerr<<"File not open correctly. Terminating Program.";
            std::cin.get();
        }
        
        //read in the list of files and store in a vector
        while(in>>temp)
        {
            fileList.push_back(temp);
        }
        
        //display the list of files that will build the crossword
        display(fileList, fileList.size());
        
    /******************************************************************* 
      Now that we have the list it's time to build the crossword puzzle.
     *******************************************************************/ 
        
        int puzzleWidth = int(sqrt(fileList.size()));
        //std::cout<<"puzzleWidth: "<<puzzleWidth;
        //vector containing the entire puzzle
        char puzzle[charsPerPuzzle*puzzleWidth][4];
     
        buildPuzzle(puzzle, charsPerPuzzle, puzzleWidth,fileList);
        std::cout<<"\nNow I am displaying the puzzle:\n\n";
    //prints off the puzzle. really should be a function but I am having trouble 
    //passing double arrays    
        for(int i = 0; i < charsPerPuzzle * puzzleWidth; i++)
        {
            for(int j = 0; j < charsPerPuzzle * puzzleWidth; j++)
            {
                std::cout<<puzzle[i][j];
            } 
            std::cout<<std::endl;
        }
        
    /******************************************************************* 
      Finish off the program.
     *******************************************************************/               
        in.close();
        std::cin.ignore();
        std::cin.get();
        return EXIT_SUCCESS;
    }
    template <typename Any>
    void display(Any a, int size)
    {
        for(int i = 0; i < size; i++)
        {
            std::cout<<a[i]<<std::endl;
        }
    }
    
    //function that creates the puzzle given the 
    //puzzleWidth - tells how many files wide the puzzle is (4 files (2 wide), 9 files (3 wide))
    //charsPerPuzzle - tells how many characters wide the puzzle is
    //fileList - vector containing the list of all the files that comprise the crossword
    void buildPuzzle(char (*puzzle)[4], int charsPerPuzzle, int puzzleWidth, std::vector<std::string> fileList)
    {
         std::cout<<"\nBuilding Crossword\n";
         std::cout<<std::endl;
         
    //initialize the puzzle to be all 'A's     
        for(int i = 0; i < charsPerPuzzle * puzzleWidth; i++)
        {
            for(int j = 0; j < charsPerPuzzle * puzzleWidth; j++)
            {
                puzzle[i][j] = 65;
            } 
            std::cout<<std::endl;
        }
    //prints off the puzzle. really should be a function but I am having trouble 
    //passing double arrays       
        std::cout<<"\n***********\n";
        for(int i = 0; i < charsPerPuzzle * puzzleWidth; i++)
        {
            for(int j = 0; j < charsPerPuzzle * puzzleWidth; j++)
            {
                std::cout<<puzzle[i][j];
            } 
            std::cout<<std::endl;
        }   
    
    //this part does the bulk of the puzzle building looping over every file adding it to the puzzle
      for(int j = 0; j < puzzleWidth; j++)
      {   
             for(int i = 0; i < puzzleWidth; i++)
             {
    //prints off the puzzle. really should be a function but I am having trouble 
    //passing double arrays                   
                    std::cout<<"\n***********\n";
                    for(int t = 0; t < charsPerPuzzle * puzzleWidth; t++)
                    {
                        for(int d = 0; d < charsPerPuzzle * puzzleWidth; d++)
                        {
                            std::cout<<puzzle[t][d];
                        } 
                        std::cout<<std::endl;
                    } 
                    //open the file to read from
                    std::ifstream input(fileList[j*puzzleWidth+ i].c_str());
                    //error checking
                    if(!input.is_open())
                        std::cerr<<"Error opening file!\n"<<std::endl;
                    //temp string to hold the line red from the file.
                    std::string temp;
                    //k can be thought of as a variable for every line of the file
                    for(int k = 0; k < charsPerPuzzle; k++)
                    { 
                        //read the line from the file and print it out
                        getline(input, temp);
                        std::cout<<temp<<std::endl;
                        //count is a variable that keeps track of which charcter of the line
                        //just read that we are on
                        int count = 0;
                        
                        std::cout<<"\ntemp.length(): "<<temp.length()<<std::endl;
                        //for every character of every line we read
                        while(count < temp.length())
                        {   
                            //determine if it's a space (discard) or a character we need to keep
                            if(temp[count] == ' ')
                            {
                                count++;
                                continue;
                            }
                            else
                            {
                                //print out more data for error checking 
                                std::cout<<"j="<<j<<",i="<<i<<" ("<<j*charsPerPuzzle+k<<","<<i*charsPerPuzzle + count/2<<")\n";
                                std::cout<<"putting:"<<temp[count]<<" at"<<" ("<<j*charsPerPuzzle+k<<","<<i*charsPerPuzzle + count/2<<")\n";
                                //actually set the charcter read to the correct puzzle location
                                puzzle[j*charsPerPuzzle+k][i*charsPerPuzzle + count/2] = temp[count];  
                                //print the puzzle out again so we can contrast this with before we added the character
                                //so we can ascertain what is being added at every step
                                std::cout<<"\n***********\n";
                                for(int m = 0; m < charsPerPuzzle * puzzleWidth; m++)
                                {
                                    for(int p = 0; p < charsPerPuzzle * puzzleWidth; p++)
                                    {
                                        std::cout<<puzzle[m][p];
                                    } 
                                    std::cout<<std::endl;
                                }                               
                            }    
                            count++;  //increase the character count   
                        }//done looping over the line erad
                   
          
                   }//done looping over the file
                    input.close();
             }//done looping over the first line of files added to the puzzle (for 3x3 this would be files 1,2,3)
        }//done looping over all files
        
        //print out the puzzle again for error checking purposes 
        std::cout<<std::endl;
        for(int i = 0; i < charsPerPuzzle * puzzleWidth; i++)
        {
            for(int j = 0; j < charsPerPuzzle * puzzleWidth; j++)
            {
                std::cout<<puzzle[i][j];
            } 
            std::cout<<std::endl;
        }
     
    }
    Crossword File Generator.cpp
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdlib>
    
    std::string ........itoa(int);
    int main()
    {
        
        std::ofstream fileOut("file.txt");
        for(int i = 1; i < 10; i++)
        {  
            fileOut<<i<<".txt"<<std::endl;
            std::cout<<i<<".txt"<<std::endl;
        }   
    
        fileOut.close();
        std::string temp = ".txt";
        char *ch;
        for(int i = 1; i < 10; i++)
        {  
            std::cout<<temp<<std::endl;
            std::ofstream out((........itoa(i).append(temp)).c_str());
            out<<i<<" "<<i<<" \n";
            out<<i<<" "<<i<<" \n";
            out<<"\nwords here";
            out.close();
        } 
    }
    
    std::string ........itoa(int num)
    {
        switch(num)
        {
         case 1:
                   return "1";   
         case 2:
                   return "2";
         case 3:
                   return "3";  
         case 4:
                   return "4";   
         case 5:
                   return "5";
         case 6:
                   return "6"; 
         case 7:
                   return "7";   
         case 8:
                   return "8";
         case 9:
                   return "9"; 
         default: 
                   return "";   
                                                                      
        }
        
    }
    I really appreciate the help guys. Main.cpp is the file you run that ctually solves the problem. Since we can't attached zip files and there were too many text files i created another program that will generate all of the files necessary so run Crossword File Generator.cpp first. Thanks.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Code:
    //this is where things screw up. It says I am putting a 1 at puzzle[1][0] which it does
    //but for seemingly no reason it also puts a 1 at puzzle[0][4]
    ***********
    11AA1A
    1AAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    AAAAAA
    Since your array is only 4 wide:
    Code:
    char (*puzzle)[4]
    0,4 and 1,0 are the same element. By printing them, you're accessing the same section of memory.
    Code:
    #include <iostream>
    
    int main(void) {
        int array[4][4], x, y;
    
        for(x = 0; x < 4*4; x ++) {
            array[x/4][x%4] = x;
        }
    
        for(y = 0; y < 2; y ++) {
            for(x = 0; x < 6; x ++) {
                std::cout << array[y][x] << ' ';
            }
    
            std::cout << std::endl;
        }
    
        return 0;
    }
    Output:
    Code:
    0 1 2 3 4 5
    4 5 6 7 8 9
    As you can see, the same element is printed twice.

    The lesson is to always make your arrays big enough.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    System.out.println("");
    Join Date
    Jan 2005
    Posts
    84
    Thanks so much dwks. I just couldn't seem to figure it out the other night. I got frustrated and figured I needed a break (thus it taking so long for this reply). Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BOOKKEEPING PROGRAM, need help!
    By yabud in forum C Programming
    Replies: 3
    Last Post: 11-16-2006, 11:17 PM
  2. Can someome help me with a program please?
    By WinterInChicago in forum C++ Programming
    Replies: 3
    Last Post: 09-21-2006, 10:58 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM