Jumble Game
#include<iostream>
#include<string>
#include<cstdlib>
#include<ctime>
using namespace std;
int main(void) {
enum fields {WORD, HINT, NUM_FIELDS};
const int NUM_WORDS = 5;
const string WORDS[NUM_WORDS][NUM_FIELDS] = {
{"wall","Do you feel you're banging your head against something?"},
{"glasses","These might help you see the answer."},
{"labored","Going slowly, is it?"},
{"persistent","keep at it"},
{"jumble","it's what the game is all about."}
};
enum difficulty{EASY, MEDIUM, HARD, NUM_DIFF_LEVELS};
cout << "There are " << NUM_DIFF_LEVELS << " difficulty levels";
srand(static_cast<unsigned int>(time(nullptr)));
int choice = (rand() % NUM_WORDS);
string theWord = WORDS[choice][WORD]; //정답 변수에 저장
string theHint = WORDS[choice][HINT]; //힌트 변수에 저장
string jumble = theWord; //만약 chice가 3이라면 jumble에는 persistent 저장
int length = jumble.size();
for (int i = 0; i < length; ++i) {
int index1 = (rand() % length); //choice가 3이면 length는 10:index1 이 갖을 수 있는 값은 0~9
int index2 = (rand() % length);
char temp = jumble[index1]; //철자 교환
jumble[index1] = jumble[index2];
jumble[index2] = temp;
}
cout << "\t\tWelcome to Word Jumble" << endl << endl;
cout << "Unscramble the letters to make a word" << endl;
cout << "Enter 'hint' for a hint" << endl;
cout << "Enter 'quit' to quit the game" << endl;
cout << "The Jumble is : " << jumble;
string guess;
cout << "\n\nYour guess: ";
cin >> guess;
while ((guess != theWord) && guess != "quit") {
if (guess == "hint")
cout << theHint;
else
cout << "Sorry, that's not it";
cout << "\n\nYour guess: ";
cin >> guess;
}
if (guess == theWord)
cout << endl << "That's it! You guessed it" << endl;
cout << endl << "Thanks for playing" << endl;
return 0;
}
- 벡터 멤버 함수를 사용하여 시퀀스 요소를 조작
- 반복자를 사용하여 시퀀스 이동
- 알고리즘을 사용하여 요소 그룹 작업
컨테이너를 사용하면 동일한 타입의 값 컬렉션을 저장하고 액세스할 수 있습니다.
컨테이너는 단순하지만 신뢰할 수 있으며 배열보다 더 많은 유연성과 성능을 제공합니다.
알고리즘은 컨테이너들과 함께 작동합니다.
컨테이너 요소들을 분류하거나 검색, 복사, 병합, 삽입, 제거등을 알고리즘을 사용하여 처리할 수 있습니다.
이터레이터는 컨테이너에서 요소를 식별하는 개체이며 요소 간에 이동하도록 조작할 수 있습니다.
1. 벡터는 필요에 따라 증가할 수 있지만 배열은 크기를 변경할 수 없습니다.
2. STL 알고리즘은 벡터를 사용할 수 있지만 배열은 사용할 수 없습니다.
1.벡터는 오버헤드로 약간의 여부 메모리를 필요로 합니다.
2.벡터의 크기가 커지면 성능 비용이 발생합니다.
3.환경에 따라 사용이 불가능할 수 있습니다.(예: 콘솔 환경)
벡터를 이용한 인벤토리 프로그램
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void) {
vector<string> inventory;
vector<int> intVec;
inventory.push_back("sword"); //생성된 벡터 뒤쪽으로 데이터 추가
inventory.push_back("armor");
inventory.push_back("sheild");
cout << "You have" << inventory.size() << " items." << endl;
cout << endl << "Your items: ";
for (unsigned int i = 0; i < inventory.size(); ++i) {
cout << inventory[i] << endl;
}
cout << endl << "The item name " << inventory[0] << " has";
cout << inventory[0].size();
cout << "\n격렬한 전투후 방패가 파괴되었습니다";
inventory.pop_back();
cout << endl << "Your items: " << endl;
for (unsigned int i = 0; i < inventory.size(); ++i)
cout << inventory[i] << endl;
cout << "\n당신의 모든 아이템을 도적에게 빼았겼습니다.";
inventory.clear();
if (inventory.empty()) {
cout << "\n당신의 인벤토리에는 아무것도 없습니다." << endl;
}
else
cout << "\n당신은 적어도 하나의 아이템을 소유하고 있습니다." << endl;
}
return 0;
}
컨테이너를 최대한 활용하기 위해서는 이터레이터가 핵심입니다.
이터레이터를 사용하면 시퀀스 컨테이너를 순회하는 것이 가능합니다.
이터레이터를 이용한 인벤토리 프로그램
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(void) {
std::vector<string> inventory;
inventory.push_back("sword"); //생성된 벡터 뒤쪽으로 데이터 추가
inventory.push_back("armor");
inventory.push_back("sheild");
vector<string>::iterator myIterator;
//문자열을 저장하는 벡터를 순회할 수 있는 반복자 객체생성
vector<string>::const_iterator iter;
//const타입의 반복자는 순회중인 대상의 값을 변경할 수 없다는 것이 일반 반복자와의 차이점
cout << "Your items: "<< endl;
for (iter = inventory.begin(); iter != inventory.end(); ++iter) {
cout << *iter << endl;//이터레이터도 일종의 포인터이므로 역참조를 해야함
}
cout << "\nYou trade your sword for a battle axe";
myIterator = inventory.begin();//인벤토리의 첫번째 요소가 들어있는 주소를 가리킴
*myIterator = "battle axe";
cout << "Your items: " << endl;
for (iter = inventory.begin(); iter != inventory.end(); ++iter) {
cout << *iter << endl;//이터레이터도 일종의 포인터이므로 역참조를 해야함
}
return 0;
}
알고리즘은 검색, 무작위 추출, 정렬과 같은 일반적인 작업을 위해 존재합니다.
알고리즘의 강력한 특징은 동일한 알고리즘은 컨테이너 타입이 다른 요소들과 함께 작동할
수 있다는 점입니다.(즉, 컨테이너 종류에 상관없이 사용 가능합니다).
고득점 프로그램
#include<iostream>
#include<algorithm>
#include<vector>
#include<random>
#include<iterator>
using namespace std;
int main(void) {
vector<int>::const_iterator iter;
cout << "Creating a list of scores.";
vector<int> scores;
scores.push_back(1500);
scores.push_back(3500);
scores.push_back(7500);
cout << "\nHigh scores: " << endl;
for (iter = scores.begin(); iter != scores.end(); ++iter) {
cout << *iter << endl;
}
cout << "\nFinging a score: ";
int score;
cout << "\nEnter a score to find: ";
cin >> score;
iter = find(scores.begin(), scores.end(), score);
//만약에 iter가 가리키는 주소가 scores.end()의 주소와 같다면 찾는값이 없는 것
if (iter != scores.end()) {
cout << "Score fount" << endl;
}
else {
cout << "Scores not found" << endl;
}
cout << "\nRandomize scores.";
random_device rd;
shuffle(scores.begin(), scores.end(), default_random_engine(rd()));
cout << "\nHigh scores: " << endl;
for (iter = scores.begin(); iter != scores.end(); ++iter) {
cout << *iter << endl;
}
cout << "\nSorting scores.";
sort(scores.begin(),scores.end());
cout << "\nHigh scores: " << endl;
for (iter = scores.begin(); iter != scores.end(); ++iter) {
cout << *iter << endl;
}
return 0;
}
-기본 인수(Default Parameter) 사용 : 함수의 매개변수가 거의 항상 같은 값을 전달 받는 경우에는 기본인수(호출과정에서 인수가 지정되지 않은 경우에 매개변수에 할당되는 값)를 사용하여 이 값을 지속으로 지정하는 작업을 최소화할 수 있습니다.
예를 들어 그래픽 디스플레이를 설정하는 함수가 있다고 가정해 보겠습니다. 매개변수 중 하나는 게임을 전체 화면으로 표현할지 아니면 창 모드로 표시할지를 함수에 알려주는 bool fullScreen 일 수 있습니다. 함수가 매우 자주 fullScreen에 대해 true로 호출된다고 생각하면 해당 매개변수에 기본 true인수를 부여하여 후출자가 이 디스플레이 설정 함수를 호출할 때마다 fullScreen으로 true를 전달하는 작업을 최소화 할 수 있습니다.
void setDisplay(int width,int height,boolfullScreen=true)
파라미터 목록에 기본 인수를 지정하면 나머지 모든파라미터에 대해 기본 인수를 저장해야 함.
즉, 디폴트로 지정한 매개변수의 뒤의 매개변수들은 모두 디폴트로 지정해야함.
Default Parameter 활용
#include<iostream>
#include<string>
using namespace std;
int askNumber(int high, int low = 1); //하한치는 주로 1로 설정. 기본인수로 설정
int main(void) {
int number = askNumber(5); //하한치는 디폴트값으로 설정되어 있어 호출시 생략가능
cout << "Thanks for entering: " << number << endl << endl;
number = askNumber(10, 5);
cout << "Thanks for entering: " << number << endl << endl;
return 0;
}
int askNumber(int high, int low) { //함수 정의부에서는 디폴트 값을 설정할 필요가 없습니다.
int num;
do {
cout << "Please enter a number" << " (" << low << " - " << high << "): ";
cin >> num;
} while (num > high || num < low); //입력과정에서 입력한 값이 상한치를 넘거나 하한치보다 작으면 다시 입력
return num;
}
각 함수에 매개변수 목록과 하나의 반환 형식을 지정했습니다.
좀 더 다양한 함수를 표현하기 위해 여러 인수 집합을 사용할 수 있는 함수를 원한다면 어떨까요?
예를 들어, float로 표현되는 정점 집합에 대해 3차원 변환을 수행하는 두함수가 있다고 가정합시다.
이 함수에 대해 int로 표현되는 변환함수를 사용하기 원한다면 두 개의 다른 이름으로 두개의 개별
함수를 작성하는 대신 함수에 서로 다른 매개변수 목록을 처리할 수 있도록 함수 오버로딩을
사용할 수 있습니다. 이렇게 하면 하나의 함수를 호출하여 정점을 float 또는 int로 전달할 수 있습니다.