題目
許多撲克牌遊戲都需要向4位玩家發牌,發完牌後每個人會有13張牌。有的玩家可以不整牌直接玩,但是大多數玩家都需要整牌。整牌首先按花色排序,花色順序為:
C = Clubs♣ < D = Diamonds♢ < S = Spades♠ < H = Hearts♡
再來按照點數大小排序,點數順序為:
2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < K < A
玩家的座位分為北N,東E,南S,西W。其中一位玩家將被指定為發牌人,他向每個玩家分發一張牌,從左手邊的玩家開始,然後順時針進行發牌。請你寫一個程式,該程式將讀取一副撲克牌的順序,並將其發給4位玩家,最後根據最後一行指令輸出對應格式的檔案。
圖一、方位圖
詳細說明如下:
(1) 程式要求:
A. 教過的函式庫皆可用,基本上 iostream、vector、map、fstream這四個就夠用了,另外map如果需要歷遍,請避免使用auto。
B. 請讀取input.txt中的資料
C. 依照input.txt最後給出的數字執行相對應的功能,並將之輸出於”output.txt”
D. 相對應的功能為:
功能1:第四行的數字是"1",將持有梅花三(C3)的玩家輸出於"output.txt "並結束程式(最後一行需換行)。
功能2:第四行的數字是"2",將四位玩家發完牌之後"未整理牌"的狀態輸出於"output.txt "並結束程式(最後一行需換行)。
功能3:第四行的數字是"3",將四位玩家發完牌之後"整理好牌"的狀態輸出於"output.txt "並結束程式(最後一行需換行)。
E. 請使用Function sort_card(string *pointer)做整理牌的動作,該function傳入一個pointer,沒有使用該Function成績打八折,Function的名稱以及回傳值不能改,參數只能為”一個”pointer,pointer的型態以及名稱隨意。
void sort_card(string *p_card)
F. 請使用Function”show_card()”將每位玩家手上的牌輸出於”output.txt”,該function傳入一個pointer,沒有使用該Function成績打八折,Function的名稱以及回傳值不能改,參數只能為”一個”pointer,pointer的型態以及名稱隨意。
void show_card(string *p_card)
G. 請使用區域變數 string card[4][13] 來儲存每位玩家的手牌,整理手牌以及顯示手牌時只能傳入該變數記憶體位置,並使用pointer去做整理以及讀寫等動作。
int main(){
string card[4][13]
sort_card(&card[0][0]);
show_card(&card[0][0]);
}
(2) 資料解說
"input.txt"的第一行為一個字元(N,E,S,W),代表發牌人坐的方位。
接下來二行為一副撲克牌順序,每行26張牌,每張牌中間使用空白做間隔。
第四行為一個數字(1、2、3)
(3) 輸出格式:
功能1請輸出一個字元代表拿到梅花三的玩家並換行。
功能2和功能3輸出皆為四行。分別代表4位玩家的手牌,每張手牌請用空白分隔(每位玩家最後一張牌後面接換行而非空白),輸出玩家順序為(S、W、N、E),最後一行要換行。
例一:
input.txt自此始,但不包括此行
S
CQ DT C4 D8 S7 HT DA H7 D2 S3 D6 C6 S6 D9 S4 SA D7 H2 CK H5 D3 CT S8 C9 H3 C3
DQ S9 SQ DJ H8 HA S2 SK D4 H4 S5 C7 SJ C8 DK C5 C2 CA HQ CJ ST H6 HK H9 D5 HJ
1
input.txt至此止,但不包括此comment
output.txt自此始,但不包括此行
N
output.txt至此止,但不包括此comment
例二:
input.txt自此始,但不包括此行
S
CQ DT C4 D8 S7 HT DA H7 D2 S3 D6 C6 S6 D9 S4 SA D7 H2 CK H5 D3 CT S8 C9 H3 C3
DQ S9 SQ DJ H8 HA S2 SK D4 H4 S5 C7 SJ C8 DK C5 C2 CA HQ CJ ST H6 HK H9 D5 HJ
2
input.txt至此止,但不包括此comment
output.txt自此始,但不包括此行
S: D8 H7 C6 SA H5 C9 S9 HA H4 C8 CA H6 HJ
W: CQ S7 D2 S6 D7 D3 H3 SQ S2 S5 DK HQ HK
N: DT HT S3 D9 H2 CT C3 DJ SK C7 C5 CJ H9
E: C4 DA D6 S4 CK S8 DQ H8 D4 SJ C2 ST D5
output.txt至此止,但不包括此comment
例三:
input.txt自此始,但不包括此行
S
CQ DT C4 D8 S7 HT DA H7 D2 S3 D6 C6 S6 D9 S4 SA D7 H2 CK H5 D3 CT S8 C9 H3 C3
DQ S9 SQ DJ H8 HA S2 SK D4 H4 S5 C7 SJ C8 DK C5 C2 CA HQ CJ ST H6 HK H9 D5 HJ
3
input.txt至此止,但不包括此comment
output.txt自此始,但不包括此行
S: C6 C8 C9 CA D8 S9 SA H4 H5 H6 H7 HJ HA
W: CQ D2 D3 D7 DK S2 S5 S6 S7 SQ H3 HQ HK
N: C3 C5 C7 CT CJ D9 DT DJ S3 SK H2 H9 HT
E: C2 C4 CK D4 D5 D6 DQ DA S4 S8 ST SJ H8
完整程式碼
#include<iostream>
#include<fstream>
#include<string>
#include <string.h>
#include <sstream>
#include<vector>
using namespace std;
vector<string> split(const string &s, char delimiter) {
vector<string> tokens;
string token;
istringstream tokenStream(s);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
void show_card(string *p_card){
ofstream outputer;
outputer.open("output.txt");
//無法寫入的處理程序
if (!outputer.is_open()) {
cout << "Failed to open file.\n";
}
//可以寫入的程序處理
int cardOrder=0;
for(int i=0;i<4;i++){
switch(i){
case 0 :
outputer << "S: ";
break;
case 1 :
outputer << "W: ";
break;
case 2 :
outputer << "N: ";
break;
case 3 :
outputer << "E: ";
break;
default:
break;
}
for(int j=0;j<13;j++){
outputer << *(p_card+i*13+j) <<' ';
}
outputer << '\n';
}
outputer.close();
}
int getnumber(char number){
switch(number){
case '2': return 1;
case '3': return 2;
case '4' :return 3;
case '5' :return 4;
case '6' :return 5;
case '7' :return 6;
case '8' :return 7;
case '9' :return 8;
case 'T' :return 9;
case 'J' :return 10;
case 'Q' :return 11;
case 'K' :return 12;
case 'A' :return 13;
default : break;
}
}
//比較花色順位
int getcolor (char color){
if(color=='C') return 1;
else if(color=='D') return 2;
else if(color=='S') return 3;
else if(color=='H') return 4;
else return 0;
}
void sort_card(string *p_card){
for(int i=0;i<4;i++){
for(int j=0;j<12;j++){
for(int k=0;k<12-j;k++){
//card1
string card1 = *(p_card+i*13+k);
int color1 = getcolor(card1[0]);
int number1 = getnumber(card1[1]);
//card2
string card2 = *(p_card+i*13+k+1);
int color2 = getcolor(card2[0]);
int number2 = getnumber(card2[1]);
// card[i][k] card[i][k+1]比較
if(color1 > color2){
string temp = *(p_card+i*13+k);
*(p_card+i*13+k) = *(p_card+i*13+k+1);
*(p_card+i*13+k+1) = temp;
}
else{
if(color1 == color2 && number1 > number2){
string temp = *(p_card+i*13+k);
*(p_card+i*13+k) = *(p_card+i*13+k+1);
*(p_card+i*13+k+1) = temp;
}
}
}
}
}
}
int main(){
//1. 初始要使用到的變數
//發牌順序
string direction[] = {"S","W","N","E"};
//發牌者
char licenser;
//指令 (1、2、3)
char cmd;
//所有卡片
vector<string> Allcards;
//每個人持有的卡片
vector<string> S_hold;
vector<string> W_hold;
vector<string> N_hold;
vector<string> E_hold;
//2.讀檔知道 start、cards
ifstream reader;
reader.open("input.txt",ios::binary);
string line;
int isLicenser = 1;
while(getline(reader,line)){
vector<string> cards = split(line, ' ');
//判斷line是start還是卡片內容
if(cards.size()==1){
//判斷是讀入第一行或是第四行
if(isLicenser==1){
licenser=line[0];
isLicenser=0;
}
else cmd=line[0];
}
else{
for(int i=0;i<cards.size();i++){
//去除可能有的\n (e.g. "C3+\n")
string c = cards[i].substr(0,2);
Allcards.push_back(c);
}
}
}
reader.close();
//3.依據cards,direction內容完成四個人的持有卡片
//知道licenser在direction array中的index (發牌的起始方位)
int start;
switch(licenser){
case 'S':
start = 0;
break;
case 'W':
start = 1;
break;
case 'N':
start = 2;
break;
case 'E':
start = 3;
break;
default:
break;
}
for(int i=0;i<Allcards.size();i++){
//拿牌的人在direction array中的index
int getCard = (start+1+i)%4;
switch(getCard){
case 0:
S_hold.push_back(Allcards[i]);
break;
case 1:
W_hold.push_back(Allcards[i]);
break;
case 2:
N_hold.push_back(Allcards[i]);
break;
case 3:
E_hold.push_back(Allcards[i]);
break;
default:
break;
}
}
//4.將vector結果寫進二維陣列
string card[4][13];
for(int i=0;i<13;i++){
card[0][i] = S_hold[i];
card[1][i] = W_hold[i];
card[2][i] = N_hold[i];
card[3][i] = E_hold[i];
}
//5.處理cmd的功能
ofstream outputer;
outputer.open("output.txt");
switch(cmd){
case '1':
int c3Holder;
for(int i=0;i<4;i++){
for(int j=0;j<13;j++){
if(card[i][j].compare("C3") == 0) {
c3Holder = i;
break;
}
}
}
outputer << direction[c3Holder] << '\n';
break;
case '2':
show_card(&card[0][0]);
break;
case '3':
sort_card(&card[0][0]);
show_card(&card[0][0]);
break;
default:
break;
}
outputer.close();
}
解題觀念及思路
基本上跟上一題一樣的就不提了
讀取S_hold、W_hold等來存成二微陣列型態
string card[4][13];
for(int i=0;i<13;i++){
card[0][i] = S_hold[i];
card[1][i] = W_hold[i];
card[2][i] = N_hold[i];
card[3][i] = E_hold[i];
}
處理新的第四行功能
ofstream outputer;
outputer.open("output.txt");
switch(cmd){
case '1':
int c3Holder;
for(int i=0;i<4;i++){
for(int j=0;j<13;j++){
if(card[i][j].compare("C3") == 0) {
c3Holder = i;
break;
}
}
}
outputer << direction[c3Holder] << '\n';
break;
case '2':
show_card(&card[0][0]);
break;
case '3':
sort_card(&card[0][0]);
show_card(&card[0][0]);
break;
default:
break;
}
outputer.close();
cmd = 1:
case '1':
int c3Holder;
for(int i=0;i<4;i++){
for(int j=0;j<13;j++){
if(card[i][j].compare("C3") == 0) {
c3Holder = i;
break;
}
}
}
outputer << direction[c3Holder] << '\n';
break;
cmd = 2 :
case '2':
show_card(&card[0][0]);
break;
void show_card(string *p_card){
ofstream outputer;
outputer.open("output.txt");
//無法寫入的處理程序
if (!outputer.is_open()) {
cout << "Failed to open file.\n";
}
//可以寫入的程序處理
int cardOrder=0;
for(int i=0;i<4;i++){
switch(i){
case 0 :
outputer << "S: ";
break;
case 1 :
outputer << "W: ";
break;
case 2 :
outputer << "N: ";
break;
case 3 :
outputer << "E: ";
break;
default:
break;
}
for(int j=0;j<13;j++){
outputer << *(p_card+i*13+j) <<' ';
}
outputer << '\n';
}
outputer.close();
}
cmd = 3:
case '3':
sort_card(&card[0][0]);
show_card(&card[0][0]);
break;
主要是使用bubble sort進行排序
分別先用花色 同花色再用數字進行排序
void sort_card(string *p_card){
for(int i=0;i<4;i++){
for(int j=0;j<12;j++){
for(int k=0;k<12-j;k++){
//card1
string card1 = *(p_card+i*13+k);
int color1 = getcolor(card1[0]);
int number1 = getnumber(card1[1]);
//card2
string card2 = *(p_card+i*13+k+1);
int color2 = getcolor(card2[0]);
int number2 = getnumber(card2[1]);
// card[i][k] card[i][k+1]比較
if(color1 > color2){
string temp = *(p_card+i*13+k);
*(p_card+i*13+k) = *(p_card+i*13+k+1);
*(p_card+i*13+k+1) = temp;
}
else{
if(color1 == color2 && number1 > number2){
string temp = *(p_card+i*13+k);
*(p_card+i*13+k) = *(p_card+i*13+k+1);
*(p_card+i*13+k+1) = temp;
}
}
}
}
}
int getcolor (char color){
if(color=='C') return 1;
else if(color=='D') return 2;
else if(color=='S') return 3;
else if(color=='H') return 4;
else return 0;
}
int getnumber(char number){
switch(number){
case '2': return 1;
case '3': return 2;
case '4' :return 3;
case '5' :return 4;
case '6' :return 5;
case '7' :return 6;
case '8' :return 7;
case '9' :return 8;
case 'T' :return 9;
case 'J' :return 10;
case 'Q' :return 11;
case 'K' :return 12;
case 'A' :return 13;
default : break;
}
}