C++筆記 撲克牌問題2


題目

許多撲克牌遊戲都需要向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;

    }
}







你可能感興趣的文章

[FE102] 前端必備:JavaScript (下)

[FE102] 前端必備:JavaScript (下)

useRef ref callback

useRef ref callback

D33_ W4-NET101

D33_ W4-NET101






留言討論