메모리 영역에 대한 복습이다. 주로 각 영역에 저장되는 것들을 한번에 알아보기 위해서 작성하였다.
기존 공부 자료 에 부족함이 보여 추가적으로 복습한다.
https://rhksgml78.tistory.com/43
이전 공부했던 자료를 참조하여 메모리의 각영역에 저장되는 것들을 나누어 보고자 한다.
◆프로세스 메모리 영역
- 프로세스 : 현재 실행중인 프로그램
◆커널(Kernel) 영역
- 윈도우즈(Windows)가 사용하는 공간
- 단일 공간으로 커널 모드를 사용하는 모든 프로세스에 공유된다.
- 시스템 운영에 필수적이기 때문에 RAM에 존재한다.
주기억장치 & 보조기억 장치 기존 조사 자료를 참조하자
https://rhksgml78.tistory.com/5
◆코드(CODE) 영역
- 이름공간, 함수, 제어문에 대한 기계어 코드가 저장됨
- 문자열의 상수를 제외한 지역변수에 해당되는 리터럴 상수(Literal Constant)가 기계어로 저장
- 작성한 코드가 저장되는 공간
- 라이프 타임 : 프로그램 시작 ~ 종료 까지
◆데이터(DATA) 영역
- .rodata : 읽기전용으로 초기화되는 영역(const선언),전역변수,정적변수,배열,구조체,문자열 저장
- .data : 0이아닌 값으로 초기화된 전역변수 혹은 정적변수 저장 (읽기,쓰기 가능한 영역)
- .bss : 0으로 초기화, 초기화 되지않은 전역변수, 정적변수를 저장 (Block Started Symbol)
- 전역변수, 정적변수(static)
- 모든 전역 변수는 별도로 초기화되지 않으면 모두 0으로 초기화된다.
- 라이프 타임 : 프로그램 시작 ~ 종료 까지
◆스택(STACK) 영역
- 지역변수(로컬변수)(매개변수 포함) 저장
- LIFO (후입선출 : Last In First Out)
- 로컬 변수는 const 키워드가 붙어도 스택 영역에 저장된다.(필드 종료시 삭제되어야 하기때문)
- 라이프 타임 : 필드 '{'시작 ~ 종료'}' 까지
◆힙(HEAP) 영역
- 동적 할당 변수 (C : malloc / C++ : new)
- 프로그램 동작 중 사용자가 원할 때 생성하고 원할때 해제 할수있는 변수들이 저장
- 라이프 타임 : 동적할당 ~ 해제 까지 (C++ : new ~ delete 까지)
◆기타 메모리 공간에 할당되지 않는 것들
- 매크로 상수 (Macro Constant) = #define 전처리 과정에서 치환되므로 메모리공간 할당 x
- 열거체 (Enumeration) = 정수 값에 이름을 붙인 형태 > 정수형으로 치환 메모리공간 할당x
#define 그리고 enum 열거체는 Black Jack 게임 작성 코드에서 한번에 확인 할수 있다.
블랙잭 코드는 접은글로 첨부한다.
더보기
#include <iostream>
#include <time.h>
#include <string>
#include <vector>
#define SET 3
using namespace std;
enum Shape //모양 함수 4종류
{
DIA,
CLOVER,
HEART,
SPADE
};
enum Num //특정숫자는 문자출력을 위한 함수
{
A = 1,
J = 11,
Q,
K
};
struct Card // 구조체 카드 (숫자, 모양, 특정숫자는 문자변환출력)
{
int num;
string shape;
void Print()
{
switch (num)
{
case A:
cout << shape << "A" << "\t";
break;
case J:
cout << shape << "J" << "\t";
break;
case Q:
cout << shape << "Q" << "\t";
break;
case K:
cout << shape << "K" << "\t";
break;
default:
cout << shape << num << "\t";
break;
}
}
};
struct Player //플레이어 구조체 (이름 돈 카드 점수 승패 카드패출력)
{
string name;
int money;
vector<Card>card;
int jokbo = 0; //카드의합 초기화 = 처음상태는 0
bool win; //승패용 변수
void MakeJokbo(bool dealer = 0)
{
jokbo = 0;
int select; //플레이어의 패중에 A의카드가있을시 1또는 11점수 선택용 변수
for (int i = 0; i < card.size(); i++) //카드갯수만큼 반복시킬 반복문
{
if (card[i].num > 10) //카드의 넘버가 10이상인경우는 무조건 10만 더해지도록설정
{
jokbo += 10;
}
else if (card[i].num == 1) //카드가 1 즉,카드가 A패일 경우
{
if (!dealer) // 딜러가아닐때 = 즉, 플레이어일때
{
for (int i = 0; i < card.size(); i++) // 카드패만큼반복하면서 출력시킴
{
card[i].Print();
}
cout << "A카드획득. 카드점수선택. [1]=1점 / [2]=11점 "; //점수선택 출력
cin >> select; //선택 입력
if (select == 1) //1번선택
{
jokbo += 1; // 1번카드는 점수1점
}
else if (select == 2) // 2번선택
{
jokbo += 11; // 1번카드는 점수11점
}
}
else
{
jokbo += 1; //그외에는 그냥 A카드 1점더하기
}
}
else // a카드가 아니고 다른카드일경우 그냥 일반점수더하기
{
jokbo += card[i].num;
}
}
}
void Print(bool dealer = 0)
{
cout <<"["<< name<<"]" << "\t";
for (int i = 0; i < card.size(); i++) // 딜러도 플레이어도 점수는 출력된다
{
card[i].Print();
}
cout << "점수 : " << jokbo << "\t";
if (!dealer) //딜러가아니라면 = 플레이어라면 소지금 출력
{
cout << "소지금 : " << money << "\t";
}
cout << endl;
}
};
Card MakeDeck(int num, string shape) //카드덱 만들기, 구조체안에있는 숫자 모양 불러오기
{
Card temp; // 카드덱의 빈 인덱스 생성
temp.num = num; // 빈인덱스의 숫자생성
temp.shape = shape; // 빈인덱스의 모양생성
return temp; // 빈인덱스 반환
}
void Shuffle(vector<Card>& deck) //카드섞기(셔플) 벡터로할당된 카드구조체의 덱주소
{
for (int i = 0; i < 1000; i++) //대충 천번정도 셔플해주기
{
int sour = rand() % (52 * SET); //52개의 카드 총 SET갯수 전부 셔플해준다.
int dest = rand() % (52 * SET);
Card temp = deck[sour]; //기본셔플형식. 단 카드구조체셔플.
deck[sour] = deck[dest];
deck[dest] = temp;
}
}
//===============================================================================함수구성끝
int main() // 메인 시작
{
srand(time(NULL));
vector<Card>deck;
Player* player;
Player dealer;
int cardCount = 0; //카드의 합계산을위한 초기화
int input;
int size;
//덱만들기
for (int i = 0; i < 52*SET; i++) // 총카드는 52개가한묶음으로 define SET 갯수만큼 곱해진다.
{ // 52개의 묶음 *3 이기때문에 같은카드는 3개까지 나오게된다.
string temp;
int cut = i % 52; // 0~51까지 카운트후 다시 0부터 51까지만 카운트되도록
switch (cut / 13) // 52개의 카드는 4종류의 모양으로 나뉜다. 초 4종 각각 13장씩 52장
{
case DIA:
temp = "◆";
break;
case CLOVER:
temp = "♣";
break;
case HEART:
temp = "♥";
break;
case SPADE:
temp = "♠";
break;
}
deck.push_back(MakeDeck(i % 13 + 1, temp));
}
//========================================== 게임 시작전 기본세팅
cout <<"\t" << "[블랙잭 게임]"<<"\t" << endl;
cout << endl;
cout << "게임에 참가할 인원수를 입력해 주세요 : " << "\t"; cin >> size;
cout << endl;
player = new Player[size]; //플레이어의 인원수입력에따른 동적할당.
for (int i = 0; i < size; i++) //참가인원수 만큼 반복하며 이름 입력받기
{
cout << i + 1 << "번 참가자의 이름을 입력 : " << "\t";
cin >> player[i].name; // 구조체에 동적할당 받았기때문에 직접 palyer[i].name 에 접촉이 가능
player[i].money = 100000; // 플레이어들의 소지금은 단순히 통일시킴.
}
dealer.name = "딜러"; // 딜러의 이름은 단순히 딜러
dealer.money = 100000; // 딜러도 일단 금액설정해둔다.
//=========================================== 본게임 시작
while (true) //게임은 게속 반복 되도록 설정
{
cardCount = 0; //카드나누어줄때 같은 배열에있는 카드가 겹치지않도록 카운트초기화
//0번배열에있는 카드부터 순차대로 나눠준다.
//카드는 나눠줄때마다 배열순서대로 나눠준다 (배열은 셔플되어있음)
Shuffle(deck); // 게임시작전 덱셔플해주기
for (int i = 0; i < size; i++) //게임 인원수 설정만큼 반복
{
cout << endl;
cout << "=======================================" << player[i].name << "의 차례입니다." << endl;
cout << endl;
player[i].win = true; //게임플레이어의 상태는 기본 참값으로 하여 진행되도록한다.
player[i].money -= 1000; // 새게임마다 1천원씩 소지금 감소
player[i].card.clear(); //새게임시작시 기존의 카드패는 초기화
player[i].card.push_back(deck[cardCount]); //새로운 카드 벡터로 1장받는다
cardCount++; //카드배열 하나증가. (0번카드 받고 다음받을수있는카드는 1번카드)
player[i].card.push_back(deck[cardCount]); //새로운 카드 벡터로 1장받는다
cardCount++; //카드배열 하나증가. (1번카드 받고 다음받을수있는카드는 2번카드)
//카드를 받았다면 현재 카드의 합을 보여준뒤 더받을지 멈출지 확인하기
player[i].MakeJokbo(); //플레이어의 족보(카드의합)을 계산시킨다.
//그리고나서 출력
player[i].Print(); // 프린트 함수를 이용하여 소지카드 점수 소지금 등을 보이게한다.
//출력이되어 확인하였으면 추가카드 받기여부
while (true) //버스트하거나 그만받을때까지 반복한다
{
cout << "추가카드를 받으시겠습니까? [1]YES / [2]NO" << "\t"; cin >> input;
if (input == 2)
{
break; // 카드를 더안받는선택시 반복문 탈출한다.
}
// 2번선택이 아니라면 아래 코드진행
player[i].card.push_back(deck[cardCount]); //카드한장만 더받고
cardCount++; // 이후 제공될 카드 인덱스카운트 증가
player[i].MakeJokbo(); // 카드를 받아서 다시 점수 계산을하고
player[i].Print(); // 출력시킨다
if (player[i].jokbo > 21) //플레이어의 카드점수가 21점이 넘어갔을경우
{
cout << player[i].name << "참가자가 버스트 ! " << endl;
player[i].win = false; // 플레이어의 승리가 거짓값으로 바뀐다 = 패배.
break; //진행중인 반복문을 탈출한다.
}
else
{
player[i].win = true; // 카드합계가 21이넘지않는한 플레이어의 상태는 그대로이다.
}
}
}
//플레이어 설정후 딜러 설정
dealer.win = true; //딜러의 상태도 기본 참값이다.
dealer.card.clear(); //딜러도 마찬가지로 게임시작때마다 패는 초기화 시킨다.
dealer.card.push_back(deck[cardCount]);
cardCount++;
dealer.card.push_back(deck[cardCount]);
cardCount++; // 딜러도 매판마다 카드 2장을 받으며 분배할카드 인덱스는 줄때마다증가.
cout << endl;
cout << "=======================================" << dealer.name << "의 차례입니다." << endl;
cout << endl;
//딜러패의 합계산
dealer.MakeJokbo(true); // 함수의 매개변수가 참인이유는 함수는 플레이어 함수에 들어가지않게하기위해서
//딜러패의 출력
dealer.Print(true); // 매개변수가 참인이유는 위와 동일.
//딜러는 카드의합이 17미만인경우 자동적으로 카드를 더 받도록 설정한다.
while (dealer.jokbo < 17)
{
dealer.card.push_back(deck[cardCount]); //조건에일치하면 카드한장을 더받고
cardCount++; //카드인덱스 1증가
dealer.MakeJokbo(true); //딜러패의 점수 계산
dealer.Print(true); //게산후 출력
if (dealer.jokbo > 21) //딜러의 점수가 21점이 넘으면 버스트시키고
{
cout << dealer.name << " 의 버스트 ! " << endl;
dealer.win = false; //딜러의 상태는 패배가된다.
for (int i = 0; i < size; i++) //플레이어 인원수만큼 반복문을 돌려서
{
if (player[i].win) //만약 플레이어의 상태가 win 이라면
{
cout << player[i].name << " 승리 ! " << endl; //해당플레이어의 승리
player[i].money += 3000; //승리한 플레이어는 소지금이 3천원 추가된다.
}
}
break; // 반복문을 탈출한다.
}
else
{
dealer.win = true; // 점수의 합이 21만넘지않는다면 패배상태가 아니다.
}
}
//반복문 내에서 승패 비교까지 이루어져야한다.
for (int i = 0; i < size; i++) // 승패조건의검사는 플레이어의 수만큼 반복되서 검사된다
{
if (dealer.win && player[i].win) // 딜러와 플레이어 양쪽이 버스트가 아닌상태에서
{
if (dealer.jokbo < player[i].jokbo) // 딜러의 점수보다 플레이어의 점수가 높다면
{
cout << player[i].name << " 승리 ! " << endl; //해당플레이어의 승리
player[i].money += 3000; //승리한 플레이어는 소지금이 3천원 추가된다.
}
else if (dealer.jokbo = player[i].jokbo)
{
cout << player[i].name << " 패배 ! " << "\t";
cout << "동점은 딜러 승리 입니다. " << endl;
player[i].win = false;
}
else
{
cout << "딜러 승리 입니다 ! " << endl;
cout << player[i].name << " 패배 ! " << endl;
player[i].win = false;
}
}
}
}
for (int i = 0; i < size; i++)
{
delete[i] player;
}
delete[] player;
return 0;
}
'공부' 카테고리의 다른 글
수학 - 삼각 함수 / 삼각비 (0) | 2022.12.06 |
---|---|
Win32 API 프로시저 / 메시지 / 메시지 루프 / 메시지 큐 (0) | 2022.12.03 |
C++ static & const 복습 (0) | 2022.12.01 |
C++ 함수 포인터 / 멤버 함수 포인터 (0) | 2022.11.30 |
C++ 생성자(복사,이동,push_back,emplace_back) (0) | 2022.11.30 |
댓글