加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
BlackJackAITest.cpp 39.92 KB
一键复制 编辑 原始数据 按行查看 历史
陆静君 提交于 2024-12-05 16:57 . 4人,修改奖励
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189
// BlackJackAITest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <torch/script.h>
#include "torch/torch.h"
#include "biostream.h"
typedef std::vector<int> VecInt;
typedef std::vector<VecInt> VecVecInt;
typedef std::map<int, VecVecInt> MapVecVecInt;
typedef std::map<int, VecInt> MapVecInt;
struct D21AiModule {
torch::DeviceType device_type;
torch::jit::script::Module module;
};
int aamain()
{
// 检查是否有可用的CUDA设备
bool cuda_is_available = torch::cuda::is_available();
if (!cuda_is_available) {
std::cerr << "CUDA is not available." << std::endl;
return 1; // 如果没有CUDA设备,则退出程序
}
// 初始化张量并指定设备类型
//torch::Tensor tensor = torch::rand({2, 3}, torch::device(torch::kCUDA).dtype(torch::kFloat32));
//std::cout << tensor << std::endl;
// 加载 TorchScript 模型
std::cout << "Loading model\n";
torch::DeviceType device_type = at::kCUDA;
torch::jit::script::Module module;
try {
module = torch::jit::load("D:/code/rlcard/examples/experiments/blackjack_dqn_result/model_scripted.pt", device_type);
module.eval();
std::cout << "Model loaded\n";
} catch (const c10::Error& e) {
std::cerr << "Error loading the model: " << e.what() << std::endl;
return -1;
}
// 创建输入 Tensor 并指定设备类型
//torch::Tensor tensor1 = torch::randint(5, 21, {1, 2}, torch::device(torch::kCUDA).dtype(torch::kFloat32));
//std::cout << tensor1 << std::endl;
for (size_t i = 0; i < 100; i++)
{
//at::Tensor tensor_gpu = torch::tensor({ {10, 21} }, at::device(at::DeviceType::CUDA).dtype(at::ScalarType::Float));
//at::Tensor tensor_gpu = torch::randint(5, 21, {1, 2}, torch::device(torch::kCUDA).dtype(torch::kFloat32));
//std::cout << tensor_gpu << std::endl;
std::cout << " >>>>>>>>> 第 " << i << "局 \n";
at::Tensor tensor_cpu = torch::randint(5, 21, { 1, 2 });
float my_value = tensor_cpu[0][0].item<int>();
float zhuang_value = tensor_cpu[0][1].item<int>();
std::cout << "我的点数:" << my_value << " 庄家的点数:" << zhuang_value << std::endl;
// 将张量转移到GPU上
at::Tensor tensor_gpu = tensor_cpu.to(device_type, torch::kFloat32);
// 准备输入
std::vector<torch::jit::IValue> inputs;
inputs.push_back(tensor_gpu);
// 执行模型
auto out = module.forward(inputs).toTensor(); // 确保结果也是 Tensor 类型
// 将张量从GPU复制到CPU内存
out = out.to(torch::kCPU); // 将张量移动到CPU
// 访问张量中的值
//std::cout << "q_value:" << out << std::endl;
// 获取张量中的值
float first_value = out[0][0].item<float>();
float second_value = out[0][1].item<float>();
std::cout << "q_value:" << first_value << " " << second_value << std::endl;
if (first_value > second_value)
{
std::cout << "选择 要" << "\n";
}
else {
std::cout << "选择 不要" << "\n";
}
std::cout << "\n";
}
}
template<typename T>
inline void InitArray(T* pData, int nLen, T nData = 0) {
for (int i = 0;i < nLen;++i) {
pData[i] = nData;
}
}
template<typename T>
inline void ZeroArray(T* pData, int nLen) {
for (int i = 0;i < nLen;++i) {
pData[i] = 0;
}
}
int cards3_2[3][2] = { {0, 1}, {0, 2}, {1, 2} };
int cards4_2[6][2] = { {0, 1},{0, 2},{0, 3},
{1, 2},{1, 3},
{2, 3} };
int cards4_3[4][3] = { {0, 1, 2},{0, 1, 3},{0, 2, 3},{1, 2, 3} };
int getPaiType(std::vector<int>& pai) {
int size = pai.size();
if (size < 3) {
return size;
}
if (size == 3) {
if (pai[0]/4 == pai[1]/4) return 3;
else return 5;
}
else if (size == 4) {
if (pai[0] / 4 == pai[1] / 4) return 4;
else return 5;
}
else if (size % 2 == 0) {
if (pai[0] / 4 == pai[1] / 4) return 6;
else return 5;
}
else {
return 5;
}
}
void selectCardsFromArray3_2(VecInt& srcDic, VecVecInt& target) {
for (size_t i = 0; i < 3; i++)
{
VecInt cards;
for (size_t j = 0; j < 2; j++)
{
cards.push_back(srcDic[cards3_2[i][j]]);
}
if(cards.size() == 2) target.push_back(cards);
}
}
void selectCardsFromArray4_2(VecInt& srcDic, VecVecInt& target) {
for (size_t i = 0; i < 6; i++)
{
VecInt cards;
for (size_t j = 0; j < 2; j++)
{
cards.push_back(srcDic[cards4_2[i][j]]);
}
if (cards.size() == 2) target.push_back(cards);
}
}
void selectCardsFromArray4_3(VecInt& srcDic, VecVecInt& target) {
for (size_t i = 0; i < 4; i++)
{
VecInt cards;
for (size_t j = 0; j < 3; j++)
{
cards.push_back(srcDic[cards4_3[i][j]]);
}
if (cards.size() == 3) target.push_back(cards);
}
}
template<typename T>
std::vector<std::vector<T>> cartesianProduct(const std::vector<std::vector<T>>& arrays) {
std::vector<std::vector<T>> result;
std::vector<T> temp(arrays.size());
// 递归生成笛卡尔积
std::function<void(int)> generateCombinations = [&](int depth) {
if (depth == arrays.size()) {
result.push_back(temp);
return;
}
for (const auto& item : arrays[depth]) {
temp[depth] = item;
generateCombinations(depth + 1);
}
};
generateCombinations(0);
return result;
}
// 生成二元组合的函数
std::vector<std::vector<int>> combinationsOfTwo(const std::vector<int>& array) {
std::vector<std::vector<int>> result;
for (size_t i = 0; i < array.size(); ++i) {
for (size_t j = i + 1; j < array.size(); ++j) {
result.push_back({ array[i], array[j] });
}
}
return result;
}
void selectChain2FromArray(MapVecInt& srcDic, int start, int end, VecVecInt& target) {
if (!(start >= 0 && end > 0 && end - start >= 2)) return;
VecVecInt array;
for (int i = start; i <= end; ++i) {
array.push_back(srcDic.at(i));
}
// 生成每个子数组的二元组合
std::vector<std::vector<std::vector<int>>> combinations_per_array;
for (const auto& sub_array : array) {
combinations_per_array.push_back(combinationsOfTwo(sub_array));
}
// 生成所有子数组组合的笛卡尔积
std::vector<std::vector<std::vector<int>>> all_combinations = cartesianProduct(combinations_per_array);
// 将结果转换为二维数组形式
for (const auto& combination : all_combinations) {
std::vector<int> flatCombination;
for (const auto& sublist : combination) {
flatCombination.insert(flatCombination.end(), sublist.begin(), sublist.end());
}
target.push_back(flatCombination);
}
}
void selectChainFromArray(MapVecInt& srcDic, int start, int end, VecVecInt& target) {
if (!(start >= 0 && end > 0 && end - start >= 2)) return;
VecVecInt array;
for (size_t i = start; i <= end; i++)
{
array.push_back(srcDic[i]);
}
// 生成笛卡尔积
VecVecInt all_combinations;
all_combinations = cartesianProduct(array);
for (const auto& combination : all_combinations) {
target.push_back(combination);
}
}
int leftPaycount(const int cardcount[13], VecInt& out, int start, int end) {
int tempcount[13];
for (size_t i = 0; i < 13; i++)
{
tempcount[i] = cardcount[i];
}
for (size_t i = 0; i < out.size(); i++)
{
tempcount[out[i] / 4] -= 1;
}
int paycount = 1;
for (size_t i = start; i <= end; i++)
{
if (tempcount[i] > 0) paycount++;
}
return paycount;
}
int getMaxPaycount(const int cardcount[13], int start, int end, int num) {
int tempcount[13];
for (size_t i = 0; i < 13; i++)
{
tempcount[i] = cardcount[i];
}
for (size_t i = start; i <= end; i++)
{
tempcount[i] -= num;
}
int paycount = 1;
for (size_t i = start; i <= end; i++)
{
if (tempcount[i] > 0) paycount++;
}
return paycount;
}
//把手牌中的双顺取出,是否符合出牌需要另外判断
void getShuangShun(const int cardcount[13], MapVecInt& cards_dict, VecVecInt& list) {
// 双顺
int start = -1;
int end = -1;
int count = 0;
for (size_t idx = 0; idx < 12; idx++)
{
if (cardcount[idx] > 1) {
if (start == -1) {
start = idx;
end = idx;
}
else {
end = idx;
}
}
else {
count = end - start + 1;
if (count >= 3) {
int max = getMaxPaycount(cardcount, start, end, 2);
for (size_t ct = 3; ct < count+1; ct++)
{
for (size_t ss = start; ss < end - ct + 2; ss++)
{
VecVecInt chainlist;
selectChain2FromArray(cards_dict, ss, ss + ct - 1, chainlist);
for (size_t chainidx = 0; chainidx < chainlist.size(); chainidx++)
{
int paycount = leftPaycount(cardcount, chainlist.at(chainidx), start, end);
if (paycount <= max) {
list.push_back(chainlist.at(chainidx));
}
}
}
}
}
start = -1;
end = -1;
}
}
count = end - start + 1;
if (count >= 3) {
int max = getMaxPaycount(cardcount, start, end, 2);
for (size_t ct = 3; ct < count + 1; ct++)
{
for (size_t ss = start; ss < end - ct + 2; ss++)
{
VecVecInt chainlist;
selectChain2FromArray(cards_dict, ss, ss + ct - 1, chainlist);
for (size_t chainidx = 0; chainidx < chainlist.size(); chainidx++)
{
int paycount = leftPaycount(cardcount, chainlist.at(chainidx), start, end);
if (paycount <= max) {
list.push_back(chainlist.at(chainidx));
}
}
}
}
}
}
//把手牌中的单顺取出,是否符合出牌需要另外判断
void getDanShun(const int cardcount[13], MapVecInt& cards_dict, VecVecInt& list) {
int start = -1;
int end = -1;
int count = 0;
for (size_t idx = 0; idx < 12; idx++)
{
if (cardcount[idx] > 0) {
if (start == -1) {
start = idx;
end = idx;
}
else {
end = idx;
}
}
else {
count = end - start + 1;
if (count >= 3) {
int max = getMaxPaycount(cardcount, start, end, 1);
for (size_t ct = 3; ct < count + 1; ct++)
{
for (size_t ss = start; ss < end - ct + 2; ss++)
{
VecVecInt chainlist;
selectChainFromArray(cards_dict, ss, ss + ct - 1, chainlist);
for (size_t chainidx = 0; chainidx < chainlist.size(); chainidx++)
{
int paycount = leftPaycount(cardcount, chainlist.at(chainidx), start, end);
if (paycount <= max) {
list.push_back(chainlist.at(chainidx));
}
}
}
}
}
start = -1;
end = -1;
}
}
count = end - start + 1;
if (count >= 3) {
int max = getMaxPaycount(cardcount, start, end, 1);
for (size_t ct = 3; ct < count + 1; ct++)
{
for (size_t ss = start; ss < end - ct + 2; ss++)
{
VecVecInt chainlist;
selectChainFromArray(cards_dict, ss, ss + ct - 1, chainlist);
for (size_t chainidx = 0; chainidx < chainlist.size(); chainidx++)
{
int paycount = leftPaycount(cardcount, chainlist.at(chainidx), start, end);
if (paycount <= max) {
list.push_back(chainlist.at(chainidx));
}
}
}
}
}
}
void getDanZhang(VecInt cards, VecVecInt& list) {
int len = cards.size();
for (size_t idx = 0; idx < len; idx++)
{
VecInt cc;
cc.push_back(cards[idx]);
list.push_back(cc);
}
}
int getDanZhangCount(const int cardcount[13]) {
int ct = 0;
for (size_t idx = 0; idx < 13; idx++)
{
if (cardcount[idx] == 1) {
ct++;
}
}
return ct;
}
void getDuiZi(const int cardcount[13], MapVecInt& cards_dict, VecVecInt& list) {
for (size_t idx = 0; idx < 13; idx++)
{
if (cardcount[idx] == 2) {
list.push_back(cards_dict[idx]);
}
else if (cardcount[idx] == 3) {
selectCardsFromArray3_2(cards_dict[idx], list);
}
else if (cardcount[idx] == 4) {
selectCardsFromArray4_2(cards_dict[idx], list);
}
}
}
void getSanZhang(const int cardcount[13], MapVecInt& cards_dict, VecVecInt& list) {
for (size_t idx = 0; idx < 13; idx++)
{
if (cardcount[idx] == 3) {
list.push_back(cards_dict[idx]);
}
else if (cardcount[idx] == 4) {
selectCardsFromArray4_3(cards_dict[idx], list);
}
}
}
void getZhaDan(const int cardcount[13], MapVecInt& cards_dict, VecVecInt& list) {
for (size_t idx = 0; idx < 13; idx++)
{
if (cardcount[idx] == 4) {
list.push_back(cards_dict[idx]);
}
}
}
void vector2Array(VecInt& cards, int *array, int start) {
for (size_t i = 0; i < cards.size(); i++)
{
array[cards[i]+start] = 1;
}
}
void checkVector(VecInt& cards) {
if (cards.size() == 1 && cards[0] > 51) {
cards.clear();
}
}
void checkVecVec(VecVecInt& cards) {
for (size_t i = 0; i < cards.size(); i++)
{
checkVector(cards[i]);
}
}
void printVector(VecInt& cards) {
std::cout << "[";
for (size_t i = 0; i < cards.size(); i++)
{
std::cout << " " << cards[i];
}
std::cout << " ]" << std::endl;
}
void printVecVec(VecVecInt& cards) {
for (size_t i = 0; i < cards.size(); i++)
{
printVector(cards[i]);
}
}
void sortVector(VecInt& cards) {
std::sort(cards.begin(), cards.end());
}
void addToArray(VecInt& org, int arr[52]) {
for (size_t i = 0; i < org.size(); i++)
{
arr[org[i]] = 1;
}
}
extern "C" __declspec(dllexport) void* CreateXNP2RAiModule() {
// 加载 TorchScript 模型
std::cout << "Loading model\n";
torch::DeviceType device_type = at::kCPU;
torch::jit::script::Module module;
try {
module = torch::jit::load("D:/code/BlackJackAITest/models/model_scripted_xnp.pt", device_type);
module.eval();
std::cout << "Model loaded\n";
}
catch (const c10::Error& e) {
std::cerr << "Error loading the model: " << e.what() << std::endl;
return 0;
}
D21AiModule* a = new D21AiModule();
a->device_type = device_type;
a->module = module;
return a;
}
extern "C" __declspec(dllexport) void XNP2RAi(void* ai, VecInt& current_hand, VecInt& others_hand, VecInt& last_greater,
VecInt& last_action, VecVecInt& last_9_actions, VecInt& current_played_cards,
VecInt& other_played_cards, int current_num_cards_left, int other_num_cards_left, bool jump, VecInt& action) {
std::cout << std::endl;
std::cout << "----------- XNP2RAi start ------------ " << std::endl;
checkVector(last_greater);
checkVector(last_action);
checkVecVec(last_9_actions);
checkVector(current_played_cards);
checkVector(other_played_cards);
sortVector(last_greater);
std::cout << "current_hand size = " << current_hand.size() << std::endl;
printVector(current_hand);
std::cout << "last_greater size = " << last_greater.size() << std::endl;
printVector(last_greater);
std::cout << "last_action size = " << last_action.size() << std::endl;
printVector(last_action);
std::cout << "last_9_actions size = " << last_9_actions.size() << std::endl;
printVecVec(last_9_actions);
std::cout << "current_played_cards size = " << current_played_cards.size() << std::endl;
printVector(current_played_cards);
std::cout << "other_played_cards size = " << other_played_cards.size() << std::endl;
printVector(other_played_cards);
std::cout << "current_num_cards_left = " << current_num_cards_left << std::endl;
std::cout << "other_num_cards_left = " << other_num_cards_left << std::endl;
VecVecInt playCards;
MapVecInt cards_dict;
int card_count[13];
InitArray(card_count, 13);
int exclude[52];
InitArray(exclude, 52, 0);
int handcount = current_hand.size();
int greaterLength = last_greater.size();
if (greaterLength == 0) {
for (size_t i = 0; i < handcount; i++)
{
int card_value = current_hand[i];
int ds = card_value / 4;
int hs = card_value % 4;
if (cards_dict.find(ds) == cards_dict.end()) {
cards_dict[ds] = std::vector<int>();
}
cards_dict[ds].push_back(card_value);
card_count[ds] += 1;
}
int payoff = 0;
if (payoff == 0) {
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
int maxlen = 0;
for (size_t i = 0; i < list.size(); i++)
{
if (list[i].size() > maxlen) {
maxlen = list[i].size();
}
}
if (list.size() > 0 && handcount <= maxlen+1) {
payoff = 1;
}
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (payoff == 1) {
if (cards.size() == maxlen) {
playCards.push_back(cards);
addToArray(cards, exclude);
}
}
else {
playCards.push_back(cards);
addToArray(cards, exclude);
}
}
}
if (payoff == 0) {
VecVecInt list;
getDanShun(card_count, cards_dict, list);
int maxlen = 0;
for (size_t i = 0; i < list.size(); i++)
{
if (list[i].size() > maxlen) {
maxlen = list[i].size();
}
}
if (list.size() > 0 && handcount <= maxlen + 1) {
payoff = 1;
}
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (payoff == 1) {
if (cards.size() == maxlen) {
playCards.push_back(cards);
addToArray(cards, exclude);
}
}
else {
playCards.push_back(cards);
addToArray(cards, exclude);
}
}
}
if (payoff == 0) {
VecVecInt list;
getZhaDan(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
playCards.push_back(cards);
addToArray(cards, exclude);
}
if (list.size() > 0 && handcount <= 4 + 1) {
payoff = 1;
}
}
if (payoff == 0) {
VecVecInt list;
getSanZhang(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
playCards.push_back(cards);
}
if (list.size() > 0 && handcount <= 3 + 1) {
payoff = 1;
}
}
if (payoff == 0) {
VecVecInt list;
getDuiZi(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() > 0 && exclude[cards[0]] == 0) {
playCards.push_back(cards);
}
}
if (list.size() > 0 && handcount <= 2+1) {
payoff = 1;
}
}
if (payoff == 0) {
if (other_num_cards_left == 1) {//打最大的
int card = -1;
for (size_t i = 0; i < current_hand.size(); i++)
{
if (current_hand.at(i) > card) {
card = current_hand.at(i);
}
}
if (card < 0) {
card = current_hand.at(0);
}
VecInt cards;
cards.push_back(card);
playCards.push_back(cards);
}
else {
getDanZhang(current_hand, playCards);
}
}
}
else {
int greaterType = getPaiType(last_greater);
int greaterValue = last_greater[greaterLength - 1];
bool isPig = greaterValue >= 48 && greaterValue < 52;
playCards.push_back(std::vector<int>());//先加一个不要
for (size_t i = 0; i < handcount; i++)
{
int card_value = current_hand[i];
int ds = card_value / 4;
int hs = card_value % 4;
if (cards_dict.find(ds) == cards_dict.end()) {
cards_dict[ds] = std::vector<int>();
}
cards_dict[ds].push_back(card_value);
card_count[ds] += 1;
if (greaterType == 1 && card_value > greaterValue && !jump) {
//牌值大的单牌
VecInt cards;
cards.push_back(card_value);
playCards.push_back(cards);
}
}
if (jump) {
//跳过后只能出四对顺,小于8张直接不判定了
if (current_hand.size() >= 8) {
if (isPig && (greaterType == 1 || greaterType == 2)) {
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8) {
playCards.push_back(cards);
}
}
}
else if (greaterType == 4) {
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8) {
playCards.push_back(cards);
}
}
}
else if (greaterType == 6) {
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8) {
if (greaterLength == 6) {
playCards.push_back(cards);
}
else if (greaterLength == 8 && greaterValue < cards[cards.size() - 1]) {
playCards.push_back(cards);
}
}
}
}
}
}
else {
if (greaterType == 1) {
//单牌的情况,1.牌值大 2.猪的时候(三对顺,四队顺,炸弹)
if (isPig) {
getZhaDan(card_count, cards_dict, playCards);
getShuangShun(card_count, cards_dict, playCards);
}
}
else if (greaterType == 2) {
//对子 1.牌值大的对子 2.猪的时候(四队顺,炸弹)
VecVecInt list;
getDuiZi(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
}
if (isPig) {
list.clear();
getZhaDan(card_count, cards_dict, playCards);
list.clear();
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8) {
playCards.push_back(cards);
}
}
}
}
else if (greaterType == 3) {
//三张 1.牌值大的三张
VecVecInt list;
getSanZhang(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
}
}
else if (greaterType == 4) {
//四张 1.四张 2.四队顺
VecVecInt list;
getZhaDan(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
}
list.clear();
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8) {
playCards.push_back(cards);
}
}
}
else if (greaterType == 5) {
//顺子 1.顺子
VecVecInt list;
getDanShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == greaterLength && cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
}
}
else if (greaterType == 6) {
//对顺
if (greaterLength == 6) {
//三对顺 1.三对顺 2.四对顺 3.炸弹
getZhaDan(card_count, cards_dict, playCards);
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == greaterLength && cards.size() == 6 && cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
else if (cards.size() == 8) {
playCards.push_back(cards);
}
}
}
else if (greaterLength == 8) {
//四队顺 1.四队顺
VecVecInt list;
getShuangShun(card_count, cards_dict, list);
for (size_t i = 0; i < list.size(); i++)
{
VecInt cards = list[i];
if (cards.size() == 8 && cards[cards.size() - 1] > greaterValue) {
playCards.push_back(cards);
}
}
}
}
}
}
int obs[754];
InitArray(obs, 754);
int start = 0;
vector2Array(current_hand, obs, start);
start += 52;
vector2Array(others_hand, obs, start);
start += 52;
vector2Array(last_action, obs, start);
start += 52;
int s9_start = start;
s9_start += (9-last_9_actions.size())*52;
for (size_t i = 0; i < last_9_actions.size(); i++)
{
vector2Array(last_9_actions[i], obs, s9_start);
s9_start += 52;
}
start += 468;
vector2Array(current_played_cards, obs, start);
start += 52;
vector2Array(other_played_cards, obs, start);
start += 52;
obs[start + current_num_cards_left-1] = 1;
start += 13;
obs[start + other_num_cards_left-1] = 1;
int action_num = playCards.size();
std::vector<std::vector<float>> action_array;
for (size_t i = 0; i < action_num; i++)
{
std::vector<float> temp_actionArray(52, 0.0f); // 使用 vector<float> 来代替 std::array
for (size_t j = 0; j < playCards[i].size(); j++)
{
temp_actionArray[playCards[i][j]] = 1.0f; // 使用 float 类型
}
action_array.push_back(temp_actionArray);
}
std::vector<std::vector<float>> obs_vector;
for (size_t i = 0; i < action_num; i++)
{
std::vector<float> temp_obsArray(754, 0.0f);
for (size_t i = 0; i < 754; i++)
{
temp_obsArray[i] = (float)obs[i];
}
obs_vector.push_back(temp_obsArray);
}
// 计算二维数组的维度
size_t rows = obs_vector.size();
// 扁平化为一维 vector
std::vector<float> flat_data;
for (size_t i = 0; i < rows; i++) {
flat_data.insert(flat_data.end(), obs_vector[i].begin(), obs_vector[i].end());
}
// 使用 torch::from_blob 创建 Tensor
at::Tensor tensor_obs = torch::from_blob(flat_data.data(), { action_num, 754 }, at::TensorOptions().dtype(at::ScalarType::Float));
// 计算二维数组的维度
rows = action_array.size();
// 扁平化为一维 vector
std::vector<float> flat_data1;
for (size_t i = 0; i < rows; i++) {
flat_data1.insert(flat_data1.end(), action_array[i].begin(), action_array[i].end());
}
// 使用 torch::from_blob 创建 Tensor
at::Tensor tensor_actions = torch::from_blob(flat_data1.data(), { action_num, 52 }, at::TensorOptions().dtype(at::ScalarType::Float));
// 转换为 Tensor
//at::Tensor tensor_obs = torch::from_blob(obsss.data(), { action_num, 754 }, at::TensorOptions().dtype(at::ScalarType::Float));
//at::Tensor tensor_actions = torch::from_blob(action_array.data(), { action_num, 52 }, at::TensorOptions().dtype(at::ScalarType::Float));
D21AiModule* mm = (D21AiModule*)ai;
// 准备输入
std::vector<torch::jit::IValue> inputs;
inputs.push_back(tensor_obs);
inputs.push_back(tensor_actions);
std::cout << "XNP2RAi module.forward >>>>>> " << std::endl;
// 执行模型
auto out = mm->module.forward(inputs).toTensor(); // 确保结果也是 Tensor 类型
auto num = torch::argmax(out);
//std::cout << "out :" << num.item<float>() << std::endl;
//// 方法三:使用 data_ptr 方法(适用于多维张量)
//if (out.numel() > 1) {
// float* data_ptr = out.data_ptr<float>();
// for (int i = 0; i < out.numel(); ++i) {
// std::cout << "Element " << i << ": " << data_ptr[i] << std::endl;
// }
//}
VecInt select_action = playCards[num.item<float>()];
std::cout << "select_action size =" << select_action.size() << std::endl;
for (size_t i = 0; i < select_action.size(); i++)
{
action.push_back(select_action[i]);
}
printVector(action);
// 释放内存
//for (int i = 0; i < action_num; ++i) {
// delete[] action_array[i];
//}
//delete[] action_array;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门使用技巧:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
extern "C" __declspec(dllexport) void* CreateD21AiModule() {
bool cuda_is_available = torch::cuda::is_available();
if (!cuda_is_available) {
std::cerr << "CUDA is not available." << std::endl;
return 0; // 如果没有CUDA设备,则退出程序
}
// 初始化张量并指定设备类型
//torch::Tensor tensor = torch::rand({2, 3}, torch::device(torch::kCUDA).dtype(torch::kFloat32));
//std::cout << tensor << std::endl;
// 加载 TorchScript 模型
std::cout << "Loading model\n";
torch::DeviceType device_type = at::kCUDA;
torch::jit::script::Module module;
try {
module = torch::jit::load("D:/code/BlackJackAITest/models/model_scripted_21d.pt", device_type);
module.eval();
std::cout << "Model loaded\n";
}
catch (const c10::Error& e) {
std::cerr << "Error loading the model: " << e.what() << std::endl;
return 0;
}
D21AiModule* a = new D21AiModule();
a->device_type = device_type;
a->module = module;
return a;
}
extern "C" __declspec(dllexport) int D21Ai(void* ai,int self_dianshu,int zhuang_dianshu) {
D21AiModule* mm = (D21AiModule*)ai;
//at::Tensor tensor_cpu = torch::randint(5, 21, { 1, 2 });
at::Tensor tensor_gpu = torch::tensor({ {self_dianshu, zhuang_dianshu} }, at::device(at::DeviceType::CUDA).dtype(at::ScalarType::Float));
/*float my_value = tensor_gpu[0][0].item<int>();
float zhuang_value = tensor_gpu[0][1].item<int>();
std::cout << "我的点数:" << my_value << " 庄家的点数:" << zhuang_value << std::endl;*/
// 将张量转移到GPU上
//at::Tensor tensor_gpu = tensor_cpu.to(mm->device_type, torch::kFloat32);
// 准备输入
std::vector<torch::jit::IValue> inputs;
inputs.push_back(tensor_gpu);
// 执行模型
auto out = mm->module.forward(inputs).toTensor(); // 确保结果也是 Tensor 类型
// 将张量从GPU复制到CPU内存
out = out.to(torch::kCPU); // 将张量移动到CPU
// 访问张量中的值
//std::cout << "q_value:" << out << std::endl;
// 获取张量中的值
float first_value = out[0][0].item<float>();
float second_value = out[0][1].item<float>();
std::cout << "q_value:" << first_value << " " << second_value << std::endl;
if (first_value > second_value)
{
std::cout << "选择 要" << "\n";
}
else {
std::cout << "选择 不要" << "\n";
}
std::cout << "\n";
return first_value > second_value ? 1 : 0;
}
extern "C" __declspec(dllexport) void DeleteD21AiModule(void* ai) {
D21AiModule* mm = (D21AiModule*)ai;
//delete[] mm;
}
extern "C" __declspec(dllexport) void* CreateAiModule241120(const char* mode)
{
if (strstr(mode, "xnp")) {
return CreateXNP2RAiModule();
}
return 0;
}
extern "C" __declspec(dllexport) int AiRun241120(void* ai,int len,unsigned char* in_data,unsigned char* out_data,int outmaxlen)
{
VecInt current_hand; VecInt others_hand; VecInt last_greater;
VecInt last_action; VecVecInt last_9_actions; VecInt current_played_cards;
VecInt other_played_cards; int current_num_cards_left=0; int other_num_cards_left=0; bool jump=false; VecInt action;
Win32Tools::biostream bios((char* )in_data, len);
unsigned char temp=0, temp1=0,tempv=0;
bios >> temp;current_hand.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(current_hand).at(i) = tempv; }
bios >> temp;others_hand.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(others_hand).at(i) = tempv; }
bios >> temp;last_greater.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(last_greater).at(i) = tempv; }
bios >> temp;last_action.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(last_action).at(i) = tempv; }
bios >> temp;last_9_actions.resize(temp);
for (unsigned int i = 0;i < temp;i++) {
bios >> temp1;last_9_actions[i].resize(temp1);
for (unsigned int j = 0;j < temp1;j++) {
bios >> tempv;last_9_actions.at(i).at(j) = tempv;
}
}
bios >> temp;current_played_cards.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(current_played_cards).at(i) = tempv; }
bios >> temp;other_played_cards.resize(temp);
for (unsigned int i = 0;i < temp;i++) { bios >> tempv;(other_played_cards).at(i) = tempv; }
bios >> tempv;current_num_cards_left=tempv;
bios >> tempv;other_num_cards_left = tempv;
bios >> tempv;jump = tempv!=0;
XNP2RAi(ai, current_hand, others_hand, last_greater,
last_action, last_9_actions, current_played_cards,
other_played_cards, current_num_cards_left, other_num_cards_left, jump, action);
for (auto i = 0;i < action.size();i++)
out_data[i] = action[i];
return action.size();
}
extern "C" __declspec(dllexport) void DeleteAi241120(const char* mode)
{
}
int main()
{
//auto a = CreateD21AiModule();
//D21Ai(a, 18, 8);
//DeleteD21AiModule(a);
//getchar();
auto a = CreateXNP2RAiModule();
VecInt current_hand;
VecInt others_hand;
VecInt last_greater;
VecInt last_action;
VecVecInt last_9_actions;
VecInt current_played_cards;
VecInt other_played_cards;
VecInt action;
int current_num_cards_left = 2;
int other_num_cards_left = 1;
int hand[] = { 0 };
std::size_t len = sizeof(hand) / sizeof(hand[0]);
for (size_t i = 0; i < len; i++)
{
current_hand.push_back(hand[i]);
}
int greater[] = { 48 };
len = sizeof(greater) / sizeof(greater[0]);
for (size_t i = 0; i < len; i++)
{
//last_greater.push_back(greater[i]);
}
last_action.push_back(41);
XNP2RAi(a, current_hand, others_hand, last_greater, last_action, last_9_actions, current_played_cards, other_played_cards, current_num_cards_left, other_num_cards_left, false, action);
return 0;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化