前三节:
第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
- #ifndef POKER_H_INCLUDED
- #define POKER_H_INCLUDED
-
- struct Poker
- {
- public:
- Poker();
-
- void Shuffle();
- bool Deal(int card[4]);
-
- private:
- int _cards[52];
- int _index;
- };
-
- #endif // POKER_H_INCLUDED
_cards[52]用来存放0~51的值,表示扑克牌。_index是发牌时需要的,表示当前发到第几张牌。
主要操作就两:一个洗牌,一个发牌。
poker.cpp
- #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
- #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, 请思考!
按任意键查看本轮答案.
(5*9+3)/2
当前牌为: 8, 7, 8, 13, 请思考!
按任意键查看本轮答案.
-------------------------------------------------------------------------------
如果您想与我交流,请点击如下链接成为我的好友:
http://student.csdn.net/invite.php?u=112600&c=f635b3cf130f350c