您的位置:首页 > 其它

24点游戏7节课--第4节-引入扑克牌发牌出数

2010-07-02 13:29 357 查看
前三节:

 

第1节-游戏介绍与基本算法   http://student.csdn.net/space.php?uid=112600&do=blog&id=34066

第2节-24点计算处理 http://student.csdn.net/space.php?uid=112600&do=blog&id=34327

第3节-格式化结果表达式 http://student.csdn.net/space.php?uid=112600&do=blog&id=35873

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

第4节-引入扑克牌发牌出数



 24点游戏中,扑克只是用作提供数值的道具,其中花色用不上,大小鬼也不需要。数值限在1~13范围内。

我们用一个int数组来表达52张牌。内部存值为0~51. 要转成牌值时,公式是: N % 13 + 1。 %是求余数操作符。

比如 :0 -> 0 %13 + 1 = 1。所以在程序中,0表示牌值为1的牌。0 除以 13,余数是0,这个是小学算术。

再如: 2 -> 2 % 13 + 1 = 3。所以2表示牌值为3的牌。

再如: 15-> 15 % 13 + 1 = 3。 所15也表示牌值是3的牌。(只是花色不同,花色可以用N/13表示,但在此无意义)

 

有这些知识,就可以写扑克牌的类了,新建poker.h 和 poer.cpp加入项目。

poker.h 

Code:

#ifndef POKER_H_INCLUDED  

#define POKER_H_INCLUDED  

  

struct Poker  

{  

public:  

    Poker();  

      

    void Shuffle(); //洗牌  

    bool Deal(int card[4]); //发牌,如果不够4张,返回false  

      

private:  

    int _cards[52];  

    int _index;  

};  

 

#endif // POKER_H_INCLUDED  

_cards[52]用来存放0~51的值,表示扑克牌。_index是发牌时需要的,表示当前发到第几张牌。

主要操作就两:一个洗牌,一个发牌。

poker.cpp

Code:

#include "poker.h"  

 

#include <cstdlib>  

#include <ctime>  

#include <iostream>  

  

using namespace std;  

  

Poker::Poker()  

    : _index(0)  

{  

    for (int i=0; i<52; _cards[i] = i, ++i);  

}  

  

void Poker::Shuffle() //洗牌  

{  

    _index = 0;  

    srand(time(0));  

 

    #define SIMPLE_SWAP_int(a,b) do {int t = a; a=b; b=t;} while(0)  

       

    for (int i=52, c=1; i>0; --i,++c)  

    {  

        int ri = rand() % i;  

        SIMPLE_SWAP_int(_cards[52-c], _cards[ri]);  

    }  

}  

  

bool Poker::Deal(int card[4]) //发牌  

{  

    if (_index + 4 > 52)  

        return false;  

          

    for (int i=0; i<4; ++i, ++_index)  

    {  

        card[i] = _cards[_index];  

    }  

      

    return true;  

}  

构造函数中,让牌值是顺的,其实是为了确保_pokers[]里放的都是正确的值。

洗牌算法很简单 ,简单说下:

step1 :从前面51张牌中,随机取一张,和第52张牌交换。

step2: 从前面50张牌中,再随机取一张,和第51张牌交换。

重复,即:从前面1~N牌中,随机取出一张,和第N+1张牌交换。直到第1张。

 

发牌就没有什么算法了:从第_index张开始,取出4张。同时_index前进4。

接下来我们改改一main函数。

main.cpp

Code:

#include <iostream>  

#include <sstream> //for stringstream  

 

#include "calc_24.h"  

#include "exp_getter.h"  

 

#include "poker.h"  

  

using namespace std;  

  

int main()  

{         

    int num[4];  

      

    Poker poker;  

    poker.Shuffle();  

      

    while(poker.Deal(num))  

    {  

        cout << "/n当前牌为: ";  

          

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

        {  

            num[i] = num[i] % 13 +1;  

            cout << num[i] << ", ";              

        }  

              

        cout << "请思考!" << std::endl;  

        cout << "按任意键查看本轮答案." << std::endl;  

        cin.get();  

              

        if (!calc_24(num))  

        {  

            cout << "查无答案" << endl;  

        }  

    }  

      

    return 0;  

}  

它会先出4个数,然后等待我们按下任意键,后给出答案,在此期间,我们可以思考那4个数如何计算成24了。还不能接受我们录入答案(并判断正误),更没有提供人机对抗……那是后两节课的内容了。

不管怎样,它看起还是挺智能的,我们完全可以拿来复习及锻炼一下小学所学的四则运算能力了……嗯,我这就叫来我女儿,然后出题让她想。

这是运行中的一个输出示例:

 

当前牌为: 12, 6, 1, 13, 请思考!

按任意键查看本轮答案.



(13-1)*12/6

当前牌为: 5, 3, 9, 2, 请思考!

按任[b]意键查看本轮答案.[/b]

(5*9+3)/2

当前牌为: 8, 7, 8, 13, 请思考!

按任[b]意键查看本轮答案.[/b]

-------------------------------------------------------------------------------

 如果您想与我交流,请点击如下链接成为我的好友:
 
http://student.csdn.net/invite.php?u=112600&c=f635b3cf130f350c
 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 算法 c