前两天帮同学做一个C++的作业 大致是这样的
设计一个21点的纸牌游戏 21点的游戏规则我就不做介绍了 先给人发牌 每发一次问一声还要不要 要是不要了给电脑发 电脑每次都跟人的点数比较 直到比人的点大或者撑死游戏结束 基本流程就是这样
我当时想了很久要怎么设计洗牌和发牌程序 嗯 对 是想了很久 我很弱的
当时我想的是先将52张牌定义成一个数组 至于牌本身定义个结构里面一个char个花色 一个int个牌数
但是纠结的是怎么发牌 他题目上说的是编一个洗牌程序一个随机发牌函数 但我想他喵的要是随机发牌随机两次一样的牌怎么办 于是纠结在这里不可自拔 最后想的法子是先洗牌 然后按顺序发
然后有了最初版的傻逼洗牌程序
void wash ( card sum[] ){
int i , j , color ;
card temp ;
srand(time(NULL));
for( i=0 ; i<52 ; i++ ){
color = int ( rand()%4+1 ) ;
sum[i].color = new char[10] ;
re : if( color == 1 ) sum[i].color = "红桃" ;
else if( color == 2 ) sum[i].color = "方片" ;
else if( color == 3 ) sum[i].color = "黑桃" ;
else sum[i].color = "梅花" ;
sum[i].num = int( rand()%13+1 ) ;
temp = sum[i] ;
for( j=0 ; j<i-1 ; j++ ){
if( temp.color == sum[j].color )
if( temp.num == sum[j].num ) goto re ;
}
}
}
不要吐槽我这个傻逼的goto语句是多么的麻烦QAQ
人家已经婶婶的知道错了
然后就是按顺序发牌了 基本满足的这个游戏的要求
然后 那个同学还有一个同学 写了一个很有趣的随机洗牌算法 我觉得很好
void shufflel()
{
for(int i=0;i<52;++i)
deck[i]=i+1;
for(int i=0;i<52;++i)
{
int j=0;
j=rand()%52;
int temp=0;
temp=deck[i];
deck[i]=deck[j];
deck[j]=temp;
}
return;
}
这个比我的高效多了 先按顺序来给牌定个序 然后将第 i 项和第 j 项交换 因为 j 是随机rand出来的 就满足了洗牌的条件
但是这个程序有一点问题 就是 i 与 j 没有相关性
j=rand()%52
这有一个问题 就是如果我们的RP太差 每个 j 随机出来的数都跟 i 一样就跪了
所以我把这句改成了这样
j=rang()%i
这样每个 j 必然跟 i 不一样 而且也满足随机的条件
最后我们都以为这个问题就这么圆满顺利的解决了
结果 事实证明 太年轻了= =
最后的答案给的是这样的
洗牌程序就是给52张牌定序 没随机
但他有个发牌程序
void provide_cards(float cards[4][13]){
srand(time(NULL));
type[0] = rand()%4;
type[1] = rand()%13;
while (cards[type[0]][type[1]] == 0) {
type[0]= rand()%4;
type[1] = rand()%13;}
}
注意到这个while
他在玩家阶段和电脑阶段加了一句
provide_cards(cards);
color = type[0];
number = type[1];
str_output += show_cards(color,number);
total[0] += cards[color][number];
cards[color][number] = 0;
最后一句= =
每次发完牌后直接将发出去的牌定义成0 下次发牌的时候只要card[type[0]][type[1]]==0 就跳 不发
怎么说呢 在看到这个的时候 我只想说我擦
感觉婶婶的被鄙视了= =
其实一开始就想的有问题 一开始不知道怎么销掉已发出去的牌 就把注意力转移到了随机牌上 利用顺序发随机牌组来绕过发重复牌这个问题 殊不知可以用个很小的办法就可以解决
好了 今天就写这么多