微信公众号 
图码生活

每天发布有五花八门的文章,各种有趣的知识等,期待您的订阅与参与
电脑报 1992-2001 十年文章全集
电脑报 1992-2001 十年文章全集
包含从 1992 年 - 2001 年间,两万余篇期刊文章,查询最少输入两个字符
随便看看
读取中
读取中
标题请你编程——扑克牌游戏
栏目软件大世界
作者阮锡光
发布1997-01-01
  题目:编制一个小游戏,在屏幕上给出四张扑克牌,牌上显示由用户任意输入的点数(11.12.13.1分别用J.Q.K.A表示),将牌翻转,把纸牌的位置作若干次互换,屏幕上给出互换的顺序,在限定时间内请用户判定哪张牌的点数最大。
  下面先介绍中国纺织大学黄剑的程序中的一个函数:
  procedure swap-card(start-card,end-card:byte);
  {在这个展示换牌动画的过程中,选用切换显示页的方法,纸牌的移动速度和用户选的等级呈正比关系,并且纸牌的移动曲线为SIN函数曲线。}
  var i:integer;{循环变量}  
  x,{所要交换的两张纸牌的横坐标距离}  
  x1,y1:integer;  {当前将要画纸牌的坐标}  
  t,{SIN函数变量}
  omega,step:real; {omega为SIN函数参数,step为其变量每次的增量}
  page:integer;   {用page对2取模的值作为显示页号}
  frame-number:integer;   {动画的帧数,也可以看作动画的速度}
  delay-time:integer;   {每帧动画之间的延迟}
  begin x:=(end-card-start-card)*1{计算横坐标距离}
  frame-number:=11+(end-card-start-card)*2-2*(level div 10);
  if(frame-number mod 2)=0 then inc(frame-number);{帧数调整}
  delay-time:=(3-(x div 100))*5+10;
  omega:=pi/x;step:=x/frame-number;
  t:=0;page:=1;{初始化变量} 
  while (t<=x) do begin
  {动画循环}  
  setactivepage(page mod 2); {选择当前不可见页为活动页}
  cleardevice; 
  for i:=0 to 3 do   {画出不作交换的两纸牌} 
  if (i<>start-card) and (i<>end-card)  
  then place-card(i,1,down-side);  
  x1:=120+start-card*100+round(t);  
  y1:=130-round(80*sin(omega*t)); 
  draw-card(x1,y1,1,down-side);{画出由左向右移动的一张纸牌}
  x1:=120+end-card*100-round(t);  
  y1:=130+round(80*sin(omega*t)); 
  draw-card(x1,y1,1,down-side);{画出由右向左移动的一张纸牌}
  setvisualpage(page mod 2);{选择刚才输出动画的活动页为可见页}
  t:=t+step; inc(page);   {变量各自加上增量}
  delay(delay-time);end;end {视觉延迟}
  另外,宁夏张永强编制的程序很有特色,他设计的扑克牌不仅有点数,而且有花色,并有大小王,画面漂亮。如:
  梅花:
  fillellipse(xx,y+60,10*size,10);
  fillellipse(xx+8*size,y+75,10*size,10);
  fillellipse(xx-8*size,y+75,10*size,10);
  line(xx,y+75,xx-3*size,y+90);
  line(xx,y+75,xx+3*size,y+90);
  line(xx-3*size,y+90,xx+3*size,y+90);
  floodfill(xx,y+89,BLACK);
  黑桃:
  line(xx,y+50,xx+15*size,y+70);
  line(xx,y+50,xx-15*size,y+70);  
  fillellipse(xx+5*size,y+75,12*size,12);
  fillellipse(xx-5*size,y+75,12*size,12);
  line(xx,y+75,xx-3*size,y+100);
  line(xx,y+75,xx+3*size,y+100); 
  line(xx-3*size,y+100,xx+3*size,y+100);
  floodfill(xx,y+52,BLACK);
  floodfill(xx,y+99,BLACK);
  红桃和方片用同样方法也可实现,用
  settextstyle(TRIPLEX-FONT,0,4);
  outtextxy(xx-45*size,y+5,CARD-title[title])语句显示点数。将54张牌放入一个数组,使用者选择牌时,54张牌可随机显示,用户通过按回车选牌,限于版面,不能一一登出。下面另给出一个完整的程序,虽其结果不够理想,但比较简单,也能够达到要求。
  /*Turbo C 2.0*/
  #include <conio.h>
  #include <math.h>
  #include <stdio.h>
  #include <dos.h>
  #include <bios.h>
  #include <ctype.h>
  #include <stdlib.h>
  #include <time.h>
  static char s[11][15]={{"  "},
  {"  "},
  {"  "},
  {"  "},
  {"  "},
  {"  "},
  {"  "}};
  void cocp(int co) /*光标开关函数*/
  {union REGS regs;
  regs.h.ah=1;
  regs.h.ch=6;
  regs.h.cl=co;
  int86(0x10,&regs,&regs);}
  char inkey() /*键值读取函数*/
  {union REGS regs;
  regs.h.ah=0;
  int86(0x16,&regs,&regs);
  return(regs.h.al);}
  int timeinkey(int t) /*定时读取键值函数*/
  {union REGS regs;
  int i,j,m;
  for(t=9;t>0;t--)  
  {gotoxy(12,23);  
  printf("%d",t);  
  gotoxy(10,23);  
  for(j=1;j<10;j++)  
  {delay(500);  
  regs.h.ah=1;  
  int86(0x16,&regs,&regs);
  if ((regs.x.flags & 0x60)==0)  
  /*是否按键*/  
  {m=inkey();  
  if(m>48 && m<53)  
  {gotoxy(10,23);  
  m=m-48;  
  printf("%d  ",m);
  return(m);}}}}
  return(0); }
  void display(ldx,ldy,dx,dy,x,y)/*显示纸牌函数*/
  int ldx,ldy,dx,dy,x,y;
  {int i,j;
  for(i=0;i<dy;i++) 
  {gotoxy(x,y+i);
  for(j=0;j<dx;j++)  
  putchar(s[ldy+i][ldx+j]); }}
  void move(a,b)/*移动纸牌函数*/
  int a,b;
  {int ldx,ldy,dx,dy,x,y,i,m,n;
  m=(b-a)*15; /*未移动两纸牌之间距离*/
  for(i=13;i>2;i--)  
  {display(1,1,12,10,a*15,i);  
  display(1,1,12,10,b*15,i); }
  for(i=0;i<m;i++)
  {n=m-2*i-2; /*移动中那两个纸牌之间距离*/ 
  display(0,1,13,9,a*15+i,3); 
  if(abs(n)<12)/*两牌相遇时B牌显示范围调整*/  
  if(n>=0)  
  display(12-n,1,n+2,9,a*15+i+13,3);  
  else display(1,1,-n,9,b*15-i-1,3);  
  else display(1,1,13,9,b*15-i-1,3); }
  for(i=3;i<14;i++)  
  {display(1,0,12,10,a*15,i);  
  display(1,0,12,10,b*15,i); }}
  main()
  {int i,j,ka,kb,a[4];
  char m;
  clrscr();/*清屏*/
  cocp(0);/*消隐光标*/
  for(i=1;i<5;i++)  
  {display(1,1,12,9,i*15,14);  
  gotoxy(i*15+6,18);  
  putchar(' '); }
  gotoxy(1,23);
  cocp(7);/*显示光标*/
  printf("input(2-9,a,j,q,k)");
  for(i=0;i<4;i++)  
  {gotoxy(i*15+21,18);  
  m=inkey(1);  
  if (m>49 && m<58)  
  {a[i]=m-48;putchar(m);continue;}  
  if (m==' a'|| m=='A')  
  { a[i]=1;putchar(m);continue;}  
  if (m=='j' || m=='J')  
  {a[i]=11;putchar(m);continue;}  
  if (m==' q'|| m==' Q')
  {a[i]=12;putchar(m);continue;}  
  if (m=='k'|| m=='K')  
  {a[i]=13;putchar(m);continue;}  
  i--; }
  gotoxy(1,23);
  printf("   ");
  cocp(0);
  delay(1800);
  for(i=1;i<5;i++)
  {gotoxy(i*15+6,18);putchar(176);}/*盖牌*/
  randomize();
  for(i=1;i<11;i++)/*随机调换两只纸牌十次*/  
  {ka=random(4)+1;  
  kb=ka+random(3)+1;  
  if(kb>4){j=ka;ka=kb-4;kb=j;}  
  move(ka,kb); }
  gotoxy(1,23);
  cocp(7);
  printf("maxnaber:");
  j=timeinkey(9);
  if(j==0){clrscr();exit(0);}
  gotoxy(1,24);
  for(i=0;i<4;i++)  
  {if(a[j-1]<a[i])  
  {printf("NO");  
  exit(0);} }
  printf("YES");}