转载请标明出处:https://blog.csdn.net/sm9sun/article/details/70859884 文章出自:九日王朝
转载请标明出处:https://blog.csdn.net/sm9sun/article/details/70859884 文章出自:九日王朝
前面几章已经把整个斗地主AI算法工程完成的差不多了,接下来进入整合联调以及模拟测试模块。
测试模块主要任务就是代替服务器给出我们需要的数据。因为我们本来的计划是封装成类库通过服务器调用获取,其调用的接口无非就是叫分、被动出牌、主动出牌。
被动出牌和主动出牌我们已经完成,叫分我们已经实现了权值的获取,只需要在外面加一个区间划分即可:
-
/*
-
获取叫分函数
-
*/
-
-
int LandScore(GameSituation &clsGameSituation, HandCardData &clsHandCardData)
-
{
-
int SumValue =
0;
-
-
clsHandCardData.uctHandCardValue=get_HandCardValue(clsHandCardData);
-
-
SumValue = clsHandCardData.uctHandCardValue.SumValue;
-
-
cout <<
"SumValue is :" << SumValue <<
",";
-
-
cout <<
"NeedRound is :" << clsHandCardData.uctHandCardValue.NeedRound <<
endl;
-
-
if (SumValue<
10)
-
{
-
return
0;
-
}
-
else
if (SumValue <
15)
-
{
-
return
1;
-
}
-
else
if (SumValue <
20)
-
{
-
return
2;
-
}
-
else
-
{
-
return
3;
-
}
-
}
-
//洗牌
-
void InitCards(vector <int> &Cards)
-
{
-
//先清空Cards
-
Cards.clear();
-
-
vector <
int> tmpCards;
-
int i;
-
-
//大王56,小王52,没有53,54,55号牌
-
for (i =
0; i <
53; i++) {
-
tmpCards.push_back(i);
-
}
-
tmpCards.push_back(
56);
-
-
-
//顺序随机打乱
-
for (i = tmpCards.size(); i>
0; i--) {
-
srand(
unsigned(time(
NULL)));
-
// 选中的随机下标
-
int index = rand() % i;
-
Cards.push_back(tmpCards[index]);
-
tmpCards.erase(tmpCards.begin() + index);
-
}
-
-
}
-
//洗牌(指定牌型,用于测试)
-
void InitCards_Appoint(vector <int> &Cards)
-
{
-
//先清空Cards
-
Cards.clear();
-
-
/***********飞机与炸弹连续拆分逻辑测试**********/
-
-
Cards.push_back(
48); Cards.push_back(
50); Cards.push_back(
49);
-
Cards.push_back(
44); Cards.push_back(
47); Cards.push_back(
35);
-
Cards.push_back(
40); Cards.push_back(
46); Cards.push_back(
34);
-
Cards.push_back(
36); Cards.push_back(
45); Cards.push_back(
33);
-
Cards.push_back(
23); Cards.push_back(
43); Cards.push_back(
31);
-
Cards.push_back(
22); Cards.push_back(
42); Cards.push_back(
30);
-
Cards.push_back(
21); Cards.push_back(
41); Cards.push_back(
29);
-
Cards.push_back(
19); Cards.push_back(
39); Cards.push_back(
27);
-
Cards.push_back(
18); Cards.push_back(
38); Cards.push_back(
26);
-
Cards.push_back(
17); Cards.push_back(
37); Cards.push_back(
25);
-
Cards.push_back(
15); Cards.push_back(
32); Cards.push_back(
20);
-
Cards.push_back(
14); Cards.push_back(
28); Cards.push_back(
16);
-
Cards.push_back(
13); Cards.push_back(
24); Cards.push_back(
12);
-
Cards.push_back(
11); Cards.push_back(
3); Cards.push_back(
7);
-
Cards.push_back(
10); Cards.push_back(
2); Cards.push_back(
6);
-
Cards.push_back(
9); Cards.push_back(
1); Cards.push_back(
5);
-
Cards.push_back(
8); Cards.push_back(
0); Cards.push_back(
4);
-
Cards.push_back(
51); Cards.push_back(
52); Cards.push_back(
56);
-
-
-
}
-
//下发到三名玩家的手牌序列,此数据只用于测试,作为AI时不会获取
-
-
struct ALLCardsList
-
{
-
vector <
int> arrCardsList[
3];
-
};
-
//发牌
-
void SendCards(GameSituation & clsGameSituation, ALLCardsList &uctALLCardsList)
-
{
-
//洗牌
-
vector <
int> Cards;
-
InitCards(Cards);
-
//InitCards_Appoint(Cards);
-
int i, j, k;
-
j =
0;
-
for (k =
0; k <
17; k++) {
-
for (i =
0; i <
3; i++,j++)
-
{
-
uctALLCardsList.arrCardsList[i].push_back(Cards[j]);
-
}
-
}
-
-
//三张底牌
-
clsGameSituation.DiPai[
0] = Cards[j];
-
clsGameSituation.DiPai[
1] = Cards[j+
1];
-
clsGameSituation.DiPai[
2] = Cards[j+
2];
-
-
return;
-
}
-
GameSituation clsGameSituation;
-
-
ALLCardsList uctALLCardsList;
-
-
//发牌
-
SendCards(clsGameSituation, uctALLCardsList);
-
-
HandCardData arrHandCardData[
3];
-
-
arrHandCardData[
0].color_nHandCardList = uctALLCardsList.arrCardsList[
0];
-
arrHandCardData[
1].color_nHandCardList = uctALLCardsList.arrCardsList[
1];
-
arrHandCardData[
2].color_nHandCardList = uctALLCardsList.arrCardsList[
2];
-
-
for (
int i =
0; i <
3; i++)
-
{
-
arrHandCardData[i].Init();
-
arrHandCardData[i].nOwnIndex = i;
-
}
-
-
cout <<
"0号玩家牌为:" <<
endl;
-
arrHandCardData[
0].PrintAll();
-
cout <<
"1号玩家牌为:" <<
endl;
-
arrHandCardData[
1].PrintAll();
-
cout <<
"2号玩家牌为:" <<
endl;
-
arrHandCardData[
2].PrintAll();
-
-
cout <<
"底牌为:" <<
endl;
-
cout << get_CardsName(clsGameSituation.DiPai[
0]) <<
','
-
<< get_CardsName(clsGameSituation.DiPai[
1]) <<
','
-
<< get_CardsName(clsGameSituation.DiPai[
2]) <<
endl;
-
-
cout <<
endl;
发完牌后开始叫地主,调用LandScore函数返回其叫的分值,只有比当前已叫的分值更高才可以刷新叫地主记录。若无人叫地主重新开一局,否则将三张底牌给地主,同时刷新地主手牌,且将地主设置成将要出牌的玩家
-
for (
int i =
0; i <
3; i++)
-
{
-
int tmpLandScore = LandScore(clsGameSituation, arrHandCardData[i]);
-
if (tmpLandScore > clsGameSituation.nNowLandScore)
-
{
-
clsGameSituation.nNowLandScore = tmpLandScore;
-
clsGameSituation.nNowDiZhuID = i;
-
}
-
}
-
-
if (clsGameSituation.nNowDiZhuID ==
-1)
-
{
-
cout <<
"无人叫地主" <<
endl;
-
return;
-
}
-
-
cout << clsGameSituation.nNowDiZhuID <<
"号玩家是地主,叫分为:" << clsGameSituation.nNowLandScore <<
endl;
-
clsGameSituation.nDiZhuID=clsGameSituation.nNowDiZhuID;
-
clsGameSituation.nLandScore =clsGameSituation.nNowLandScore;
-
-
-
//将三张底牌给地主
-
arrHandCardData[clsGameSituation.nDiZhuID].color_nHandCardList.push_back(clsGameSituation.DiPai[
0]);
-
arrHandCardData[clsGameSituation.nDiZhuID].color_nHandCardList.push_back(clsGameSituation.DiPai[
1]);
-
arrHandCardData[clsGameSituation.nDiZhuID].color_nHandCardList.push_back(clsGameSituation.DiPai[
2]);
-
-
//地主手牌刷新
-
arrHandCardData[clsGameSituation.nDiZhuID].Init();
-
-
//出牌玩家ID
-
int indexID= clsGameSituation.nDiZhuID;
-
-
cout <<
endl;
-
-
-
cout <<
"0号玩家牌为:" <<
endl;
-
arrHandCardData[
0].PrintAll();
-
cout <<
"1号玩家牌为:" <<
endl;
-
arrHandCardData[
1].PrintAll();
-
cout <<
"2号玩家牌为:" <<
endl;
-
arrHandCardData[
2].PrintAll();
-
//当前控手玩家先为地主
-
clsGameSituation.nCardDroit = indexID;
-
while (!clsGameSituation.Over)
-
{
-
get_PutCardList_2(clsGameSituation, arrHandCardData[indexID]);
//获取出牌序列
-
arrHandCardData[indexID].PutCards();
-
cout << indexID <<
"号玩家出牌:" <<
endl;
-
for (
vector<
int>::iterator iter = arrHandCardData[indexID].color_nPutCardList.begin();
-
iter != arrHandCardData[indexID].color_nPutCardList.end(); iter++)
-
cout << get_CardsName(*iter) << (iter == arrHandCardData[indexID].color_nPutCardList.end() -
1 ?
'\n' :
',');
-
cout <<
endl;
-
-
if (arrHandCardData[indexID].nHandCardCount ==
0)
-
{
-
clsGameSituation.Over =
true;
-
-
if (indexID == clsGameSituation.nDiZhuID)
-
{
-
cout <<
"地主" << indexID <<
"号玩家获胜" <<
endl;
-
}
-
else
-
{
-
for (
int i =
0; i <
3; i++) {
-
if (i != clsGameSituation.nDiZhuID)
-
{
-
cout <<
"农民" << i <<
"号玩家获胜" <<
endl;
-
}
-
}
-
}
-
-
}
-
-
if (arrHandCardData[indexID].uctPutCardType.cgType != cgZERO)
-
{
-
clsGameSituation.nCardDroit = indexID;
-
clsGameSituation.uctNowCardGroup = arrHandCardData[indexID].uctPutCardType;
-
}
-
-
indexID ==
2 ? indexID =
0 : indexID++;
-
-
}
-
/*
-
2.0版本策略 根据场上形势决定当前预打出的手牌——分支处理
-
*/
-
void get_PutCardList_2(GameSituation &clsGameSituation, HandCardData &clsHandCardData)
-
{
-
if (clsGameSituation.nCardDroit == clsHandCardData.nOwnIndex)
-
{
-
get_PutCardList_2_unlimit(clsGameSituation, clsHandCardData);
-
}
-
else
-
{
-
get_PutCardList_2_limit(clsGameSituation, clsHandCardData);
-
}
-
return;
-
}
完成测试模块后,我们就可以调试程序了。
那么现在我们就可以愉快的玩耍了,下一章我们将观察几次对局情况进行样例的分析。
敬请关注下一章:斗地主AI算法——第十六章の样例分析