-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCrossword.cpp
138 lines (129 loc) · 4.39 KB
/
Crossword.cpp
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
#include <bits/stdc++.h>
using namespace std;
const char DATA_FILE[] = "Crossword.txt";
typedef vector<string> vstring;
typedef vector<int> vint;
void coutCrossword(vstring &crossword)
{
for (int i = 1; i < crossword.size(); ++i)
cout << setw(3) << i << ". " << crossword[i] << '\n';
}
void getCrossword(int &crossLen, vstring &crossword, vstring &question,
vint &keyPos, const char* fileName)
{
ifstream fcin(fileName);
if (fcin.is_open() == 0) {
fcin.close(); return;
}
fcin >> crossLen;
if (crossLen < 1) {
fcin.close(); return;
}
crossword.resize(crossLen); question.resize(crossLen), keyPos.resize(crossLen);
for (int i = 0; i < crossLen; ++i) {
getline(fcin, question[i]);
getline(fcin, question[i]);
getline(fcin, crossword[i]);
fcin >> keyPos[i];
}
fcin.close(); return;
}
void processCrossword(int &crossLen, vstring &crossword, vint &keyPos,
vstring &knownWord, int &maxKeyPos)
{
for (int i = 1; i < crossLen; ++i) {
maxKeyPos = max(maxKeyPos, keyPos[i]);
}
for (int i = 1; i < crossLen; ++i) {
knownWord[i].append(maxKeyPos - keyPos[i], ' ');
knownWord[i].append(crossword[i].size(), '*');
knownWord[i][maxKeyPos - 1] = '|';
}
}
void renderGame(vstring &knownWord, int point)
{
coutCrossword(knownWord);
cout << "Point: " << point << '\n';
}
void respondToAns(int &crossLen, vstring &crossword, vint &keyPos, vstring &knownWord, int &maxKeyPos,
vector<bool> &answeredQues, string &ans, int &ques, int &point, int &wordCount)
{
bool needUpdate = 0;
if (ans != crossword[ques]) {
if (ques) {
needUpdate = 1;
cout << "Wrong! The correct answer is: " << crossword[ques];
}
else cout << "Wrong!";
}
else {
needUpdate = 1;
point += ((ques == 0) ? wordCount : 1);
cout << "Right! Your point now is: " << point;
}
cout << '\n';
//Update
if (needUpdate == 0) return;
--wordCount;
answeredQues[ques] = 1;
if (ques) {
int startPos = maxKeyPos - keyPos[ques];
for (int i = knownWord[ques].size() - 1; i >= startPos; --i)
knownWord[ques][i] = crossword[ques][i - startPos];
}
else {
for (int i = 1; i < crossLen; ++i)
knownWord[i][maxKeyPos - 1] = crossword[0][i - 1];
}
}
int main()
{
//Init crossword
int crossLen;
vstring crossword, question;
vint keyPos;
getCrossword(crossLen, crossword, question, keyPos, DATA_FILE);
if (crossword.size() < 1) {
cout << "Invalid crossword file " << DATA_FILE;
return -1;
}
vstring knownWord(crossLen);
int maxKeyPos = 0;
vector<bool> answeredQues(crossLen, 0);
processCrossword(crossLen, crossword, keyPos, knownWord, maxKeyPos);
//Interactive part
int wordCount = crossLen, point = 0;
do {
renderGame(knownWord, point);
cout << "Type the number of a question to answer it(0 to answer the keyword)\n";
int ques;
string tmp;
while (1)
{
cin >> tmp;
bool valid = 1;
for (auto &c : tmp)
if (c < '0' || c > '9') valid = 0;
if (valid == 0) {
cout << "Invalid input. Please type again\n";
continue;
}
ques = 0;
for (auto &c : tmp) ques = ques * 10 + c - '0';
if (ques < 0 || ques >= crossLen || answeredQues[ques]) {
cout << "Invalid input. Please type again\n";
continue;
}
break;
}
if (ques != 0) cout << question[ques] << '\n';
cout << "The number of character is " << crossword[ques].size() << ". Please type the answer\n";
string ans;
cin >> ans;
tmp = ans;
transform(tmp.begin(), tmp.end(), ans.begin(), ::tolower); //make lower case string
respondToAns(crossLen, crossword, keyPos, knownWord, maxKeyPos, answeredQues, ans, ques, point, wordCount);
} while (wordCount && (wordCount != 1 || answeredQues[0])); //dung khi het ques hoac chi con keyword
cout << "Congratulation! Your final point is: " << point;
return 0;
}