crossword puzzle

Pages: 123456
Hello the replacement function doesn't work in the previous code Maybe it works better that way! The rest of the errors I don't understand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include <iostream>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <vector>
using namespace std;
std::vector<double> coord_x;
std::vector<double> coord_y;
map<char, int> coordX_letter;
map<char, int> coordY_letter;

//Vectors for recording word coordinates
std::vector<double> temporary_coord_x;
std::vector<double> temporary_coord_y;
std::vector<std::string > words_vect;
std::vector<std::string > intersection;

//vector to know how the word is placed in the grid vertically or horizontally (v / h)
std::vector<std::string > place;
constexpr char empty = '.';
char grid[26][26] = {
		{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' }
};
//Random number generating function
int random(int from, int to)
{
	return rand() % (to - from + 1) + from;
}

//Function searching for letters common to two words
std::string find_intersection(std::string &first, std::string &second)
{
	std::sort(first.begin(), first.end());
	std::sort(second.begin(), second.end());
	int length = std::min(first.length(), second.length());
	std::string result(length, ' ');
	std::set_intersection(first.begin(), first.end(), second.begin(), second.end(), result.begin());
	return result;
}

//Horizontal word placement function
int PlaceHorizontal(int x, int y, int id_word, std::string &word)
{
	int taille = word.length();
	for (int j = 0; j < taille; j++)
	{
		if (grid[x][y + j] == empty || grid[x][y + j] == word[j])
		{
			grid[x][y + j] = word[j];
			coord_x.push_back(x);
			coord_y.push_back(y);
		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}

//Function placing words vertically
int PlaceVertical(int x, int y, int id_word, std::string &word)
{
	int taille = word.length();
	for (int j = 0; j < taille; j++)
	{
		if (grid[x + j][y] == empty || grid[x + j][y] == word[j])
		{
			grid[x + j][y] = word[j];
			coord_x.push_back(x);
			coord_y.push_back(y);
		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}

//function that assigns a score to the place chosen for the word
int can_place_v(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x][y + j] == empty || grid[x][y + j] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}

int can_place_h(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x + j][y] == empty || grid[x + j][y] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}

//Function randomly retrieving words from the dictionary
std::string randomword(int randomline)
{
	std::string word1;
	std::string ifileName = "dictionary.txt";
	std::ifstream f(ifileName);

	if (!f) std::cerr << "File '" << ifileName << "' couldn't opened!\n";

	std::string s;

	for (int i = 1; i < randomline; i++)
	{
		std::getline(f, s);
		std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c)
		{
			return std::tolower(c);
	});
		word1 = s;
	}

	return word1;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
int main(int argc, char *argv[])
{
	int score;
	srand(time(0));
	bool place_v = false;
	bool place_h = false;
	int n;
        //number of words to place
	int rand0 = random(10, 15);
	int num = rand0;

        //position of the horizontal and vertical intersection letter
	int x_word2_intersection_h;
	int x_word1_intersection_h;
	int x_word2_intersection_v;
	int x_word1_intersection_v;
	int number;
	std::string temp1;
	std::string temp2;
	int word_index;
	std::string prec_word;
	std::string current_word;
	int temp_intersec_2;
	int temp_intersec_1;
        //score for horizontal and vertical positioning
	int score_h = 0;
	int score_v = 0;

	//random word retrieval and addition to vector
        for (int i = 0; i < num; i++)
	{
                //depending on the size of the dictionary
		int rand1 = random(100, 20000);
		std::string word1 = randomword(rand1);
		words_vect.push_back(word1);

	}

	std::string word1 = words_vect[0];
	int pos_word1 = 8;
	PlaceVertical(pos_word1, pos_word1, 0, words_vect[0]);

	for (int k = 1; k < words_vect.size(); k++)
	{
		// start of testing
                back: 
                prec_word = words_vect[k - 1];
		current_word = words_vect[k];
		std::string temp_word0 = words_vect[k - 1];
		std::string temp_word1 = words_vect[k];
		std::string intersec = find_intersection(temp_word0, temp_word1);
                //as long as there is no intersecting letter
		while (intersec.empty())
		{
                        //replaces the word and goes back to the beginning of the checks.
			int rand3 = random(100, 20000);
   			std::string replacement = randomword(rand3);
			std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
			temp_word0 = words_vect[k - 1];
			temp_word1 = words_vect[k];
			std::string intersec = find_intersection(temp_word0, temp_word1);
			goto back;
		}
                //for each intersecting letter of the word in the vector 
		for (int j = 0; j < intersec.length(); j++)
		{
                       //temporary position of the selected intersection letter
			temp_intersec_2 = current_word.find_last_of(intersec[j]);
			temp_intersec_1 = prec_word.find_last_of(intersec[j]);
			score_h = can_place_h(coord_x[k - 1] + temp_intersec_2, coord_y[k - 1] - temp_intersec_1, k, current_word);
			score_v = can_place_v(coord_x[k - 1] - temp_intersec_1, coord_y[k - 1] + temp_intersec_2, k, current_word);
                        //if the vertical score of the position is equal to the size of the word 
			if (score_v == current_word.length())
			{
				if (k % 2 == 0)
				{
					place_v = true;
					std::cout << " Testing word " << k << "/" << num << "\n";
					std::cout << " Current score " << score_v << "/" << current_word.length() << "\n";
					std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
					std::cout << "-----" << "\n";
					x_word2_intersection_v = temp_intersec_2;
					x_word1_intersection_v = temp_intersec_1;
					goto placing_word;
				}
			}
			else
			{
				place_v = false;
				std::cout << " Testing word " << k << "/" << num << "\n";
				std::cout << " Current score " << score_v << "/" << current_word.length() << "\n";
				std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
				std::cout << "-----" << "\n";
                                //replaces the word and goes back to the beginning of the checks.
				int rand3 = random(100, 20000);
  				std::string replacement = randomword(rand3);
				std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
				goto back;
			}
                        //if the horizontal score of the position is equal to the size of the word 
			if (score_h == current_word.length())
			{
				if (k % 2 != 0)
				{
					place_h = true;
					std::cout << " Testing word " << k << "/" << num << "\n";
					std::cout << " Current score " << score_h << "/" << current_word.length() << "\n";
					std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
					std::cout << "-----" << "\n";
					x_word2_intersection_h = temp_intersec_2;
					x_word1_intersection_h = temp_intersec_1;
					goto placing_word;
				}
			}
			else
			{
				place_h = false;
				std::cout << " Testing word " << k << "/" << num << "\n";
				std::cout << " Current score " << score_h << "/" << current_word.length() << "\n";
				std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
				std::cout << "-----" << "\n";
                                //replaces the word and goes back to the beginning of the checks.
				int rand3 = random(100, 20000);
				std::string replacement = randomword(rand3);

				std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
				goto back;
			}
		}

		placing_word: if (k % 2 != 0)
		{
			if (place_h == true)
			{
				if (score_h == current_word.length())
				{
					PlaceHorizontal(coord_x[k - 1] + x_word2_intersection_h, coord_y[k - 1] - x_word1_intersection_h, k, current_word);
				}
			}
			else {}
		}

		if (k % 2 == 0)
		{
			if (place_v == true)
			{
				if (score_v == current_word.length())
				{
					PlaceVertical(coord_x[k - 1] - x_word1_intersection_v, coord_y[k - 1] + x_word2_intersection_v, k, current_word);
				}
			}
			else {}
		}
	}

	//grid view
	for (int i = 0; i < 26; i++)
	{
		for (int j = 0; j < 26; j++)
		{
			std::cout << grid[i][j];
			std::cout << " ";
		}

		std::cout << "\n";
	}

	words_vect.clear();
}
Last edited on
for the rest of the errors I don't understand how to modify the program without making a class or a structure.
but the program is recursive, as long as it has no solution it replaces the current word and tries to position it in the grid. It makes mistakes while checking the box where it places the letter of the word. there are variables declared that aren't used, but I didn't clean it up. It's my draft style ;)
Last edited on
for the rest of the errors

Exactly what errors are you talking about?

I don't understand how to modify the program without making a class or a structure.

More functions would probably be a good place to start. Also getting rid of all those horrible global variables and constructs like: goto placing_word; would probably be a good idea as well.

but the program is recursive,

I don't see any "recursion" in your last couple of posts, perhaps you could point out where the recursion is happening.

as long as it has no solution it replaces the current word and tries to position it in the grid. It makes mistakes while checking the box where it places the letter of the word.

What "mistakes" are you talking about.

If you are getting compile/link errors post them exactly as they appear in your development environment, and it would probably be better if you posted the complete program that generates the "mistakes" or "errors" and provide any and all input you supplied, and show the output you desire based on the input you supplied.

It's when the word crosses two other words it makes mistakes more often. Why is it that when I check what's in the grid and which char is present, he still places the word?

in this loop for example :

 
if (grid[x][y + j] == empty || grid[x][y + j] == word[j])


to finish on the style, I have nothing against refinement but if it's making classes and structures, it doesn't respect my initial idea !

I don't know the variable writing standards you use. I learned at home, sorry.

"Recursion (adjective: recursive) occurs when a thing is defined in terms of itself or of its type.Recursion is used in a variety of disciplines ranging from linguistics to logic.The most common application of recursion is in mathematics and computer science, where a function being defined is applied within its own definition. While this apparently defines an infinite number of instances ..."

I think the fact that I'm testing the words and replacing it and going back to the beginning of the main function is kind of recursive.

The dictionary is a text file a list of words like this one but longer (about 22000 words):

Aaron
lowering
lower
abandonment
abandoning
gives up
gives up
abandoned
abandoned
give up
give up
dropouts

The complete program is as shown above, and my environment is dev c++ on windows 7. I have no compilation error, what I want is to cross a maximum of words in a grid with as few letterless boxes as possible. A sort of crossword puzzle.

Propose code! Because to say that my code is sketchy, I get it now. But it doesn't matter since I don't know the coding standards lol
Last edited on
Then I suggest you review your practices and stop using some of the poor practices you are now using.

Using goto is considered an extremely bad practice in most cases and should be avoided. Learn to use other more acceptable loop constructs instead. Also more functions would probably help avoid the "need" for goto.

Using global variables is also a bad practice and should be avoided whenever possible. Learn to pass the required variables to and from your functions as required. Using global variables make it much harder to troubleshoot logic problems because where a global variable changes values can be difficult to spot.

Don't let "being self taught" be an excuse to fail to learn from your mistakes.

but if it's making classes and structures, it doesn't respect my initial idea !

Well maybe you need to rethink your initial idea. Using structures and classes often greatly simplify things. IMO, if you're going to write C++ code you shouldn't be ruling out one of C++'s greatest assets.
I think the fact that I'm testing the words and replacing it and going back to the beginning of the main function is kind of recursive.

In C++ recursion usually means that you have a function that calls itself. Iteration is when you use a loop (in this case the horrible goto) to repeat parts of a function.

But it doesn't matter since I don't know the coding standards lol

What's so funny about lack of knowledge? What have you done to try to solve this failing?

Propose code!

This is your program, I have made suggestions but you don't seem to interested to implement the suggestions so I don't know what more I can do to help.


Have you run the program with your debugger, single stepping through the program watching the various variables as you step?



Looking at your partial dictionary I do see some problems, there appears to be "words" that contain spaces won't that cause problems.
So keep your value judgments, please. With classes and structures I can't do half of what I do with what bothers you. And if helping people for you means creating a new topic with unusable code for those who are trying to learn, look for the meaning of the word pedagogy. Then if the small elite who make the code treat those who try as you do, if they don't come to tell us about the incapacity of some to adapt, the maladjusted are those who lack humility.
It's a good idea to clean up compiler warnings. That way if a new one appears and indicates an actual bug, it will stand out. For example, PlaceHorizontal and PlaceVertical should return void instead of int, and loop counters that compare to vector::size() should be unsigned instead of int

can_place_v and can_place_h have an unused parameter (id_word)

randomword(): Consider reading the dictionary into a vector at the beginning of the program. That would probably save time. Even a huge dictionary will fit in just a few megabytes. Google's list of the 10,000 most popular English words is just 75kb. 350,000 words take just 3.7MB.

If you don't want to read the dictionary into memory, move the call to transform() outside the loop. You only need to transform the word that you selected.

Instead of writing:
1
2
3
            temp_word0 = words_vect[k - 1];
            temp_word1 = words_vect[k];
            std::string intersec = find_intersection(temp_word0, temp_word1);

just pass the words to find_intersection by value. Then you can do
std::string intersec = find_intersection(words_vect[k-1], words_vect[k]);

I don't see any code to verify whether a word will run off the end of the grid.

BUG #1: You will only try to place a word horizontally if it can ALSO be placed vertically:
1
2
3
4
5
6
7
8
9
10
11
12
13
            if (score_v == current_word.length()) {
                if (k % 2 == 0) {
                    ...
                    goto placing_word;
                }
            } else {
                ...
               goto back;
            }
            // This code is reached only when score_v==current_word.length() && k%2 != 0
            //if the horizontal score of the position is equal to the size of the word
            if (score_h == current_word.length()) {
                if (k % 2 != 0) {


When you place a word, you push each letter's coordinate into coord_x and coord_y. But you check to place them, you look at coord_x[k-1] where k is the number of the word being placed. This doesn't make sense to me, especially considering that you never clear coord_x and coord_y. You should check your logic for these values.

BUG #2: You're getting horizontal and vertical confused. In PlaceVertical() you have:
if (grid[x + j][y] == empty || grid[x + j][y] == word[j]) {
and in can_place_v you have:
if (grid[x][y + j] == empty || grid[x][y + j] == word_letter) {

And similarly for PlaceHorizontal()/can_place_h()

The first coordinate is the row number (vertical) and the second is the column (horizonal)
Hello, thank you indeed I had a confusion between the note and the placement it was reversed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//Horizontal word placement function
void PlaceHorizontal(int x, int y, int id_word, std::string &word)
{
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x][y + j] == empty || grid[x][y + j] == word[j])
		{
			grid[x][y + j] = word[j];
			coord_x.push_back(x);
			coord_y.push_back(y);
		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}

//Function placing words vertically
void PlaceVertical(int x, int y, int id_word, std::string &word)
{
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x + j][y] == empty || grid[x + j][y] == word[j])
		{
			grid[x + j][y] = word[j];
			coord_x.push_back(x);
			coord_y.push_back(y);
		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}

//function that assigns a score to the place chosen for the word
int can_place_v(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x + j][y] == empty || grid[x + j][y] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}

int can_place_h(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x][y + j] == empty || grid[x][y + j] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}


And for this line, when I do as you advise it mixes up the letters of the word, I don't understand why. The word is unreadable at the end of the function.
 
std::string intersec = find_intersection(words_vect[k-1], words_vect[k]);



"I don't see any code to verify whether a word will run off the end of the grid."

I don't understand what you're trying to tell me.


My logic is this: coord_x[k-1] and coord_y[k-1] are the coordinates of the word placed before, having an alternation of even and odd numbers I thus make sure not to place the following word in the same way as the previous one. Assuming that I have the same number of coordinates as the word placed, by taking the index k I make sure to find a match.

Sorry I didn't take the order of your ideas/questions to answer you.


Last edited on
And for this line, when I do as you advise it mixes up the letters of the word, I don't understand why. The word is unreadable at the end of the function.

I suspect you only did half of what I suggested. You missed this part:
pass the words to find_intersection by value


The words get scrambled because find_intersection sorts the letters in each word. You need to change it to pass the arguments by value:
1
2
std::string find_intersection(std::string first, std::string second)
{ ...


dhayden wrote:
I don't see any code to verify whether a word will run off the end of the grid.
oneidacharisse wrote:
I don't understand what you're trying to tell me.

You have a 25x25 grid of letters. You place words in the grid. What prevents you from placing. say, "birthday" horizontally at position row=2,col=20? If you put it there, the word will "spill out" beyond column 25.

My logic is this: coord_x[k-1] and coord_y[k-1] are the coordinates of the word placed before
But you push x,y for each letter in the word. So if you place "birthday" at (8,5), then coord_x contains {8, 8, 8, 8, 8, 8, 8, 8 } and coord_y contains {5, 5, 5, 5, 5, 5, 5, 5 }. You need to push back just one number to each inside PlaceHorizontal and PlaceVertical.
{
Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//Horizontal word placement function
void PlaceHorizontal(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x][y + j] == empty || grid[x][y + j] == word[j])
		{
			grid[x][y + j] = word[j];

		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}

//Function placing words vertically
void PlaceVertical(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x + j][y] == empty || grid[x + j][y] == word[j])
		{
			grid[x + j][y] = word[j];

		}
		else
		{
			std::cout << "Placing word : " << word << " is impossible ! " << "\n";
		}
	}
}


Because if I don't remember both coordinates, I can't place the next word.

And to replace the word if it doesn't fit how do I do with a function to be able to go back to the search for an intersection letter without goto I do k-1 and let the for arrive at the end?

1
2
3
4
5
6
7
8
std::string replace_word(std::string & current_word)
{
                                //replaces the word and goes back to the beginning of the checks.
					int rand3 = random(100, 20000);
				std::string replacement = randomword(rand3);

				std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
}


Otherwise it doesn't actually work, it's because my scoring loop was wrong that he managed to come back. In this loop:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
		if (score_h == current_word.length())
			{
				if (k % 2 != 0)
				{
					place_h = true;
					std::cout << " Testing word " << k << "/" << num << "\n";
					std::cout << " Current score " << score_h << "/" << current_word.length() << "\n";
					std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
					std::cout << "-----" << "\n";
					x_word2_intersection_h = temp_intersec_2;
					x_word1_intersection_h = temp_intersec_1;
					goto placing_word;
				}
			}
			else
			{
                               //I speak for that part of the loop. 
				place_h = false;
				std::cout << " Testing word " << k << "/" << num << "\n";
				std::cout << " Current score " << score_h << "/" << current_word.length() << "\n";
				std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
				std::cout << "-----" << "\n";
                                //replaces the word and goes back to the beginning of the checks.
				int rand3 = random(100, 20000);
				std::string replacement = randomword(rand3);

				std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
				goto back;
			}
Last edited on
My complete code with the modifications but as I said before the words are unreadable and the program doesn't work most of the time:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
#include <iostream>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <vector>
using namespace std;
std::vector<double> coord_x;
std::vector<double> coord_y;


//Vectors for recording word coordinates
std::vector<double> temporary_coord_x;
std::vector<double> temporary_coord_y;
std::vector<std::string > words_vect;
std::vector<std::string > intersection;

//vector to know how the word is placed in the grid vertically or horizontally (v / h)
std::vector<std::string > place;
constexpr char empty = '.';
char grid[26][26] = {
		{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' },
	{
		'.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.' }
};
//Random number generating function
int random(int from, int to)
{
	return rand() % (to - from + 1) + from;
}

//Function searching for letters common to two words
std::string find_intersection(std::string &first, std::string &second)
{
	std::sort(first.begin(), first.end());
	std::sort(second.begin(), second.end());
	int length = std::min(first.length(), second.length());
	std::string result(length, ' ');
	std::set_intersection(first.begin(), first.end(), second.begin(), second.end(), result.begin());
	return result;
}

//Horizontal word placement function
void PlaceHorizontal(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x][y + j] == empty || grid[x][y + j] == word[j])
		{
			grid[x][y + j] = word[j];

		}
	
	}
}

//Function placing words vertically
void PlaceVertical(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x + j][y] == empty || grid[x + j][y] == word[j])
		{
			grid[x + j][y] = word[j];

		}

	}
}

//function that assigns a score to the place chosen for the word
int can_place_v(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x + j][y] == empty || grid[x + j][y] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}

int can_place_h(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	int taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (grid[x][y + j] == empty || grid[x][y + j] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}
//Function randomly retrieving words from the dictionary
std::string randomword(int randomline)
{
	std::string word1;
	std::string ifileName = "dictionary.txt";
	std::ifstream f(ifileName);

	if (!f) std::cerr << "File '" << ifileName << "' couldn't opened!\n";

	std::string s;

	for (int i = 1; i < randomline; i++)
	{
		std::getline(f, s);
		std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c)
		{
			return std::tolower(c);
	});
		word1 = s;
	}

	return word1;
}
std::string replace_word(std::string &current_word)
{
        srand(time(0));
	int rand3 = random(100, 20000);
	std::string replacement = randomword(rand3);

	std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);
	
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
int main(int argc, char *argv[])
{
	int score;
	srand(time(0));
	bool place_v = false;
	bool place_h = false;
	int n;
	//number of words to place
	int rand0 = random(5, 10);
	int num = rand0;

	//position of the horizontal and vertical intersection letter
	int x_word2_intersection_h;
	int x_word1_intersection_h;
	int x_word2_intersection_v;
	int x_word1_intersection_v;
	int number;
	std::string temp1;
	std::string temp2;
	int word_index;
	std::string prec_word;
	std::string current_word;
	int temp_intersec_2;
	int temp_intersec_1;
	//score for horizontal and vertical positioning
	int score_h = 0;
	int score_v = 0;

	//random word retrieval and addition to vector
	for (unsigned int i = 0; i < num; i++)
	{
		//depending on the size of the dictionary
		int rand1 = random(100, 20000);
		std::string word1 = randomword(rand1);
		words_vect.push_back(word1);
	}

	std::string word1 = words_vect[0];
	int pos_word1 = 8;
	PlaceVertical(pos_word1, pos_word1, 0, words_vect[0]);

	for (unsigned int k = 1; k < words_vect.size(); k++)
	{
		back:
		// start of testing
		prec_word = words_vect[k - 1];
		current_word = words_vect[k];
		std::string intersec = find_intersection(words_vect[k - 1], words_vect[k]);
		
		if (intersec.empty())
		{
			replace_word(current_word);
					
		}
		else 
		{
					//for each intersecting letter of the word in the vector 
		for (unsigned int j = 0; j < intersec.length(); j++)
		{
			//temporary position of the selected intersection letter
		
				if (k % 2 != 0)
			{
					temp_intersec_2 = current_word.find_last_of(intersec[j]);
			temp_intersec_1 = prec_word.find_last_of(intersec[j]);
			score_h = can_place_h(coord_x[k - 1] + temp_intersec_2, coord_y[k - 1] - temp_intersec_1, k, current_word);
			}
			if (k % 2 == 0)
			{
					temp_intersec_2 = current_word.find_last_of(intersec[j]);
			temp_intersec_1 = prec_word.find_last_of(intersec[j]);
			score_v = can_place_v(coord_x[k - 1] - temp_intersec_1, coord_y[k - 1] + temp_intersec_2, k, current_word);
			}
			
			//if the vertical score of the position is equal to the size of the word 
			if (score_v == current_word.length() && k % 2 == 0)
			{

				place_v = true;
				std::cout << " Testing word " << k << "/" << num << "\n";
				std::cout << " Current score " << score_v << "/" << current_word.length() << "\n";
				std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
				std::cout << "-----" << "\n";
				x_word2_intersection_v = temp_intersec_2;
				x_word1_intersection_v = temp_intersec_1;
			goto placing_word;
			}
			else if (score_v != current_word.length() && k % 2 == 0)
			{
				place_v = false;

				
			
			}
			//if the horizontal score of the position is equal to the size of the word 
			if (score_h == current_word.length() && k % 2 != 0)
			{

				place_h = true;
				std::cout << " Testing word " << k << "/" << num << "\n";
				std::cout << " Current score " << score_h << "/" << current_word.length() << "\n";
				std::cout << " Current word1 " << prec_word << " Current word2 " << current_word << "\n";
				std::cout << "-----" << "\n";
				x_word2_intersection_h = temp_intersec_2;
				x_word1_intersection_h = temp_intersec_1;
				goto placing_word;
			}
			else if (score_h != current_word.length() && k % 2 != 0)
			{
				place_h = false;
					
		
				
								
			}
		}
		}

		placing_word:
		if (k % 2 != 0 && place_h == true)
		{
		
			
					PlaceHorizontal(coord_x[k - 1] + x_word2_intersection_h, coord_y[k - 1] - x_word1_intersection_h, k, current_word);
			
	
			
		}
			else
		{
		std::cout << "Placing word : " <<current_word << " is impossible ! " << "\n";
	
		}

		if (k % 2 == 0 && place_v == true)
		{
		
			
					PlaceVertical(coord_x[k - 1] - x_word1_intersection_v, coord_y[k - 1] + x_word2_intersection_v, k, current_word);
			
		
		
		}
		else
		{
		std::cout << "Placing word : " <<current_word << " is impossible ! " << "\n";
		
		}
		
	}

	//grid view
	for (unsigned int i = 0; i < 26; i++)
	{
		for (int j = 0; j < 26; j++)
		{
			std::cout << grid[i][j];
			std::cout << " ";
		}

		std::cout << "\n";
	}

	words_vect.clear();
}
Last edited on
And for the debug I tried with dev c++ but it makes a mistake and shuts down the compiler.
It probably crashes because you've defined replace_word as returning a string but it returns nothing. Change it to return void.

When I run it in a debugger, it crashes in can_place_v() because x == -3. As I've said before, you really need to ensure that you don't try to place a word outside the grid.

remove srand() from replace_word().

In fact, for now I'd comment out the call to srand(). That way you can debug the program with the same set of words each time. I'd also print the grid after each word is placed. With those and a few other changes for debugging, I have this code. Note that I replaced the initialization of grid() with a call to memset() in main to reduce the size of the code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <iostream>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <vector>
using namespace std;
std::vector < double > coord_x;
std::vector < double > coord_y;

//Vectors for recording word coordinates
std::vector < double > temporary_coord_x;
std::vector < double > temporary_coord_y;
std::vector < std::string > words_vect;
std::vector < std::string > intersection;

//vector to know how the word is placed in the grid vertically or horizontally (v / h)
std::vector < std::string > place;
constexpr char empty = '.';
constexpr int GridSize=26;
char grid[GridSize][GridSize];

//Random number generating function
int
random(int from, int to)
{
    return rand() % (to - from + 1) + from;
}

//Function searching for letters common to two words
std::string find_intersection(std::string & first, std::string & second)
{
    std::sort(first.begin(), first.end());
    std::sort(second.begin(), second.end());
    int length = std::min(first.length(), second.length());
    std::string result(length, ' ');
    std::set_intersection(first.begin(), first.end(), second.begin(), second.end(),
			  result.begin());
    return result;
}

//Horizontal word placement function
void
PlaceHorizontal(int x, int y, int id_word, std::string & word)
{
    coord_x.push_back(x);
    coord_y.push_back(y);
    std::cout << "Placing " << word << " horizontally at " << x << ',' << y << '\n';
    unsigned taille = word.length();
    for (unsigned int j = 0; j < taille; j++) {
	if (grid[x][y + j] == empty || grid[x][y + j] == word[j]) {
	    grid[x][y + j] = word[j];
	}
    }
}

//Function placing words vertically
void
PlaceVertical(int x, int y, int id_word, std::string & word)
{
    coord_x.push_back(x);
    coord_y.push_back(y);
    std::cout << "Placing " << word << " vertically at " << x << ',' << y << '\n';
    unsigned taille = word.length();
    for (unsigned int j = 0; j < taille; j++) {
	if (grid[x + j][y] == empty || grid[x + j][y] == word[j]) {
	    grid[x + j][y] = word[j];
	}
    }
}

//function that assigns a score to the place chosen for the word
int
can_place_v(int x, int y, int id_word, std::string & word)
{
    int score = 0;
    unsigned taille = word.length();
    if (x < 0 || x+taille >= GridSize || y < 0 || y >= GridSize) {
	std::cout << "can_place_v("<<x << ',' << y << ',' << word <<") out of range\n";
	return 0;
    }
    for (unsigned int j = 0; j < taille; j++) {
	char word_letter = word[j];
	if (grid[x + j][y] == empty || grid[x + j][y] == word_letter) {
	    score = score + 1;
	} else {
	    score = score - 4;
	}
    }

    return score;

}

int
can_place_h(int x, int y, int id_word, std::string & word)
{
    int score = 0;
    unsigned taille = word.length();
    if (x < 0 || x >= GridSize || y < 0 || y+taille >= GridSize) {
	std::cout << "can_place_h("<<x << ',' << y << ',' << word <<") out of range\n";
	return 0;
    }
    for (unsigned int j = 0; j < taille; j++) {
	char word_letter = word[j];
	if (grid[x][y + j] == empty || grid[x][y + j] == word_letter) {
	    score = score + 1;
	} else {
	    score = score - 4;
	}
    }

    return score;

}

//Function randomly retrieving words from the dictionary
std::string randomword(int randomline)
{
    std::string word1;
    std::string ifileName = "dictionary.txt";
    std::ifstream f(ifileName);

    if (!f)
	std::cerr << "File '" << ifileName << "' couldn't opened!\n";

    std::string s;

    for (int i = 1; i < randomline; i++) {
	std::getline(f, s);
	std::transform(s.begin(), s.end(), s.begin(),[](unsigned char c) {
		       return std::tolower(c);}	);
	word1 = s;
    }

    return word1;
}

void replace_word(std::string & current_word)
{
    int rand3 = random(100, 20000);
    std::string replacement = randomword(rand3);

    std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);

}

void showGrid()
{
//grid view
    for (unsigned int i = 0; i < GridSize; i++) {
	for (int j = 0; j < GridSize; j++) {
	    std::cout << grid[i][j];
	    std::cout << " ";
	}

	std::cout << "\n";
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
int
main(int argc, char *argv[])
{
    // srand(time(0));
    memset(grid, '.', sizeof(grid));
    bool place_v = false;
    bool place_h = false;
    //number of words to place
    int rand0 = random(5, 10);
    int num = rand0;

    //position of the horizontal and vertical intersection letter
    int x_word2_intersection_h;
    int x_word1_intersection_h;
    int x_word2_intersection_v;
    int x_word1_intersection_v;
    std::string temp1;
    std::string temp2;
    std::string prec_word;
    std::string current_word;
    int temp_intersec_2;
    int temp_intersec_1;
    //score for horizontal and vertical positioning
    int score_h = 0;
    int score_v = 0;

    //random word retrieval and addition to vector
    for (int i = 0; i < num; i++) {
	//depending on the size of the dictionary
	int rand1 = random(100, 20000);
	std::string word1 = randomword(rand1);
	words_vect.push_back(word1);
    }

    std::string word1 = words_vect[0];
    int pos_word1 = 8;
    PlaceVertical(pos_word1, pos_word1, 0, words_vect[0]);

    for (unsigned int k = 1; k < words_vect.size(); k++) {
      back:
	// start of testing
	prec_word = words_vect[k - 1];
	current_word = words_vect[k];
	std::string intersec = find_intersection(words_vect[k - 1], words_vect[k]);

	if (intersec.empty()) {
	    replace_word(current_word);
	    goto back;		// dmh
	} else {
	    //for each intersecting letter of the word in the vector 
	    for (unsigned int j = 0; j < intersec.length(); j++) {
		//temporary position of the selected intersection letter

		if (k % 2 != 0) {
		    temp_intersec_2 = current_word.find_last_of(intersec[j]);
		    temp_intersec_1 = prec_word.find_last_of(intersec[j]);
		    score_h =
			can_place_h(coord_x[k - 1] + temp_intersec_2,
				    coord_y[k - 1] - temp_intersec_1, k, current_word);
		}
		if (k % 2 == 0) {
		    temp_intersec_2 = current_word.find_last_of(intersec[j]);
		    temp_intersec_1 = prec_word.find_last_of(intersec[j]);
		    score_v =
			can_place_v(coord_x[k - 1] - temp_intersec_1,
				    coord_y[k - 1] + temp_intersec_2, k, current_word);
		}
		//if the vertical score of the position is equal to the size of the word 
		if (score_v == current_word.length() && k % 2 == 0) {

		    place_v = true;
		    std::cout << " Testing word " << k << "/" << num << "\n";
		    std::cout << " Current v score " << score_v << "/" << current_word.length() << "\n";
		    std::cout << " Prev word " << prec_word << " Current word " <<	current_word << "\n";
		    std::cout << "-----" << "\n";
		    x_word2_intersection_v = temp_intersec_2;
		    x_word1_intersection_v = temp_intersec_1;
		    goto placing_word;
		} else if (score_v != current_word.length() && k % 2 == 0) {
		    place_v = false;

		}
		//if the horizontal score of the position is equal to the size of the word 
		if (score_h == current_word.length() && k % 2 != 0) {

		    place_h = true;
		    std::cout << " Testing word " << k << "/" << num << "\n";
		    std::cout << " Current h score " << score_h << "/" << current_word.length() << "\n";
		    std::cout << " Prev word " << prec_word << " Current word " <<	current_word << "\n";
		    std::cout << "-----" << "\n";
		    x_word2_intersection_h = temp_intersec_2;
		    x_word1_intersection_h = temp_intersec_1;
		    goto placing_word;
		} else if (score_h != current_word.length() && k % 2 != 0) {
		    place_h = false;

		}
	    }
	}

      placing_word:
	if (k % 2 != 0) {
	    if (place_h == true) {
		PlaceHorizontal(coord_x[k - 1] + x_word2_intersection_h,
				coord_y[k - 1] - x_word1_intersection_h, k, current_word);
	    } else {
		std::cout << "Placing word : " << current_word << " horizontally is impossible ! " << "\n";
		return 1;
	    }
	} else {
	    if (place_v == true) {
		PlaceVertical(coord_x[k - 1] - x_word1_intersection_v,
			      coord_y[k - 1] + x_word2_intersection_v, k, current_word);

	    } else {
		std::cout << "Placing word : " << current_word << " vertically is impossible ! " << "\n";
		return 1;
	    }
	}
	showGrid();
    }

    showGrid();

    words_vect.clear();
}


Here is the start of the output that I get. Your output will be different because you're using a different dictionary and your rand() may be different from mine:
$ ./foo
Placing alertest vertically at 8,8
 Testing word 1/10
 Current h score 10/10
 Prev word alertest Current word afraidness
-----
Placing afraidness horizontally at 17,2
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . a . . . . . . . . . . . . . . . . .
. . . . . . . . l . . . . . . . . . . . . . . . . .
. . . . . . . . e . . . . . . . . . . . . . . . . .
. . . . . . . . r . . . . . . . . . . . . . . . . .
. . . . . . . . t . . . . . . . . . . . . . . . . .
. . . . . . . . e . . . . . . . . . . . . . . . . .
. . . . . . . . s . . . . . . . . . . . . . . . . .
. . . . . . . . t . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . a f r a i d n e s s . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
 Testing word 2/10
 Current v score 6/6
 Prev word aadefinrss Current word almous
-----
Placing almous vertically at 8,7


Some immediate problems to consider:
- Why didn't it place "afraidness" so it overlaps "alertest"? It overlaps with 'a', 'e', 'r', and 's'.
- When placing almous, why is afraidness() all scrambled? Ah. I see that you STILL haven't done what I suggested for find_intersection(). Pass the parameters by value instead of by reference.
Ok thank you very much, I had modified the code to make it work better but I'll start from your code again.

and for find_intersection you mean like in this example:
1
2
3
4
5
6
std::string do_something ( std::string inval )
{
   std::string return_val;
   // ... do stuff ...
   return return_val;
}


without the & sign ?

which would be:

1
2
3
4
5
6
7
8
9
10
std::string find_intersection(std::string first, std::string second)
{
    std::sort(first.begin(), first.end());
    std::sort(second.begin(), second.end());
    int length = std::min(first.length(), second.length());
    std::string result(length, ' ');
    std::set_intersection(first.begin(), first.end(), second.begin(), second.end(),
			  result.begin());
    return result;
}


and the function call would be the same ?
I'll work on it. Thanks again.
Last edited on
regarding find_intersection, yes, that's what I mean.

BTW, I find it really confusing dealing with the grid when the first dimension is the row number and the second is column, but you use variables x and y for the first and second indexes. That means x is the row number, which increases in the vertical direction, and y is the column, which increases in the horizontal direction. You might want to change your variables to "row" and "column" or r and c to make it easier to understand.
Hi, okay, I'll do it next time. Here I cleaned up the useless variables and made the corrections based on your code. I left the random to see. The program still crashes despite the fact that in the placement test functions I take care of the grid dimension to avoid in getting out. I hope that I have taken into account everything you told me. I'm learning a lot, that's great, thanks again. Here is my corrected code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include <iostream>
#include <string>
#include <algorithm>
#include <bits/stdc++.h>
#include <stdlib.h>
#include <sstream>
#include <ctime>
#include <vector>
using namespace std;

//Vectors for recording word coordinates
std::vector<double> coord_x;
std::vector<double> coord_y;
//Vectors for recording words
std::vector<std::string > words_vect;

constexpr char empty = '.';
constexpr int GridSize = 26;
char grid[GridSize][GridSize];

//Random number generating function
int random(int from, int to)
{
	return rand() % (to - from + 1) + from;
}

//Function searching for letters common to two words
std::string find_intersection(std::string first, std::string second)
{
	std::sort(first.begin(), first.end());
	std::sort(second.begin(), second.end());
	int length = std::min(first.length(), second.length());
	std::string result(length, ' ');
	std::set_intersection(first.begin(), first.end(), second.begin(), second.end(),
		result.begin());
	return result;
}

//Horizontal word placement function
void PlaceHorizontal(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	unsigned taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x][y + j] == empty || grid[x][y + j] == word[j])
		{
			grid[x][y + j] = word[j];
		}
	}
}

//Function placing words vertically
void PlaceVertical(int x, int y, int id_word, std::string &word)
{
	coord_x.push_back(x);
	coord_y.push_back(y);
	unsigned taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		if (grid[x + j][y] == empty || grid[x + j][y] == word[j])
		{
			grid[x + j][y] = word[j];
		}
	}
}

//function that assigns a score to the place chosen for the word
int can_place_v(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	unsigned taille = word.length();
	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (x < GridSize && y < GridSize && grid[x + j][y] == empty || grid[x + j][y] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}

int can_place_h(int x, int y, int id_word, std::string &word)
{
	int score = 0;
	unsigned taille = word.length();

	for (unsigned int j = 0; j < taille; j++)
	{
		char word_letter = word[j];
		if (x < GridSize && y < GridSize && grid[x][y + j] == empty || grid[x][y + j] == word_letter)
		{
			score = score + 1;
		}
		else
		{
			score = score - 4;
		}
	}

	return score;

}
//Function randomly retrieving words from the dictionary
std::string randomword(int randomline)
{
	std::string word1;
	std::string ifileName = "dictionary.txt";
	std::ifstream f(ifileName);

	if (!f)
		std::cerr << "File '" << ifileName << "' couldn't opened!\n";

	std::string s;

	for (int i = 1; i < randomline; i++)
	{
		std::getline(f, s);
		std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c)
		{
			return std::tolower(c);
	});
		word1 = s;
	}

	return word1;
}
void replace_word(std::string &current_word)
{

	int rand3 = random(100, 20000);
	std::string replacement = randomword(rand3);
	std::replace(words_vect.begin(), words_vect.end(), current_word, replacement);

}

void showGrid()
{
	//grid view
	for (unsigned int i = 0; i < GridSize; i++)
	{
		for (int j = 0; j < GridSize; j++)
		{
			std::cout << grid[i][j];
			std::cout << " ";
		}

		std::cout << "\n";
	}
}
Last edited on
Pages: 123456