c语言程序设计扑克牌游戏?

c语言程序设计扑克牌游戏?,第1张

定义一个结构类型表示一张牌,结构包含3个成员,第一个成员char:取值2,3~K,A表示牌名字,第二个成员int:取值2~14表示牌真实大小。第三个成员:结构链表指针。

写一个初始化函数,定义52大小的结构数组,成员值初值分别和牌对应,遍历数组并将每个元素的链表指针依次指向下一个元素地址。这样得到一个初始链表。(相当于一盒新牌)

所有涉及随机数都用rand函数,洗牌分四份就是循环取随机数m=1~n,n是随循环自减,初值52,直到n变成0。每随一次循环就从初始链表中遍历取出对应第m个节点,并从初始链表中将这个节点断开(既前一个节点指针直接指向后一个节点指针)。每取13张就组成一个新的链表。这样获得4个新链表分别表示4个玩家。

最后出牌就是分别遍历自己的链表,利用循环取牌比较结构数值大小。(取出的牌要从链表断开和上面一样,你把取出节点写成独立函数就能反复使用)。

/* 计算24是流行的扑克游戏。其方法是任意取出4张牌,A J Q K 王牌 算 1,其它牌按点数计算,花色不计。

目标是通过加、减、乘、除和括号最终算出24。设计一个程序,输入4个数字(1~10),则列出所有可能计算

结果为24的方案。要求:

方案不能重复(加法乘法交换律等算不同方案)。

计算中局部可以为分数,结果为整数即可(如 3 3 7 7 算法: (3 + 3/7)*7)

如果没有找到方案输出:无解。

在某些可不用括号的地方不用括号(即去掉括号后等式的解不变)

待完善:

1)除数不能为零没考虑(不用考虑可正常运行)

*/

#include<stdio.h>

#include<malloc.h>

int zuheshu(float s[],int n)// 组合数的函数

float zuhe[4]={0}// 暂时存放组合

int sum=0// 用于计数

// 动态分配n个float变量的数组

float * fsz(int n)

{

return (float *)malloc(sizeof(float)*n)

}

int zuhefu()//符号组合

int yunsuan(float s[],char p[],int k0[],int k1[])// 算式组合

float qiujie(float suanshi[],int n)// 算式求解

int hefa(float suanshi[],int r)// 算式正确性检查

float jianjie(float suanshi[],int r)// 算式简洁性检查

int fuhe=0// 计数符合算式数

void main()

{

// 输入四个数

//float shu[4]={0}

//printf("请输入4个数字(1~10):\n")

//scanf("%f",&shu[0])

//scanf("%f",&shu[1])

//scanf("%f",&shu[2])

//scanf("%f",&shu[3])

//float shu[4]={1,2,3,4}

//printf("输入的4个数字依此是: %.0f %.0f %.0f %.0f\n",shu[0],shu[1],shu[2],shu[3])

//float s[4]={3,3,3,3},shu[4]={0}

//printf("请输入四个数(0-9):\n")

for(int i=0i<4i++)

{

scanf("%f",&s[i])

for(int j=ij>0j--)

{

if(s[j]<=s[j-1])

{

float s0=s[j-1]

s[j-1]=s[j]

s[j]=s0

}

}

}

printf("四个数是:")

for(i=0i<4i++)

{

printf("%.0f ",s[i])

}

printf("\n")

zuheshu(s,4)

printf("有%d个算式符合\n",fuhe)

}

// 组合数,并调用yunsuan

int zuheshu(float s[],int n)

{

if(n==1)

{

zuhe[4-n]=s[0]

zuhefu()

return 1

}

for(int i=0i<ni++)

{

if(i==0)

{

// 直接填入s[0],数组和候选数中去除该数,递归

zuhe[4-n]=s[i]

float *p=fsz(n-1)

int o=0

for(int k=0k<nk++)

{

if(k!=i)

p[o++]=s[k]

}

zuheshu(p,n-1)

free(p)

}

else if(s[i]!=s[i-1])

{

// 直接填入s[0],数组和候选数中去除该数,递归

zuhe[4-n]=s[i]

float *p=fsz(n-1)

int o=0

for(int k=0k<nk++)

{

if(k!=i)

p[o++]=s[k]

}

zuheshu(p,n-1)

free(p)

}

}

}

// 组合运算符号,并调用yunsuan

int zuhefu()

{

// 对 *** 作符'+','—','*','/'组合

char opter[4]={'+','-','*','/'}

for(int h=0h<4h++) // 第一个 *** 作符

{

for(int i=0i<4i++) // 第二个 *** 作符

{

for(int j=0j<4j++) // 第三个 *** 作符

{

char op[3]// 放置 *** 作符

op[0]=opter[h]

op[1]=opter[i]

op[2]=opter[j]

// 对括号组合

// 0 1 1 1 2 2 2 3

int khzh[8][3]={{0,0,0},{0,0,1},{0,1,0},{1,0,0},{0,1,1},{1,0,1},{1,1,0},{1,1,1}}// 正或反括号

for(int k=0k<=3k++)

{

switch(k)

{

case 0: // 有0个括号

{

yunsuan(zuhe,op,khzh[0],khzh[0])

}

break

case 1: // 有1个括号

{

for(int m=1m<=3m++) // 正括号

{

for(int n=1n<=3n++) //反括号

{//代码将算式组合,并判断正确性其中(括号)010和100为错误组合,010和010无错误组合,001和100为错误组合,

//同时100和001可视做无括号应过滤(即正括号后接 *** 作数, *** 作符,不能是 *** 作数,反括号)

//正确组合有六组

if((m==2&&n==3)||(m==1&&n==2)||(m==3&&n==1)||(m==1&&n==3))

continue

yunsuan(zuhe,op,khzh[m],khzh[n])

}

}

}

break

case 2: // 有2个括号

{

//代码将算式组合,并判断正确性其中(括号)*1*和1**为错误组合,**1和*1*为错误组合,

//应过滤(即正括号后接 *** 作数, *** 作符,不能是 *** 作数,反括号)同时出现1**和**1也应视为0**和**0

//正确括法只有一种即101和101

yunsuan(zuhe,op,khzh[5],khzh[5])

}

break

case 3: //有3个括号,不可能

//利用khzu[7]代码将算式组合,并判断正确性(不正确)

break

}

}

}

}

}

return 1

}

// 对s[]中的四个数按照p[]和k[]中的运算符进行组合并调用qiujie()函数运算判断结果是否为24

int yunsuan(float s[],char p[],int k0[],int k1[])

{

float suanshi0[13]={'0'}// 合成等式

int r=0// 等式的长度

// 组合等式

for(int q=0q<13q++)

{

switch(q)

{

case 0:

{

if(k0[0]==1)

suanshi0[r++]='('

}

break

case 1:

{

suanshi0[r++]=s[0]

}

break

case 2:

{

suanshi0[r++]=p[0]

}

break

case 3:

{

if(k0[1]==1)

suanshi0[r++]='('

}

break

case 4:

{

suanshi0[r++]=s[1]

}

break

case 5:

{

if(k1[0]==1)

suanshi0[r++]=')'

}

break

case 6:

{

suanshi0[r++]=p[1]

}

break

case 7:

{

if(k0[2]==1)

suanshi0[r++]='('

}

break

case 8:

{

suanshi0[r++]=s[2]

}

break

case 9:

{

if(k1[1]==1)

suanshi0[r++]=')'

}

break

case 10:

{

suanshi0[r++]=p[2]

}

break

case 11:

{

suanshi0[r++]=s[3]

}

break

case 12:

{

if(k1[2]==1)

suanshi0[r++]=')'

}

break

}

}

float * suanshi=fsz(r)// 动态空间申请

for(int i=0i<ri++)

{

suanshi[i]=suanshi0[i]

}

// 组合算式的正确性检查

float f=hefa(suanshi,r)

if(f==0)

{

return 0

}

// 组合算式的简洁性检查

f=jianjie(suanshi,r)

if(f==0)

{

return 0

}

// 调用函数求解结果为24则输出等式

float sum0=qiujie(suanshi,r)

if(sum0==24)

{

fuhe++

for(int t=0t<rt++)

{

if(suanshi[t]>10)

printf("%c",char(suanshi[t]))

else

printf("%0.0f",suanshi[t])

}

printf("=%0.0f\n",sum0)

}

free(suanshi)

return 1

}

// 算式正确性检查

int hefa(float suanshi[],int r)

{

float * p=&suanshi[0]// 为当前指针

float * q=&suanshi[1]// 为下一指针

int flag=1// 等式正确标记

while(1)

{

if(*p==40) // 判断是否为'('

{

if((*q>=0)&&(*q<=9))

{

p++

q++

}

else

{

flag=0

break

}

}

if((*p>=0)&&(*p<=9)) // 判断是否为数

{

if((p-suanshi)>=(r-1))

{

break

}

if(*q==')'||((*q>41)&&(*q<48))) // '+','-','*','/'在次范围内

{

p++

q++

}

else

{

flag=0

break

}

}

if(*p==41) // 判断是否为')'

{

if((p-suanshi)>=(r-1))

{

break

}

if((*q>41)&&(*q<48)) // '+','-','*','/'在次范围内

{

p++

q++

}

else

{

flag=0

break

}

}

if((*p>41)&&(*p<48)) // // 判断是否为符号

{

if(*q==40||((*q>=0)&&(*q<=9)))

{

p++

q++

}

else

{

flag=0

break

}

}

}

return flag

}

// 算式简洁性检查

float jianjie(float suanshi[],int r)

{

float re=1// 是否括号不影响算式求解

float *p=&re,*q=&re

int k=0// 括号数目

int k1=0// 运算符的个数

float r0=0// '('前的运算符优先级

float r2=1// 算式运算符优先级

float r1=0// ')'后的运算符优先级

int r3=0

for(int i=0i<ri++)

{

if(suanshi[i]=='(')

{

k++

if(*p!='('||k==1)

{

p=&suanshi[i]

if(i!=0)

{

if(*(p-1)=='+'||*(p-1)=='-')

{

r0=1

}

else if(*(p-1)=='*'||*(p-1)=='/')

{

r0=2

}

if(*(p-1)=='-')

{

r0+=100

}

else if(*(p-1)=='/')

{

r0+=1000

}

}

}

}

else if(suanshi[i]==')')

{

if(k--==1)

{

q=&suanshi[i]

if(i!=r-1)

{

if(*(q+1)=='+'||*(q+1)=='-')

{

r1=1

}

else if(*(q+1)=='*'||*(q+1)=='/')

{

r1=2

}

}

//递归

re=jianjie(p+1,q-p-1)// 返回括号内的优先级

if(int(r0/100)>=1) // 括号'('外出现减号或除号

{

if((int(r0/100))==1&&(int(re/100))==1) // 括号'('外出现减号,括号内出现+或-

{

continue

}

else if((int(r0/1000))==1&&(int(re/1000))==1) // 括号'('外出现除号,括号内出现*或/

{

continue

}

}

if(int(re/100)==1)

re-=100

if(int(re/1000)==1)

re-=1000

if(int(r0/100)==1)

r0-=100

else if(int(r0/1000)==1)

r0-=1000

if(re==0)

return 0

if(re>=r0&&re>=r1)

return 0

}

}

else if(k==0)

{

if(suanshi[i]=='+'||suanshi[i]=='-')

{

r2=((r2*k1)+1)/(++k1)

r3=r3/10+1

}

else if(suanshi[i]=='*'||suanshi[i]=='/')

{

r2=(r2*k1+2)/(++k1)

r3=r3%10+10

}

}

}

if(r3%10==1)

r2+=100

if(r3/10==1)

r2+=1000

return r2

}

// 调用函数求解结果为24则输出等式

float qiujie(float suanshi[],int n)

{

if(n==3)

{

float a=0

switch(char(suanshi[1]))

{

case '+':

return (suanshi[0]+suanshi[2])

case '-':

return (suanshi[0]-suanshi[2])

case '*':

return (suanshi[0]*suanshi[2])

case '/':

return (suanshi[0]/suanshi[2])

}

}

// 过滤掉括号项

float pq='0'

float * p=&pq// 指向算式的第一个正括号

float * q=&pq// 指向算式的与第一个正括号配对的反括号

int k=0

float suanshi1[7]={'0'}// 除去括号后的算式

int s=0// 用来记录suanshi1数组的长度

float sum=0// 算式的值

for(int m=0m<nm++)

{

if(suanshi[m]=='(')

{

k++

if((*p)!='(')

{

p=&suanshi[m]

}

continue

}

if(suanshi[m]==')')

{

if(k--==1)

{

q=&suanshi[m]

suanshi1[s++]=qiujie(p+1,q-p-1)

p=&pq

q=&pq

}

continue

}

if(k==0)

{

suanshi1[s++]=suanshi[m]

continue

}

}

if(s==3)

{

sum=qiujie(suanshi1,s)

}

else

{

p=&suanshi1[0]// 指向第一个数

q=&suanshi1[2]// 只想第二个数

for(m=0m<(s-1)/2m++)

{

switch(char(suanshi1[2*m+1]))

{

case '+':

if((s-1)/2!=1&&(suanshi1[2*(m+1)+1]=='*'||suanshi1[2*(m+1)+1]=='/'))

{

*q=qiujie(p+2,3)

int ws=&suanshi1[s-1]-&suanshi1[2*(m+1)]

for(int w=1w<=wsw++)

{

if(((q+w+2)-(q+ws))>0)

{

*(q+w)=-1

}

else

{

*(q+w)=*(q+w+2)

}

}

s=s-2

m--

}

else

{

if(m==0)

{

sum+=*p+*q

}

else

{

sum+=*q

}

p=p+2

q=q+2

}

break

case '-':

if((s-1)/2!=1&&(suanshi1[2*(m+1)+1]=='*'||suanshi1[2*(m+1)+1]=='/'))

{

*q=qiujie(p+2,3)

int ws=&suanshi1[s-1]-&suanshi1[2*(m+1)]

for(int w=1w<=wsw++)

{

if(((q+w+2)-(q+ws))>0)

{

*(q+w)=-1

}

else

{

*(q+w)=*(q+w+2)

}

}

s=s-2

m=-1

}

else

{

if(m==0)

sum+=*p-*q

else

sum-=*q

p=p+2

q=q+2

}

break

case '*':

if(m==0)

sum+=(*p)*(*q)

else

sum*=*q

p=p+2

q=q+2

break

case '/':

if(m==0)

{

sum+=(*p)/(*q)

}

else

{

sum/=*q

}

p=p+2

q=q+2

break

}

}

}

return sum

}

rank用来循环检查A-K的牌有没有,第一个while循环定位到第一张存在的牌,接着的for循环是检查连续的有几张存在的牌。这个张数如果正好等于一手牌的张数,那就是顺子。如果不是,比如34578,for得到的值只有3,只有顺子才是5


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11534997.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-16
下一篇 2023-05-16

发表评论

登录后才能评论

评论列表(0条)

保存