您的位置:首页 > 编程语言 > C语言/C++

一个c++写的发牌程序

2006-04-07 16:40 260 查看
可以显示一,二,三,四家的牌

主要是为了训练我的牌感(记牌的能力),对有志于***或者桥牌事业的同志可能还有点用

编译为bd.exe,使用方法输入"bd -h"看帮助

以下是源代码(处理命令行参数的代码参考了vim):

[code]
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;

#include <cstdlib>
#include <ctime>
#include <cctype>

static char program_name[]="bd";
#define THE_VERSION "0.1"

namespace info{
    enum { WEST=0,NORTH=1,EAST=2,SOUTH=3,};
};
static char* deno[]={"Spade","Heart","Diamond","Cotton",};
static char card_symbol[]="23456789TJQKA";

// p - pointer to argument
// idx - index in argument
// default value 
static int
get_number_arg(char* p,int def)
{
    if (isdigit(*p))
    {
    def = atoi(p);
    }
    return def;
}

static void
print_help()
{
    cout<<"Usage: "<<program_name<<" [OPTION]..."<<endl;
    cout<<"Bridge Dealer"<<endl;
    cout<<"Example: "<<program_name<<" -p4"<<endl;
    cout<<endl;
    cout<<" -p           number of players, value ranges from 1 to 4"<<endl;
    cout<<"              /""<<program_name<<"/" with NO option equals /""<<program_name<<" -p1/" "<<endl;
    cout<<" -n           number of deals, default /"1/""<<endl;
    cout<<" -v,--version print version information and exit"<<endl;
    cout<<" -h,--help    display this help and exit"<<endl;
    cout<<endl;
    exit(0);
}

static void
print_version()
{
    cout<<program_name<<" version "<<THE_VERSION<<endl;
    exit(0);
}

static void
dump_one_hand(vector<int>::iterator ori,int sps=0)
{
    vector<int>::iterator iter=ori;
    for(int i=0;i<sizeof(deno)/sizeof(deno[0]);i++)
    {
        for(int j=0;j<sps;j++) cout<<" ";
        cout<<deno[0]<<": ";
        for(;(iter!=ori+13) && (*iter)/13==i;iter++)
        {
            cout<<card_symbol[(*iter)%13]<<" ";
        }
        cout<<endl;
    }
}

static void
dump_two_hands(vector<int>::iterator o1, vector<int>::iterator o2,int sps=0)
{
    vector<int>::iterator iter1=o1;
    vector<int>::iterator iter2=o2;
    int j;
    int cnt;
    for(int i=0;i<sizeof(deno)/sizeof(deno[0]);i++)
    {
        cout<<deno[i][0]<<": ";
        cnt=2;
        for(;(iter1!=o1+13) && (*iter1)/13==i;iter1++)
        {
            cout<<card_symbol[(*iter1)%13]<<" ";
            cnt=cnt+2;
        }

        for(j=0;j<sps+sps-cnt;j++) cout<<" ";
        cout<<deno[i][0]<<": ";
        for(;(iter2!=o2+13) && (*iter2)/13==i;iter2++)
        {
            cout<<card_symbol[(*iter2)%13]<<" ";
        }
        cout<<endl;
    }
}
[i]//error message routines---------------begin
static char* bs_errors[]=
{
    "Unknown option",
#define BS_UNKNOWN_OPTION 0
    "Too many arguments",
#define BS_TOO_MANY_ARGS 1
    "Argument missing after",
#define BS_ARG_MISSING 2
    "Garbage after option",
#define BS_GARBAGE      3
    "Too many extra commands",
#define BS_EXTRA_CMD        4
    "Invalid argument for",
#define BS_INVALID_ARG      5
};
//error message routines---------------end

int
main(int argc, char** argv)
{
    int argv_idx = 1;       /* active option letter is argv[0][argv_idx] */
    int players=1;
    int number_of_deals=1;
    bool want_argument=false;

    while(argc>0)
    {
        if(argv[0][0]=='-')
        {
            char c=argv[0][argv_idx++];
            switch(c)
            {
            case 0:
                //do nothing
                argv_idx=-1;
                break;
            case '-': // "--" don't take any more options
                if(strcmp(argv[0]+argv_idx,"version")==0){
                    print_version();
                }
                else if(strcmp(argv[0]+argv_idx,"help")==0){
                    print_help();
                }
                argv_idx=-1;
                break;
            case 'h':
                print_help();
                break;
            case 'v':
                print_version();
                break;
            case 'p': // 1,2,3,4 players, default 1
                if (argv[0][argv_idx]){ // "-p{tag}"
                    players=get_number_arg(argv[0]+argv_idx,1);
                    argv_idx=-1;
                }
                else{ // "-p {tag}"
                    want_argument=true;
                }
                break;
            case 'n': //number of deals, default 1
                if (argv[0][argv_idx]){ // "-n{tag}"
                    number_of_deals=get_number_arg(argv[0]+argv_idx,1);
                    if(number_of_deals<=0) number_of_deals=1;
                    argv_idx=-1;
                }
                else{ // "-n {tag}"
                    want_argument=true;
                }
                break;
            default:
                break;
            }

            //handle options with argument
            if(want_argument)
            {
                if (argv[0][argv_idx]){
                    cerr<<bs_errors[BS_GARBAGE]<<": /""<<argv[0]<<"/""<<endl;
                    exit(1);
                }

                --argc;
                if (argc<1){
                    cerr<<bs_errors[BS_ARG_MISSING]<<": /""<<argv[0]<<"/""<<endl;
                    exit(1);
                }
                ++argv;
                argv_idx = -1;

                switch(c)
                {
                case 'p':
                    players=get_number_arg(argv[0],1);
                    argv_idx=-1;
                    break;
                case 'n':
                    number_of_deals=get_number_arg(argv[0],1);
                    if(number_of_deals<=0) number_of_deals=1;
                    argv_idx=-1;
                    break;
                default:
                    ; //impossible
                }
            }

        }
        else{
            argv_idx=-1;//do nothing
        }
        // If there are no more letters after the current "-", go to next
        // argument.  argv_idx is set to -1 when the current argument is to be
        // skipped.
        if (argv_idx <= 0 || argv[0][argv_idx] == 0)
        {
            --argc;
            ++argv;
            argv_idx = 1;
        }
    }
    //init
    srand(time(0));

    //original card
    //value: spade, 0-12; heart, 13-25; diamond 26-38; cotton 39-51;
    //array index: west, 0-12; north, 13-25; east 26-38; south 39-51;
    const int dim=52;
    int cards[dim];

    for(int i=0;i<dim;i++)
    {
        cards=i;
    }
    vector<int> h(dim);
    h.assign(cards,cards+dim);

    [i]//redeal
    bool need_id=number_of_deals>1;
    for(int k=0;k<number_of_deals;k++)
    {
        random_shuffle(h.begin(),h.end());
        sort(h.begin()+info::WEST*13,h.begin()+info::WEST*13+13);
        sort(h.begin()+info::NORTH*13,h.begin()+info::NORTH*13+13);
        sort(h.begin()+info::EAST*13,h.begin()+info::EAST*13+13);
        sort(h.begin()+info::SOUTH*13,h.begin()+info::SOUTH*13+13);

        //dump
        if(need_id){
            cout<<"ID: "<<k+1<<endl;
        }
        switch(players)
        {
        case 1:
            dump_one_hand(h.begin()+info::SOUTH*13);
            break;
        case 2:
            dump_two_hands(h.begin()+info::EAST*13,h.begin()+info::WEST*13,26);
            break;
        case 3:
            dump_one_hand(h.begin()+info::NORTH*13,26);
            dump_one_hand(h.begin()+info::EAST*13);
            dump_one_hand(h.begin()+info::SOUTH*13,26);
            break;
        case 4:
            dump_one_hand(h.begin()+info::NORTH*13,26);
            dump_two_hands(h.begin()+info::EAST*13,h.begin()+info::WEST*13,26);
            dump_one_hand(h.begin()+info::SOUTH*13,26);
            break;
        default:
            ;//impossible
        }
        cout<<endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: