斗地主AI算法——第三章の数据处理
来源:互联网 发布:linux 查看文件夹时间 编辑:程序博客网 时间:2024/06/09 17:56
上一章我们定义了基本的数据结构,相信大家看到手牌类里面那么多出牌序列时一定会比较愤慨。。。
其实一开始写的时候我也是觉得很脑残,不过后续开发证明了这样的结构还是可以的,因为只要我封装了一层数据转换,接下来所有的算法策略都只用到2个成员变量,状态数据及手牌数量。特别便于调试、管理。那么接下来就写出类成员函数的实现方法
//手牌数据类class HandCardData{public://构造函数HandCardData::HandCardData(){}//析构函数virtual HandCardData::~HandCardData(){}public: //手牌序列——无花色,值域3~17 vector <int> value_nHandCardList; //手牌序列——状态记录,便于一些计算,值域为该index牌对应的数量0~4int value_aHandCardList[18] = { 0 }; //手牌序列——有花色,按照从大到小的排列 56,52:大王小王……4~0:红3黑3方3花3vector <int> color_nHandCardList; //手牌个数int nHandCardCount = 17 ; //玩家角色地位 0:地主 1:农民——地主下家 2:农民——地主上家int nGameRole = -1; //玩家座位ID int nOwnIndex = -1;//玩家要打出去的牌类型CardGroupData uctPutCardType;//要打出去的牌——无花色vector <int> value_nPutCardList;//要打出去的牌——有花色vector <int> color_nPutCardList;HandCardValue uctHandCardValue;public://要打出的牌序列清空void ClearPutCardList();//手牌排序,大牌靠前void SortAsList(vector <int> &arr);//出一张牌,返回操作是否合法bool PutOneCard(int value_nCard, int &clear_nCard);//出一组牌,返回操作是否合法bool PutCards();//通过有花色手牌获取无花色手牌(包含两种结构)void get_valueHandCardList();//初始化void Init();//输出所有成员变量,用于测试void PrintAll();};
void HandCardData::ClearPutCardList() 是把要出的牌打入出牌序列前清空现列表的操作,含有花色和无花色,顺便把之前出牌类型的值初始化一下
void HandCardData::ClearPutCardList(){color_nPutCardList.clear();value_nPutCardList.clear();uctPutCardType.cgType = cgERROR;uctPutCardType.nCount = 0;uctPutCardType.nMaxCard = -1;uctPutCardType.nValue = 0;return;}
void HandCardData::SortAsList(vector <int> & arr )简单的排序,这个就不说了
/*降序排序对比*/int cmp(int a, int b) { return a > b ? 1 : 0; }void HandCardData::SortAsList(vector <int> & arr ){sort(arr.begin(), arr.end(), cmp);return;}
void HandCardData::get_valueHandCardList()根据获取的有花色手牌序列转换成无花色手牌序列
我们的花色定义是按照从大到小的排列 56,52:大王小王……4~0:红3黑3方3花3 所以花色值/4再加上最小的牌3就是我们要的无花色权值
注:2对应的值是15 A对应的值是14
void HandCardData::get_valueHandCardList(){//清零value_nHandCardList.clear();memset(value_aHandCardList, 0,sizeof(value_aHandCardList));for (vector<int>::iterator iter = color_nHandCardList.begin(); iter != color_nHandCardList.end(); iter++){value_nHandCardList.push_back((*iter / 4)+3);value_aHandCardList[(*iter / 4) + 3]++;}}
void HandCardData::Init()手牌的初始化,主要用于根据获取的有花色手牌序列转换成无花色手牌序列,手牌序列排序, 计算出手牌个数。
void HandCardData::Init(){//根据花色手牌获取权值手牌get_valueHandCardList();//手牌 排序SortAsList(color_nHandCardList);SortAsList(value_nHandCardList);//当前手牌个数nHandCardCount = value_nHandCardList.size();}
void HandCardData::PrintAll()就是输出一些类成员变量,测试时使用。
void HandCardData::PrintAll(){cout << "color_nHandCardList:" << endl;for (vector<int>::iterator iter = color_nHandCardList.begin(); iter != color_nHandCardList.end(); iter++)cout << get_CardsName(*iter) << (iter == color_nHandCardList.end() - 1 ? '\n' : ',');cout << endl;/*cout << "value_nHandCardList:" << endl;for (vector<int>::iterator iter = value_nHandCardList.begin(); iter != value_nHandCardList.end(); iter++)cout << *iter << (iter == value_nHandCardList.end() - 1 ? '\n' : ',');cout << endl;cout << "value_aHandCardList:" << endl;for (int i = 0; i < 18; i++){cout << value_aHandCardList[i] << (i == 17 ? '\n' : ',');}cout << endl;cout << "nHandCardCount:" << nHandCardCount << endl;cout << endl;cout << "nGameRole:" << nGameRole << endl;cout << endl;*/}
接下来就说出牌的函数了
bool HandCardData::PutCards()出一组牌,返回操作是否合法
其函数实现为:遍历无花色手牌序列逐一映射到有花色手牌,然后将其加入有花色出牌数组里。说白了PutCards就是循环调用PutOneCard
bool HandCardData::PutCards(){for (vector<int>::iterator iter = value_nPutCardList.begin(); iter != value_nPutCardList.end(); iter++){int color_nCard = -1;if (PutOneCard(*iter, color_nCard)){color_nPutCardList.push_back(color_nCard);}else{return false;}}nHandCardCount -= value_nPutCardList.size();return true;}
重点就是出一张牌的实现方法了,bool PutOneCard(int value_nCard, int &clear_nCard);
这里我们需要做的事情可以分成两部分,第一部分,返回一个有花色的手牌以供PutCards加入有花色出牌序列,也就是引用的 int &clear_nCard
第二个就是处理我们的这几个数组(value状态数组、value列表数组、color列表数组)
bool HandCardData::PutOneCard(int value_nCard, int &color_nCard){bool ret = false;//value状态数组处理value_aHandCardList[value_nCard]--;if (value_aHandCardList[value_nCard] < 0){return false;}//value列表数组处理for (vector<int>::iterator iter = value_nHandCardList.begin(); iter != value_nHandCardList.end(); iter++){if (*iter == value_nCard){value_nHandCardList.erase(iter);ret = true;break;}}// color列表数组处理int k = (value_nCard - 3) * 4; //数值转换for (vector<int>::iterator iter = color_nHandCardList.begin(); iter != color_nHandCardList.end(); iter++){for (int i = k; i < k + 4; i++) {if (*iter == i){color_nCard = i;color_nHandCardList.erase(iter);return ret;}}}return false;}
至此,手牌类成员的数据处理函数就做完了,而全局类并没有什么需要我们处理的,因为那些都应该是我们从服务器获取的信息。
如果说这些都算是准备工作的话,那么接下来便是开始进入AI逻辑环节了,我们先从手牌权值的定义说起。
敬请关注下一章:斗地主AI算法——第四章の权值定义
- 斗地主AI算法——第三章の数据处理
- 斗地主AI算法——第二章の数据结构
- 斗地主AI算法——第一章の业务逻辑
- 斗地主AI算法——第四章の权值定义
- 斗地主AI算法——第五章の总值计算
- 斗地主AI算法——第六章の牌型判断
- 斗地主AI算法——第七章の被动出牌(1)
- 斗地主AI算法——第八章の被动出牌(2)
- 斗地主AI算法——第九章の被动出牌(3)
- 斗地主AI算法——第十章の被动出牌(4)
- 斗地主AI算法——第十一章の被动出牌(5)
- 斗地主AI算法——第十二章の主动出牌(1)
- 斗地主AI算法——第十三章の主动出牌(2)
- 斗地主AI算法——第十四章の主动出牌(3)
- 斗地主AI算法——第十五章の测试模块
- 斗地主AI算法——第十六章の样例分析
- 斗地主AI算法——第十七章の总结整理
- 斗地主AI算法实现
- 浅谈React的JSX语法(二)
- Centos7 搭建svn服务器
- sql解析顺序
- struts2开发文件上传下载的简单实例
- What is the use of having destructor as private?
- 斗地主AI算法——第三章の数据处理
- ibatis日志输出配置
- UICollectionView 适配 iPhone 7 Plus
- 信号
- Nutch爬去目录内容
- unit2.4管理系统中的简单分区和文件系统
- [2017][04][26]期中考分析
- 博客将搬家到博客园
- Bootstrap 常用知识点汇集