티스토리 뷰
Stack을 이용한 자료구조 과제.
Solitaire 게임이라면...아주 전형적인 Stack 사용 예제 아닌가??
하면서도 되게 흥미로웠던 기억이 있어서 약간 정리 안된 코드지만
올려봐야지
#include<iostream> #include<vector> #include<string> #include<cstdlib> #include<time.h> #include<iomanip> using namespace std; template<class T> class Stack { public: Stack(int stackCapacity = 10); // 처음에 크기가 stackCapacity인 공백 스택을 생성 bool IsEmpty() const; // 스택의 원소 수가 0이면 true, 아니면 false를 반환 T& Top() const; // 스택의 상위 원소를 반환 void Push(const T& item); // 스택의 상위에 item을 삽입 void Pop(); // 스택의 상위 원소를 삭제 int get_topindex(){return top;} private: T *stack; // 스택 원소를 위한 배열 int top; // 톱 원소의 위치 int capacity; // 스택 배열의 크기 void ChangeSize1D(T*& a, const int oldSize, const int newSize); }; template<class T> Stack<T>::Stack(int stackCapacity) : capacity(stackCapacity), top(-1) { if(capacity < 1) throw "Stack capacity must be>0"; stack = new T[capacity]; } template<class T> inline bool Stack<T>::IsEmpty() const { return (top == -1); } template<class T> inline T& Stack<T>::Top() const { if(IsEmpty()) throw "Stack is empty"; return stack[top]; } template<class T> void Stack<T>::Push(const T& item) { if(top == capacity-1) { ChangeSize1D(stack, capacity, 2*capacity); capacity *= 2; } stack[++top] = item; } template<class T> void Stack<T>::Pop() { if(IsEmpty()) throw "Stack is empty. Cannot delete"; top--; } template<class T> void Stack<T>::ChangeSize1D(T*& a, const int oldSize, const int newSize) { if(newSize<0) throw "New length must be >= 0"; T* temp = new T[newSize]; // 새로운 배열 int number = min(oldSize, newSize); // 복사할 원소 수 copy(a, a+number, temp); delete []a; // 이전 메모리 제거 a = temp; } struct Card{ char type; string num; }; class Solitaire{ public: Solitaire(){ } void card_init(); void print_pile(); void playing_game(); private: Stack<Card>playing[7]; Stack<Card>stock; Stack<Card>waste; Stack<Card>spade, diamond, heart, clover; static string cardnum[13]; }; string Solitaire::cardnum[13]={"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; void Solitaire ::card_init(){ vector<Card>temp_card; srand((unsigned)time(NULL)); char temptype[4]={'S', 'H', 'D', 'C'}; for(int i=0;i<4;i++){ for(int j=0;j<13;j++){ Card temp; temp.type=temptype[i]; temp.num =cardnum[j]; temp_card.push_back(temp); } } for(int i=0;i<52;i++){ int first = rand()%52; int second = rand()%52; Card swap; swap=temp_card[first]; temp_card[first] = temp_card[second]; temp_card[second]=swap; } for(int i=0;i<52;i++){ if(i<1){ playing[0].Push(temp_card[i]); } else if(i<3){ playing[1].Push(temp_card[i]); } else if(i<6){ playing[2].Push(temp_card[i]); } else if(i<10){ playing[3].Push(temp_card[i]); } else if(i<15){ playing[4].Push(temp_card[i]); } else if(i<21){ playing[5].Push(temp_card[i]); } else if(i<28){ playing[6].Push(temp_card[i]); } else{ stock.Push(temp_card[i]); } } print_pile(); } void Solitaire::print_pile(){ if(waste.get_topindex()!=-1){ cout<<"waste pile="<<waste.Top().type<<"."<<waste.Top().num<<endl; } else { cout<<"waste pile="<<endl; } for(int i=0;i<7;i++){ for(int j=0;j<playing[i].get_topindex();j++){ cout<<setw(5)<<"X"; } cout<<" "<<playing[i].Top().type<<"."<<playing[i].Top().num<<endl; } if(spade.get_topindex()!=-1){ cout<<"Spade "<<spade.Top().type<<"."<<spade.Top().num<<endl; } else{ cout<<"Spade "<<endl; } if(heart.get_topindex()!=-1){ cout<<"Heart "<<heart.Top().type<<"."<<heart.Top().num<<endl; } else{ cout<<"Heart "<<endl; } if(diamond.get_topindex()!=-1){ cout<<"Diamond "<<diamond.Top().type<<"."<<diamond.Top().num<<endl; } else{ cout<<"Diamond "<<endl; } if(clover.get_topindex()!=-1){ cout<<"Clover "<<clover.Top().type<<"."<<clover.Top().num<<endl; } else{ cout<<"Clover "<<endl; } } void Solitaire::playing_game(){ bool flag = true; int num=0; bool do_some = true; while(num++<10){ if(do_some){ waste.Push(stock.Top()); stock.Pop(); } if(waste.IsEmpty()) { waste.Push(stock.Top()); stock.Pop(); } if(waste.Top().type=='S' && waste.Top().num==cardnum[spade.get_topindex()+1]){ print_pile(); spade.Push(waste.Top()); waste.Pop(); do_some=false; } else if(waste.Top().type=='H' && waste.Top().num==cardnum[heart.get_topindex()+1]){ print_pile(); heart.Push(waste.Top()); waste.Pop(); do_some=false; } else if(waste.Top().type=='D' && waste.Top().num==cardnum[diamond.get_topindex()+1]){ print_pile(); diamond.Push(waste.Top()); waste.Pop(); do_some=false; } else if(waste.Top().type=='C' && waste.Top().num==cardnum[clover.get_topindex()+1]){ print_pile(); clover.Push(waste.Top()); waste.Pop(); do_some=false; } for(int i=0;i<7;i++){ char temptype = playing[i].Top().type; if(playing[i].get_topindex()!=-1){ switch(temptype){ case 'S': { if(playing[i].Top().num==cardnum[spade.get_topindex()+1]){ print_pile(); spade.Push(playing[i].Top()); playing[i].Pop(); do_some=false; } else{ do_some=true; } break; } case 'H': { if(playing[i].Top().num==cardnum[heart.get_topindex()+1]){ print_pile(); heart.Push(playing[i].Top()); playing[i].Pop(); do_some=false; } else{ do_some=true; } break; } case 'D': { if(playing[i].Top().num==cardnum[diamond.get_topindex()+1]){ print_pile(); diamond.Push(playing[i].Top()); playing[i].Pop(); do_some=false; } else{ do_some=true; } break; } case 'C': { if(playing[i].Top().num==cardnum[clover.get_topindex()+1]){ print_pile(); clover.Push(playing[i].Top()); playing[i].Pop(); do_some=false; } else{ do_some=true; } break; } } } } print_pile(); } } int main(){ Solitaire solitaire; solitaire.card_init(); solitaire.playing_game(); return 0; }
약간 가독성이 떨어지긴 하지만, S, D, H, C는 Spade, Diamond, Heart, Clover를 나타낸다.
카드는 무늬마다 13장씩 총 52장이 있고 이 문제의 요구사항은 자동 Solitaire 프로그램을 만드는 것이었다.
Solitaire는 카드를 잘못놓기 시작하면 끝이 나지 않기 때문에 무한 loop를 돌고싶지 않아서 10번 정도만 loop를 돌도록 했다.
뭐...저건 숫자만 수정하면 고쳐질거니까 한 100번까진 돌려봤는데
별 다른 알고리즘 없이 맨 처음 나오는 카드를 바로 더미에 올려주는 거라 100번 돈다 해서 게임이 끝날 가능성은 거의 희박하다....ㅎㅎㅋㅋㅋㅋㅋ
결과화면도 약간 가독성이 떨어지는거 같기도 하네....하하
어쨌든 이와 같이 동작 가능하다. 헐 그리고 캡쳐엔 안나왔지만 playing 더미에 있는 카드들끼리도 겹치기 가능하다.
만약 코드를 손본다면
1. 자동으로 10턴 이런것 보다는 사용자 입력이 더 재밌을거 같다.
2. 결과 가독성 면에서도 떨어지는것 같아서 출력부분을 이쁘게 수정...하고싶다
3. 이왕 효율적이게 하려면 직접 구현한 stack보다는 STL이 낫겠지....
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Longest Common Subsequence
- 풀업 저항
- Solitaire 프로그래밍
- 아두이노 버튼 LED
- 다이나믹 프로그래밍
- 탐욕 알고리즘
- postgresql php
- 그리디
- 자동 Solitaire
- 멀티부팅
- 초대장나눔
- 아두이노 우노
- 아두이노
- 아두이노 LED
- postgresql SELECT
- 아두이노 외부 LED
- 풀다운 저항
- 욕심쟁이 알고리즘
- postgresql query
- POST
- Greedy Algorithm
- c++ Solitaire
- 아두이노 LED 회로
- 최장공통부분열
- LCS
- gnutls
- 아두이노 우노 버튼
- usb파티션
- 아두이노 LED 제어
- 그리디 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함