一个c++写的发牌程序
from:redguardtoo 的 Blog
可以显示一,二,三,四家的牌
主要是为了训练我的牌感(记牌的能力),对有志于赌博或者桥牌事业的同志可能还有点用
编译为bd.exe,使用方法输入"bd -h"看帮助
以下是源代码(处理命令行参数的代码参考了vim):
#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[i][ 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;
}
}
// 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] = i;
}
vector < int > h(dim);
h.assign(cards,cards + dim);
// 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 ;
}
#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[i][ 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;
}
}
// 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] = i;
}
vector < int > h(dim);
h.assign(cards,cards + dim);
// 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 ;
}