Crossword Puzzle Program

This is a discussion on Crossword Puzzle Program within the C++ Programming forums, part of the General Programming Boards category; I am trying to redo a crossword puzzle program I made a few years ago in java and convert it ...

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:

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;
}
}

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.

//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.

"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