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
;
}