zoukankan      html  css  js  c++  java
  • 软工作业第五章第五题

    题目

    5.5下面将给出两个人玩的扑克牌游戏的一种玩法,试设计一个模拟程序,它的基本功能是:
    (1)发两手牌(利用随机数产生器)。
    (2)确定赢者和赢牌的类型。
    (3)模拟N次游戏,计算每种类型牌赢或平局的概率。要求用HIPO图描绘设计结果并且画出高层控制流程图。
    扑克牌游戏规则如下:
    (1)有两个人玩分别为A和B。
    (2)一副扑克牌有52张牌,4种花色(黑桃、红桃、梅花、方块),每种花色的牌的点数按升序排列有2,3,4,.........,10,J,Q,K,A等13种。
    (3)给每个人发三张牌,牌面向上,赢者立即可以确定。
    (4)最高等级的一手牌成为同花,即3张牌均为同一种花色,最大的同花是同一种花色的Q,K,A。
    (6)第三等级的牌是同点,即点数相同的三张牌,最大的同点是AAA。
    (7)第四等级的牌是对子,即3张牌中有两张点数相同,最大的对子是A,A,K。
    (8)第五等级的牌是杂牌,即除去上列4等之外的任何一手牌,最大的杂牌是不同花色的A.K,J。
    (9)若两个人的牌类型不同,则等级高者胜;若等级相同,则点数高者胜;若点数也相同,则为平局。
    View Code

    实现

    //对它进行编码 方便逻辑实现 1到52进行编号
    //按照1 2 3...J Q K 分
    //1-13黑桃 14-26红心 27-39梅花 40-52方块
    // 0    1      2      3

    //设一张牌的随机数编号是 x 则(x - 1)/13是他的花色 即分别是0 1 2 3
    //(x - 1) % 13 + 1是他的值
    //inf 表示这种等级中最大的等级

    再用题目要求 进行判断 

    对它的花色状态和值进行排序 判断起来比较方便

    容易忽略的地方主要是不能有相同的牌 我使用了位运算来实现 用bool数组也可以 

    总结

    位运算&写成了&&了= =

    写出了点奇奇怪股的部分 调了一下 因为没有OJ 自己手动生成数据一个个看对不对 花了20分钟....

    所有代码

    #include <stdio.h>
    #include <iostream>
    #include <ctime>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int cardnum = 52;
    const int si = 3, inf = 1e7;
    int a[si], b[si];
    
    void showcard(int x) {
        int cc = (x - 1 ) / 13;
        int vv = (x - 1 ) % 13 + 1;
        
        if (cc == 0) printf(" 黑桃");
        else if (cc == 1) printf(" 红心");
        else if (cc == 2) printf(" 梅花");
        else printf(" 方块");
        
        if (vv == 1) printf("A ");
        else if (vv == 11) printf("J ");
        else if (vv == 12) printf("Q ");
        else if (vv == 13) printf("K ");
        else printf("%d ", vv);
    }
    void generate() {
        //一副牌只有52张 且不能重复 用位运算 排除重复 速度很快
        ll sta = 0;//int只有32位 装不下52个牌 要用ll
        srand( (unsigned)time( NULL));
        for (int i = 0; i < si; i++) {
            do {
                a[i] = rand() % cardnum + 1;
            } while (sta >> a[i] & 1);//这里一开始错成了 &&
            sta |= 1 << a[i];
        }
        for (int i = 0; i < si; i++) {
            do {
                b[i] = rand() % cardnum + 1;
            } while (sta >> b[i] & 1);
            sta |= 1 << b[i];
        }
        //这样6个牌都是不重复的
    
        cout << endl << "a: "  ;
        for (int i = 0; i < si; i++) showcard(a[i]);
        cout << endl << "b: "  ;
        for (int i = 0; i < si; i++) showcard(b[i]);
        cout << endl;
    }
    void cal(int &g, int &v, int arr[]) {
        int color[si], val[si];//花色 值
        int sum = 0;
        for (int i = 0; i < si; i++)  {
            color[i] = (arr[i] - 1 ) / 13; //设一张牌的编号是 x 则(x - 1)/13是他的花色 即分别是0 1 2 3
            val[i] = (arr[i] - 1 ) % 13 + 1; //(x - 1) % 13  + 1是他的值
            sum += val[i];
        }
        sort(val, val + si);//排序方便比较
        sort(color, color + si);
        
        
        int fl = 1;//同花
        for (int i = 0; i < si - 1; i++)  if (color[i] != color[i + 1]) fl = 0;
        if (fl) {
            if (val[0] == 1 && val[1] == 12 && val[2] == 13) v = inf;
            else v = sum;
            g = 0;
            cout << "同花" << endl;
            return ;
        }
        fl = 1;//顺子 因为前面已经判断了 花色是不同的 所以不用判断了
        for (int i = 0; i < si - 1; i++)  if (val[i] + 1 != val[i + 1]) fl = 0;
        if (fl) {
      //这里 题目没说清楚 他说是花色不同的 A K Q 没说是全部都不同还是有一个和另外两个不同就行了
      //我理解成是有一个和另外两个不同就行了
            if (val[0] == 1 && val[1] == 12 && val[2] == 13) v = inf;
            else v = sum;
            g = 1;
            cout <<  "顺子" << endl;
            return ;
        }
        fl = 1;//同点
        for (int i = 0; i < si - 1; i++)  if (val[i] != val[i + 1]) fl = 0;
        if (fl) {
            if (sum == 3) v = inf;//小技巧 1 + 1 + 1 = 3; 3 必然是AAA
            else v = sum;
            g = 2;
            cout << "同点" << endl;
            return ;
        }
        fl = 0;//对子
        for (int i = 0; i < si - 1; i++)  if (val[i] == val[i + 1]) fl = 1;
        if (fl) {
            if (val[0] == 1 && val[1] == 1 && val[2] == 13) v = inf;
            else v = sum;
            g = 3;
            cout << "对子" << endl;
            return ;
        }
        
        //杂牌
        cout << "杂牌" << endl;
        if (val[0] == 1 && val[1] == 11 && val[2] == 13) v = inf;
        else v = sum;
        g = 4;
        return ;
    }
    int comparee() {//比较
        int ag, av, bg, bv;// a等级和点数 b的等级和点数
        cal(ag, av, a);//计算a b的等级和点数 0是最高 同花 最弱是4
        cal(bg, bv, b);
        
        printf("av %d,   bv %d
    
    ", av, bv);
    
        if (ag < bg)    return 1;
        if (ag > bg)    return -1;
        if (av > bv)    return 1;
        if (av < bv)    return -1;
        return 0;
    }
    int main() {
        //对它进行编码 方便逻辑实现
        //按照1 2 3...J Q K 分
        //1-13黑桃 14-26红心 27-39梅花 40-52方块
        // 0        1           2        3
        //设一张牌的编号是 x 则(x - 1)/13是他的花色 即分别是0 1 2 3
        //(x - 1) % 13  + 1是他的值
        //inf  表示这种等级中最大的等级
    
        generate();//生成随机数
        int s = comparee();//比较
    
        if (s > 0) printf("a win 
    ");
        if (s < 0) printf("b win 
    ");
        if (s == 0) printf("pingju 
    ");
        return 0;
    }
  • 相关阅读:
    智器SmartQ T7实体店试用体验
    BI笔记之SSAS库Process的几种方案
    PowerTip of the Day from powershell.com上周汇总(八)
    PowerTip of the Day2010071420100716 summary
    PowerTip of the Day from powershell.com上周汇总(十)
    PowerTip of the Day from powershell.com上周汇总(六)
    重新整理Cellset转Datatable
    自动加密web.config配置节批处理
    与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable
    在VS2003中以ClassLibrary工程的方式管理Web工程.
  • 原文地址:https://www.cnblogs.com/smatrchen/p/10785159.html
Copyright © 2011-2022 走看看