#include "game.h"
#include <iostream>
#include <algorithm>
//int game::getNextPlayerIndex(int nowPlayerIndex)const {
// auto nowPlayerIterator = this->m_calledPlayersIndex.find(nowPlayerIndex);
// if (nowPlayerIterator == this->m_calledPlayersIndex.end()) { //没找到当前玩家
// return -1;
// }
// auto nextPlayerIterator = nowPlayerIterator++;
// if (nextPlayerIterator == this->m_calledPlayersIndex.end()) {
// nextPlayerIterator = this->m_calledPlayersIndex.begin();
// }
// return *nextPlayerIterator;
//}
int game::getNextCalledPlayerIndex(const int nowPlayerIndex)const { //输入可以弃牌,输出还没弃牌的
if (this->m_calledPlayersIndex.size() < 1) //没有人
return -1;
if (this->m_calledPlayersIndex.size() == 1) //仅有一个返回这个
return *(this->m_calledPlayersIndex.begin());
//包含了nowPlayerIndex弃牌的情况
int nextCalledPlayerIndex = nowPlayerIndex;
do {
nextCalledPlayerIndex++;
if (nextCalledPlayerIndex >= maxNumOfPlayers)
nextCalledPlayerIndex -= maxNumOfPlayers;
} while (this->m_calledPlayersIndex.find(nextCalledPlayerIndex) == this->m_calledPlayersIndex.end()); //找不到一直循环
return nextCalledPlayerIndex;
}
int game::getPreCalledPlayerIndex(const int nowPlayerIndex) const{ //输入可以弃牌,输出还没弃牌的
if (this->m_calledPlayersIndex.size() < 1) //没有人
return -1;
if (this->m_calledPlayersIndex.size() == 1) //仅有一个返回这个
return *(this->m_calledPlayersIndex.begin());
int preCalledPlayerIndex = nowPlayerIndex;
do {
preCalledPlayerIndex--;
if (preCalledPlayerIndex < 0)
preCalledPlayerIndex += maxNumOfPlayers;
} while (this->m_calledPlayersIndex.find(preCalledPlayerIndex) == this->m_calledPlayersIndex.end()); //找不到一直循环
return preCalledPlayerIndex;
}
int game::getRoundBeginPlayerIndex() const {
//int beginPlayerIndex = this->m_dealer; //从dealer后一位开始
//do {
// beginPlayerIndex++; //先++
// if (beginPlayerIndex >= maxNumOfPlayers) //循环
// beginPlayerIndex -= maxNumOfPlayers;
// if (this->m_calledPlayersIndex.find(beginPlayerIndex) != this->m_calledPlayersIndex.end())
// return beginPlayerIndex; //找到了,退出
//} while (beginPlayerIndex != this->m_dealer); //找了一圈还没找到,错误
//return -1;
//重写了
return this->getNextCalledPlayerIndex(this->m_dealer); //直接获取dealer下一个
}
int game::getRoundEndPlayerIndex() const {
//重写了,dealer前一个有效玩家的后一个
int preCalledPlayerIndex = this->getPreCalledPlayerIndex(this->m_dealer);
return this->getNextCalledPlayerIndex(preCalledPlayerIndex);
}
//bool game::playersAction() { //要不要考虑把m_calledPlayersIndex换成引用或指针的set,感觉更合理一点?
// int nowPlayerIndex = this->getNextPlayerIndex(this->m_dealer);
// int endPlayerIndex = nowPlayerIndex;
// do {
// this->playerAction(nowPlayerIndex);
// nowPlayerIndex = this->getNextPlayerIndex(nowPlayerIndex);
// } while (nowPlayerIndex != endPlayerIndex);
// return true;
//}
//bool game::playerAction(const int playerIndex){
// player& nowPlayer = this->getPlayer(playerIndex);
// //以后要改
// int actionType = -1;
// cout << "玩家" << playerIndex << "行动:(1 raise, 2 check, 3 fold)" << endl;
// cin >> actionType;
// if (actionType == 1) {
// int raiseTo = -1;
// while (raiseTo < this->m_minBet) {
// cout << "raise to: (min " << this->m_minBet << ")" << endl;
// cin >> raiseTo;
// }
// nowPlayer.raise(raiseTo);
// }
// else if (actionType == 2) {
//
// }
// //nowPlayer.action();
// if (nowPlayer.hasFold()) {
// this->m_calledPlayersIndex.erase(playerIndex);
// }
// return true;
//}
void game::sendCardsToPlayers() {
for (auto nowPlayerIndex = this->m_calledPlayersIndex.begin(); nowPlayerIndex != this->m_calledPlayersIndex.end(); ++nowPlayerIndex) {
player& nowplayer = this->getPlayer(*nowPlayerIndex);
card card1 = this->m_cardHeap.getCard();
card card2 = this->m_cardHeap.getCard();
nowplayer.setHandCards(vector<card>{card1, card2});
}
}
void game::sendCardsToTable() {
if (this->m_round == PreFlop) { //翻前
this->sendCardsToPlayers();
}
else if (this->m_round == Flop) { //翻牌
this->m_commonCards[0] = this->m_cardHeap.getCard();
this->m_commonCards[1] = this->m_cardHeap.getCard();
this->m_commonCards[2] = this->m_cardHeap.getCard();
}
else if (this->m_round == Turn) { //转牌
this->m_commonCards[3] = this->m_cardHeap.getCard();
}
else if (this->m_round == River) { //河牌
this->m_commonCards[4] = this->m_cardHeap.getCard();
}
}
//四个当前玩家的动作,可以将玩家按键全部绑定至此
void game::nowPlayerRaise(const int raiseTo) {
player& nowPlayer = this->getPlayer(this->m_nowPlayerIndex);
nowPlayer.add(raiseTo);
//更新当前玩家和结束玩家,因为raise了,必然要走一轮,所以不判断是否进入下一轮
//this->afterPlayerAction(); //所以本行删掉
this->nowPlayerActionComplete(); //当前玩家结束行动渲染
this->m_endPlayerIndex = this->m_nowPlayerIndex;
this->m_nowPlayerIndex = this->getNextCalledPlayerIndex(this->m_nowPlayerIndex); //下一位玩家
this->nowPlayerRender(); //渲染下一位玩家的界面
}
void game::nowPlayerCall() {
player& nowPlayer = this->getPlayer(this->m_nowPlayerIndex);
nowPlayer.add(this->m_minBet); //就是玩家加到最小bet
this->afterPlayerAction();
}
void game::nowPlayerCheck() {
//player& nowPlayer = this->getPlayer(this->m_nowPlayerIndex);
//nowPlayer.add(0); //加到0,可以删了
this->afterPlayerAction();
}
void game::nowPlayerFold() {
player& nowPlayer = this->getPlayer(this->m_nowPlayerIndex);
nowPlayer.fold();
this->m_calledPlayersIndex.erase(this->m_nowPlayerIndex); //从已call集合中删除
this->afterPlayerAction();
}
void game::afterPlayerAction(){ //玩家行动后
this->nowPlayerActionComplete(); //当前玩家结束行动渲染
if (this->m_nowPlayerIndex == this->m_endPlayerIndex) { //本轮结束
this->finishThisRound(); //本轮结束相关渲染
this->updatePots(); //更新底池与边池
this->nextRound(); //下一轮
}
else {
this->m_nowPlayerIndex = this->getNextCalledPlayerIndex(this->m_nowPlayerIndex); //下一位玩家
this->nowPlayerRender(); //渲染下一位玩家的界面
}
}
void game::calCardTypeAndPointForAll() {
for (auto playerIndexIterator = this->m_calledPlayersIndex.begin(); playerIndexIterator != this->m_calledPlayersIndex.end(); ++playerIndexIterator) {
int playerIndex = *playerIndexIterator;
calCardTypeAndPointForPlayer(playerIndex);
}
}
void game::calCardTypeAndPointForPlayer(const int playerIndex) {
player& player = this->getPlayer(playerIndex);
vector<card> const& handCards = player.getHandCards();
vector<card> const& commonCards = this->getCommonCards();
card combine[5];
for (int i = 0; i < 21; ++i) {
for (int j = 0; j < 5; ++j) {
//获取组合
if (combineMap[i][j] >= 5)
combine[j] = handCards[combineMap[i][j] - 5];
else
combine[j] = commonCards[combineMap[i][j]];
//计算
cardTypeAndPoint nowCardTypeAndPoint = cardTypeAndPoint::calTypeAndPoint(combine);
if (nowCardTypeAndPoint > player.getCardTypeAndPoint())
player.setCardTypeAndPoint(nowCardTypeAndPoint);
}
}
}
void game::nextRound() {
if (this->m_calledPlayersIndex.size()<=1||this->m_round >= End) { //没人了或是最后一轮进行完了,结算
this->settle();
//然后渲染结束本局画面,包括每位玩家的再次开始键和show牌、牌型,再次开始绑定至下一局游戏
return;
}
this->m_round = gameRound(this->m_round + 1);
this->sendCardsToTable();
this->m_nowPlayerIndex = this->getRoundBeginPlayerIndex(); //这一轮开始的玩家,用这个是因为dealer可能弃牌了
this->m_endPlayerIndex = this->getRoundEndPlayerIndex(); //这一轮结束的玩家
if (this->m_round == PreFlop) { //翻前下盲注
this->getPlayer(this->m_nowPlayerIndex).add(smallBind); //小盲
this->m_nowPlayerIndex = this->getNextCalledPlayerIndex(this->m_nowPlayerIndex);
this->getPlayer(this->m_nowPlayerIndex).add(bigBind); //大盲
this->m_endPlayerIndex = this->m_nowPlayerIndex; //第一轮到大盲结束 !!!!!有没有问题?
this->m_minBet = bigBind;
this->m_nowPlayerIndex = this->getNextCalledPlayerIndex(this->m_now