C++ 공부 13일 차
오늘은 객체지향에 대한 개념을 공부했습니다. 이번 챕터부터 문제들의 난이도가 많이 올라서 내일 문제 풀이를 추가로 올리겠습니다.
객체지향 설계 지침
1. 결합성(Cohesion)
- 클래스는 단일 요소를 설명하고 모든 클래스 동작은 분명한 목적을 제공하기 위해 함께 논리적으로 부합되어야합니다.
2. 일관성(Consistency)
- 이름 명명을 표준 프로그래밍 형식과 이름 명명 규칙을 따르며, 일관성 있게 이름을 선택하여아 한다. 또한, 인수가 없는 생성자를 일관성 있게 사용하는게 좋으며, 만약 사용하지 않는다면 주석문에 기록해 놓는게 좋다.
3. 캡슐화(Encapsulation)
- 사용자가 클래스의 데이터에 직접 접근할 수 없게하기 위해서 private 변경자를 사용하고, get 함수(읽기)나 set 함수(갱신)를 이용하여 클래스의 데이터에 접근할 수 있도록 한다.
4. 명확성(Clarity)
- 클래스는 설명하기 쉽고 이해하기 쉬운 명확한 규칙을 가져야합니다. 많은 다른 조합과 명령, 환경에서 클래스를 통합할 수 있지만 다른 데이터로부터 유도될 수 있는 데이터는 선언하지 않아야 한다.
5. 완성도(Completeness)
- 클래스는 많은 사용자들이 사용할 수 있도록 설계되어야 합니다. 속성과 함수를 통해 사용자 정의를 위한 다양한 방법을 제공해야 한다.
(21.08.18 수정 - 문제 추가)
- 10.15(게임: 행맨) ***
임의로 한 단어를 생성하고, 사용자가 한 번에 한 문자만을 추측하도록 하는 행맨(hangman) 게임을 작성하여라.
hangman.h
#pragma once
#ifndef HANGMAN_H
#define HANGMAN_H
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
class Hangman {
public:
Hangman(std::string& problemWord);
char inputChar();
bool checkChStar(char ch);
bool checkStar();
void guessCh(char ch);
void playHangman();
private:
int state;
int collectCount;
int missCount;
std::string word;
std::string star;
};
#endif
private의 변수들 설명
- state : collectCount가 달라졌는지 확인하기 위한 변수. 만약 collectCount가 달라지지 않았다면 missCount를 증가시킨다.
- collectCount : 임의의 word에서 총 몇개가 맞는 단어인지 count 합니다. 만약 word의 사이즈와 같아지면 게임을 종료합니다.
- missCount : 게임을 진행하면서 몇 개를 틀렸는지 count 합니다. 게임이 끝나면 출력합니다.
- word : 임의의 단어입니다. 객체가 생성될 때 입력되어집니다.
- star : word의 size 만큼 *로 채운 string 변수입니다. 사용자가 문자를 맞출 때 마다 * 대신 해당 문자로 교체됩니다.
hangman.cpp
#include "hangman.h"
Hangman::Hangman(std::string& problemWord) {
state = 0;
collectCount = 0;
missCount = 0;
word = problemWord;
star = std::string(word.size(), '*');
}
char Hangman::inputChar() {
std::cout << "(Guess) Enter a letter in word " << star << " > ";
char ch;
std::cin >> ch;
return ch;
}
bool Hangman::checkChStar(char ch) {
for (int i = 0; i < star.size(); i++) {
if (star[i] == ch) {
std::cout << "\t" << ch << " is already in the word" << std::endl;
return true;
}
}
return false;
}
bool Hangman::checkStar() {
if (collectCount != word.size()) return true;
else {
std::cout << "The word is " << word << ". You missed " << missCount << " time" << std::endl;
return false;
}
}
void Hangman::guessCh(char ch) {
for (int i = 0; i < word.size(); i++) {
if (word[i] == ch) {
star.erase(i, 1);
star.insert(i, 1, ch);
collectCount++;
}
}
if (state == collectCount) {
std::cout << "\t" << ch << " is not in the word" << std::endl;
missCount++;
}
else state = collectCount;
return;
}
void Hangman::playHangman() {
while (checkStar()) {
char ch = inputChar();
if (checkChStar(ch)) continue;
guessCh(ch);
}
return;
}
- Hangman 생성자 : 클래스 Hangman의 객체를 생성해주는 생성자. 임의의 string word를 입력받아서 word와 star의 값을 생성하며, state, collectCount, missCount를 초기화한다.
- inputChar : 사용자로부터 문자 1개를 입력 받습니다.
- checkChStar : 인수 ch가 star에 있는지 확인하며, 만약 있다면 이미 입력된 문자라고 출력하고 다시 입력을 받습니다.
- checkStar : collectCount와 word의 사이즈를 확인해서 같다면 word와 missCount를 출력합니다.
- guessCh : 입력받은 문자 ch와 word를 비교하여 맞는 문자가 있는지 확인합니다. 만약 1개라도 맞는게 있다면 star에 *를 문자로 교체하고, collectCount를 증가시킵니다. 만약 맞는게 없다면 해당 문자 ch는 word에 없는 문자라고 출력하고 missCount를 증가시킵니다.
- playHangman : while문을 사용하여 checkStar가 false를 반환하기 전까지 계속 반복합니다.
main.cpp
#include "hangman.h"
int main() {
srand(time(0));
while (true) {
std::string words[10] = { "write", "that", "java", "korea", "master", "location", "program", "consider", "hello", "world"};
Hangman game(words[rand() % 10]);
game.playHangman();
std::cout << std::endl << "Do you want to guess for another word? Enter y or n>";
char answer;
std::cin >> answer;
if (answer == 'n') break;
}
return 0;
}
기본적으로 무한 루프를 사용합니다.
임의의 단어들을 생성하여 Hangman 객체인 game에 1개의 단어를 입력합니다.
그리고 playHangman 함수를 실행하여 게임을 시작하고, 게임이 끝나면 다시 한번 더 할 것인지 물어봅니다. 만약 사용자가 y를 입력하며 다시 hangman 게임을 시작하고, n을 입력하며 무한 루프문을 탈출하여 프로그램을 종료합니다.
아래는 해당 프로그램의 출력 결과입니다.
'Week4' 카테고리의 다른 글
Week 4 - 21.08.19 (0) | 2021.08.19 |
---|---|
Week 4 - 21.08.18 (0) | 2021.08.18 |
Week 4 - 21.08.16 (0) | 2021.08.17 |