斗地主
1、完成一个控制台程序
知识点:
srand(time(NULL)):这是两个函数,一个是srand函数,这是在调用rand()这个函数之前使用的,rand()是一个产生随机数的函数,而srand是一个设置随机数种子的函数,通常这两个函数是一起使用的,来完成产生随机数的功能。
而time(NULL)这个函数的返回值是作为srand函数的参数的,意思是以现在的系统时间作为随机数的种子来产生随机数,至于NULL这个参数,因为这个话就返回到现在时间时候的long秒,只有设置成NULL才能获得系统的时间。
斗地主发牌规则:
一副牌有54张,大小王各一张,牌分为黑桃、梅花、红桃、方块四种,1~10各4张共40张,JQK各四张共12张。
一共54张扑克牌,玩家抽完牌后剩余3张底牌。题目要求将54张牌发给三个玩家,并给每个玩家手中的扑克牌进行排序。
扑克牌大小顺序(从左往右依次递增):"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2",“小王”,“大王”。
每个人17张牌,共51张,加3张底牌 54张。
定义数组存储牌的花色
string hs[4]={"黑桃","桃心","梅花","方块"};
定义数组来存储数字
string number[13]={"3","4","5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
定义数组来给number里面的牌面赋予数值大小
int numer[13]={3,4,5,6,7,8,9,10,11,12,13,14,15};
定义数组来存储组后后的牌
string numbr[54];
一、制作扑克牌
采用for循环,来进行组合
//制作扑克牌
void Poker::combination(string *hs, string *number, string *numbr, int *numer,int *sum)
{
int k = 0;
int num = 0;
for (int i = 0; i < 13; i++) {
for (int j = 0; j < 4; j++) {
string temp = hs[j] + number[i]; //将花色和数字组合
num++;
numbr[k] = temp; //牌面
sum[k] = numer[i]; //牌面数值
k++;
}
}
//添加 大王、小王
string tmp1 = "大王";
numbr[k] = tmp1; //存储牌面
sum[k] = 16; //添加牌面数值大小
num++;
k++;
string tmp2 = "小王";
numbr[k] = tmp2;
sum[k] = 17;
num++;
}
二、三名玩家和底牌
用数组定义三名玩家和底牌a
string a[18],b[18],c[18],d[4];
定义每位玩家和底牌的牌面数值
int num1[18],num2[18],num3[18],num4[4];
函数打乱扑克牌顺序
//随机打乱扑克牌数组顺序
void Poker::random(string s[], int *a, int n)
{
int index, p;
string tmp;
srand(time(NULL));
for (int i = 0; i < n; i++) {
index = rand() % (n - i) + i;
if (index != i) {
//交换字符顺序
tmp = s[i];
s[i] = s[index];
s[index] = tmp;
//交换数字顺序
p = a[i];
a[i] = a[index];
a[index] = p;
}
}
}
三、发牌
一共三个玩家,按每个玩家每人每次摸3张牌的顺序发牌,最后每人手里都有17张牌。最后剩余3张底牌。
//发牌//
void Poker::sendPoker(string *numbr, int *sum, string *a, string *b, string *c,string *d, int *num1, int *num2, int *num3,int *num4)
{
int i = 0, x = 0, y = 0, z = 0;
for (int l = 0; l < 54; l++) {
if (l >= 51) { //最后剩余3张底牌
d[i] = numbr[l];
num4[i] = sum[l];
i++;
}
else { //i对3取模,对应3个玩家抽牌
if (l % 3 == 0) {
a[x] = numbr[l];
num1[x] = sum[l];
x++;
}
else if (l % 3 == 1) {
b[y] = numbr[l];
num2[y] = sum[l];
y++;
}
else if (l % 3 == 2) {
c[z] = numbr[l];
num3[z] = sum[l];
z++;
}
}
}
}
四、输出三位玩家的牌和底牌
1、给发到的牌进行排序,三个人的牌需要由牌的大小由大到小排序;
//扑克牌排序
void Poker::card(string s[], int a[], int n) {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] < a[j]) {
//交换牌面数字
int temp = a[i];
a[i] = a[j];
a[j] = temp;
//交换牌面字符
string str = s[i];
s[i] = s[j];
s[j] = str;
}
}
}
}
输出发到的牌
//输出牌
void Poker::output(string s[], int a[], int n)
{
card(s, a, n);
for (int i = 0; i < n; i++) {
cout << s[i] << " ";
}
cout << endl;
}
主函数的测试代码:
#include<iostream>
using namespace std;
#include<string>
#include "Poker.h"
string hs[4] = { "黑桃", "桃心", "梅花", "方块" };
string number[13] = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
int numer[13] = { 3,4,5,6,7,8,9,10,11,12,13,14,15 }; //对应number里面的每个牌面的数值大小
string numbr[54]; //存储组合后的牌
int main()
{
int sum[54]; //存储牌面数值
Poker p;
int l=0;
p.combination(hs,number,numbr,numer,sum);// 做扑克牌
p.random(numbr, sum, 54); //调用函数打乱扑克牌顺序
string a[18], b[18], c[18], d[4]; //玩家a b c 和底牌
int num1[18], num2[18], num3[18], num4[4]; //每一个玩家和底牌的牌面数值
p.sendPoker(numbr,sum,a,b,c,d,num1,num2,num3,num4);
cout << "玩家a:";
p.output(a, num1, 17);
cout << "玩家b:";
p.output(b, num2, 17);
cout << "玩家c:";
p.output(c, num3, 17);
cout << "底牌:";
p.output(d, num4, 3);
return 0;
}
心得:本次作业可能对于参数的定义,太过冗余了,定义了很多,导致传的参数很多,原本打算把参数定义到类里面的,后来发现感觉,想试试在外面定义看看会不会复杂,感觉也还可以。整套作业下来,难点在于如何去制作又有花色又有数字的牌,如何随机的从54张牌中任意发,然后就是如何去排序,以及如何去赋给四个数组,这四个方面比较具有挑战性。原本代码是在一个文件的,后来拆成三个文件了,感觉有点多余了,不过逻辑感觉更加清晰。