专栏文章

C++炸金花

科技·工程参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio223w3
此快照首次捕获于
2025/12/02 12:05
3 个月前
此快照最后确认于
2025/12/02 12:05
3 个月前
查看原文
CPP
#include<windows.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<random>
#include<vector>
#include<queue>
#include<cmath>
#include<ctime>
#include<map>
#define intt long long
#define intu unsigned long long
#define dle double
#define dlel long double
using namespace std;
const int Imax=0x7fffffff;
const long long LLmax=0x7fffffffffffffff;
mt19937 Rand(time(0));
const string number[15] = {
	"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"
};
const string color[5] = {
	"黑桃", "红桃", "梅花", "方片"
};
struct Card {
	string color,number;
};
struct Cards {
	Card card[5];
};
struct Player {
	Cards _card_;
	int money;
	bool have_saw;//是否看过牌
	bool have_run;//是否逃跑
};
Player players[15];
vector<Card> cards;
int now_player,player_number;
int now_money;
int last_money;
int _choice;
int __;
void print() {//打印输出
	printf("%d 轮后开牌\n上家押的钱数:%d  本局总钱数:%d\n", player_number - __, last_money, now_money);
	for (int i = 1; i <= player_number; i++) {
		printf("玩家 %2d: 剩余钱数: %d  ", i, players[i].money);
		if (players[i].money <= 0) {
			puts("破产");
		} else if (players[i].have_run) {
			puts("逃跑");
		} else if (players[i].have_saw) {
			puts("看过牌");
		} else {
			puts("未看牌");
		}
	}
}
int operator < (Card _x, Card _y) {//两张牌比大小
	if (_x.number == _y.number) {//数字相同就比花色
		int _x_id = 0, _y_id = 0;
		while (color[_x_id] != _x.color) {
			_x_id++;
		}
		while (color[_y_id] != _y.color) {
			_y_id++;
		}
		return _x_id > _y_id;
	}
	//数字不相同就比数字
	int _x_id = 0, _y_id = 0;
	while (number[_x_id] != _x.number) {
		_x_id++;
	}
	while (number[_y_id] != _y.number) {
		_y_id++;
	}
	return _x_id < _y_id;
}
void init() {
	for (int i = 0; i < 4; i ++) {//初始化牌堆
		for (int j = 0; j < 13; j++) {
			cards.push_back((Card){color[i], number[j]});
		}
	}
	for (int i = 1; i <= player_number; i++) {
		for (int j = 1; j <= 3; j++) {
			int _size = cards.size();
			int choice = Rand() % _size;
			players[i]._card_.card[j] = cards[choice];
			cards.erase(cards.begin() + choice);
		}
		sort(players[i]._card_.card + 1, players[i]._card_.card + 4);//提前排好序
	}
}
string next_card(Card _card) {
	if(_card.number == "A") return "Nothing";
	int position = 0;
	while (number[position] != _card.number) {
		position ++;
	}
	return number[position + 1];
}
int check_baozi(Cards _card) {//检查是否为豹子
	return _card.card[1].number == _card.card[2].number && _card.card[2].number == _card.card[3].number;
}
int check_shunzi(Cards _card) {//检查是否为顺子
	return _card.card[2].number == next_card(_card.card[1]) && _card.card[3].number == next_card(_card.card[2]);
}
int check_tonghua(Cards _card) {//检查是否为同花
	return _card.card[1].color == _card.card[2].color && _card.card[2].color == _card.card[3].color;
}
int check_duizi(Cards _card) {//检查是否有对子
	return _card.card[1].number == _card.card[2].number || _card.card[2].number == _card.card[3].number;
}
int type(Cards _card) {//牌的类型
	if (check_baozi(_card)) {//豹子
		return 6;
	} else if (check_shunzi(_card) && check_tonghua(_card)) {//同花顺
		return 5;
	} else if (check_shunzi(_card)) {//顺子
		return 4;
	} else if (check_tonghua(_card)) {//同花
		return 3;
	} else if(check_duizi(_card)) { //对子
		return 2;
	} else {
		return 1;
	}
	return 0;
	
}
int operator < (Cards _x, Cards _y) {
	//235 比 AAA 大
	if (_x.card[1].number == "2" && _x.card[2].number == "3" && _x.card[3].number == "5") {
		if (_y.card[1].number == "A" && _y.card[2].number == "A" && _y.card[3].number == "A") {
			return 0;
		}
	}
	if (type(_x) != type(_y)) {//牌型不一样就直接判断大小
		return type(_x) < type(_y);
	} else if (type(_x) == 6) {//豹子比大小
		return _x.card[1] < _y.card[1];
	} else if (type(_x) == 5 || type(_x) == 4) {//同花顺(顺子)比大小
		return _x.card[3] < _y.card[3];
	} else if (type(_x) == 3) {//同花比大小
		for (int i = 3; i >= 1; i--) {//从大到小逐一比较
			if (_x.card[i].number != _y.card[i].number) {
				return _x.card[i] < _y.card[i];
			}
		}
		return _x.card[3] < _y.card[3];//数字一样就比花色
	} else if (type(_x) == 2) {//对子比大小
		Card _x_card, _y_card, _x_other, _y_other;//_x_card 和 _y_card 都取对子的较大者
		if (_x.card[1].number == _x.card[2].number) {
			_x_card.number = _x.card[2].number;
			_x_card.color = _x.card[2].color;
			_x_other.number = _x.card[3].number;
			_x_other.color = _x.card[3].color;
		} else {
			_x_card.number = _x.card[3].number;
			_x_card.color = _x.card[3].color;
			_x_other.number = _x.card[1].number;
			_x_other.color = _x.card[1].color;
		}
		if (_y.card[1].number == _y.card[2].number) {
			_y_card.number = _y.card[2].number;
			_y_card.color = _y.card[2].color;
			_y_other.number = _y.card[3].number;
			_y_other.color = _y.card[3].color;
		} else {
			_y_card.number = _y.card[3].number;
			_y_card.color = _y.card[3].color;
			_y_other.number = _y.card[1].number;
			_y_other.color = _y.card[1].color;
		}
		if (_x_card.number == _y_card.number) {//对子数字相同就比剩下的数字
			if (_x_other.number == _y_other.number) {//剩下的数字还一样就比对子的花色
				//由于两人各 2 张,共 4 张,必有黑桃,黑桃在哪家,哪家就大
				return _y_card.color == "黑桃";
			}
			//剩下的数字不一样就比剩下牌的数字
			return _x_other < _y_other;
		}
		//对子数字不同就必对子数字
		return _x_card < _y_card;
	} else {//散牌比大小
		//与同花相同
		for (int i = 3; i >= 1; i--) {//从大到小逐一比较
			if (_x.card[i].number != _y.card[i].number) {
				return _x.card[i] < _y.card[i];
			}
		}
		return _x.card[3] < _y.card[3];//数字一样就比花色
	}
	return 0;//防 Warning,不会执行到这里
}
int hashh(Cards _card) {//算牌力
	if (type(_card) == 1) {//散牌
		if (_card.card[3].number == "A" || _card.card[3].number == "K") {//有 K 或 A 可以高一点
			return 500;
		} else {//否则最好尽快跑路
			return 100;
		}
	} else if (type(_card) == 2) {//对子,常规牌
		if (_card.card[1].number == _card.card[2].number) {
			if((Card){"黑桃","8"} < _card.card[2]) {//比较大的对子
				return 3000;
			} else {//小对子
				return 1000;
			}
		}
	} else if (type(_card) == 3) {//同花,稀有牌
		return 8000;
	} else if (type(_card) == 4) {//顺子,超稀有
		return 20000;
	} else if (type(_card) == 5) {//同花顺,超级稀有
		return 60000;
	}
	return 100000;//豹子,终极稀有
}
bool check(int number) {//number% 的概率是否中了
	return Rand() % 100 <= number;
}
int random(int L, int R) {//在 [L,R] 中生成随机数
	return Rand() % (R - L + 1) + L;
}
void play(int id) {//编号为 id 的玩家进行游戏
	system("cls");
	print();
	if (id == 1) {//编号为 1 的玩家为真人玩家
		if (!players[id].have_saw) {//没看过牌可以选择看牌
			puts("您是否选择看牌?(请输入 0 或 1)");
			scanf("%d", &_choice);
			if (_choice == 1) {
				players[id].have_saw = 1;
			}
		}
		if (players[id].have_saw) {
			puts("\n您的牌是:");
			for (int i = 1; i <= 3; i++) {
				cout << players[id]._card_.card[i].color << players[id]._card_.card[i].number << " ";
			}
			putchar('\n');
		}
		puts("您是否选择逃跑?(请输入 0 或 1)");
		scanf("%d", &_choice);
		if (_choice == 1) {
			players[id].have_run = 1;
			now_player--;
			return;
		}
		int money_number;
		printf("\n请输入您要押的钱数(不得少于上家),上家押的钱数为:%d\n", last_money);
		scanf("%d", &money_number);
		while (money_number < last_money || players[id].money < money_number) {
			puts("输入有误,请重新输入");
			Sleep(2000);
			system("cls");
			print();
			if (!players[id].have_saw) {
				puts("您是否选择看牌?(请输入 0 或 1)");
				scanf("%d", &_choice);
				if (_choice == 1) {
					players[id].have_saw = 1;
				}
			}
			if (players[id].have_saw) {
				puts("\n您的牌是:");
				for (int i = 1; i <= 3; i++) {
					cout << players[id]._card_.card[i].color << players[id]._card_.card[i].number << " ";
				}
				putchar('\n');
			}
			puts("您是否选择逃跑?(请输入 0 或 1)");
			scanf("%d", &_choice);
			if (_choice == 1) {
				players[id].have_run = 1;
				now_player--;
				return;
			}
			printf("\n请输入您要押的钱数(不得少于上家),上家押的钱数为:%d\n", last_money);
			scanf("%d", &money_number);
		}
		players[id].money -= money_number;
		last_money = money_number;
		now_money += money_number;
	} else {//否则是人机
		Sleep(2000);
		if (players[id].money < last_money) {//钱不够直接跑
			printf("玩家 %d 逃跑\n", id);
			players[id].have_run = 1;
			now_player--;
			return;
		}
		if (!players[id].have_saw) {
			if (check(25)) {//有 25% 的概率看牌
				printf("玩家 %d 看牌\n", id);
				players[id].have_saw = 1;
				Sleep(2000);
			}
		}
		if (players[id].have_saw) {//看过牌可以根据牌力选择是否逃跑
			if (hashh(players[id]._card_) < now_money) {//牌力不够
				if (check(40)) {//40% 的概率逃跑
					printf("玩家 %d 逃跑\n", id);
					players[id].have_run = 1;
					now_player--;
					return;
				}
			}
		}
		if (check(3)) {//3% 的概率逃跑
			printf("玩家 %d 逃跑\n", id);
			players[id].have_run = 1;
			now_player--;
			return;
		}
		int money_number = last_money + random(0, 100);
		if (players[id].have_saw) {//看过牌可以根据牌力押钱
			if (hashh(players[id]._card_) > now_money * 5) {//超了 5 倍
				money_number = random(last_money, last_money + 2000);
			} else if (hashh(players[id]._card_) > now_money * 3) {//超了 3 倍
				money_number = random(last_money, last_money + 800);
			} else if (hashh(players[id]._card_) > now_money * 2) {//超了 2 倍
				money_number = random(last_money, last_money + 500);
			} else {
				money_number = random(last_money, last_money + 100);
			}
		}
		while (check(30)) {//30% 的概率加随机数
			money_number += random(0, 50);
		}
		while (money_number > players[id].money) {//钱不够
			money_number--;
		}
		printf("玩家 %d 押 %d 元\n", id, money_number);
		players[id].money -= money_number;
		last_money = money_number;
		now_money += money_number;
	}
}
void open_card() {//开牌
	system("cls");
	puts("清算时刻");
	Sleep(2000);
	int max_id = -1;
	for (int i = 1; i <= player_number; i++) {
		if (players[i].money <= 0) {
			printf("玩家 %d 破产\n", i);
		} else if (players[i].have_run) {
			printf("玩家 %d 逃跑\n", i);
		} else {
			Sleep(1000);
			printf("玩家 %d 的牌:", i);
			Sleep(2000);
			for (int j = 1; j <= 3; j++) {
				cout << players[i]._card_.card[j].color << players[i]._card_.card[j].number << " ";
			}
			if (max_id == -1) {
				max_id = i;
			} else {
				if (players[max_id]._card_ < players[i]._card_) {
					max_id = i;
				}
			}
			putchar('\n');
		}
	}
	Sleep(1000);
	printf("玩家 %d 获胜\n", max_id);
	players[max_id].money += now_money;
	Sleep(4000);
}
void Main() {//程序核心实现
	puts("请输入人数(最少为 2 且最多为 10):");
	scanf("%d", &player_number);
	while (player_number < 2 || player_number > 10) {//输入有误
		system("cls");
		puts("输入有误,请重新输入游戏人数:");
		scanf("%d", &player_number);
	}
	for (int i = 1; i <= player_number; i++) {
		players[i].money = 10000;
	}
	while (1) {
		init();
		__ = last_money = now_money = 0;
		for (int i = 1; i <= player_number; i++) {
			players[i].have_saw = players[i].have_run = 0;
		}
		now_player = player_number;
		bool have_open_card = 0;
		while (__ < player_number) {
			for (int i = 1; i <= player_number; i++) {
				if (now_player == 1) {
					open_card();
					have_open_card = 1;
					break;
				}
				if (players[i].have_run || !players[i].money) {
					continue;
				} else {
					play(i);
				}
				Sleep(3000);
			}
			if (have_open_card) {
				break;
			}
			__++;
		}
		if (!have_open_card) {
			open_card();
		}
	}
}
int main() {
	Main();
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...