Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef PLAYER_H_INCLUDED
- #define PLAYER_H_INCLUDED
- class player
- {
- public:
- //player specifics
- std::string name;
- sf::IPAddress ip;
- sf::SocketTCP Client;
- sf::SocketTCP Client2; //only for stop commands
- bool ai;
- int pid;
- gamesettings settings;
- // hand specifics
- std::vector<Tile> menzen;
- std::vector<std::vector<Tile> > open; //render main vector backwards, inside vectors normally
- std::vector<Tile> discards;
- std::vector<Tile> waits;
- std::vector<Tile> furitile;
- Tile tsumopai;
- Tile win_pai;
- int won_from;
- int riichi;
- int kans;
- int won; //0=not won, 1=ron, 2=tsumo, 3=chakan, 4=rinshan
- bool openriichi;
- bool rtilepon; //check to turn the next discard if riichi-discard was called
- bool nodraw; //important for pons/chis etc.
- bool nokandraw;
- bool stopbutton; //if this is true, immediatly stop sending buttons!
- SYSTEMTIME ST;
- bool riichifuri;
- bool none_bt, riichi_bt, oriichi_bt, tsumo_bt, ron_bt, chi_bt, pon_bt, kan_bt, reshuffle_bt;
- int wind;
- g3::big_int pts;
- player()
- {
- name="Nuhp";
- ai=0;
- pid=0;
- won_from=0;
- riichi=0;
- kans=0;
- won=0;
- openriichi = 0;
- rtilepon=0;
- nodraw=0;
- nokandraw=0;
- stopbutton=0;
- wind=ton;
- pts=25000;
- riichifuri=false;
- none_bt=false;
- riichi_bt=false;
- oriichi_bt=false;
- tsumo_bt=false;
- ron_bt=false;
- chi_bt=false;
- pon_bt=false;
- kan_bt=false;
- reshuffle_bt=false;
- }
- std::string update_st()
- {
- std::stringstream sstr;
- GetSystemTime(&ST);
- sstr << "[" << ST.wHour<< ":"<<ST.wMinute<<":"<<ST.wSecond<<":"<< ST.wMilliseconds<<"] ";
- return sstr.str();
- }
- void send_buttons()
- {
- if(ip=="255.255.255.255")
- {
- return;
- }
- sf::Packet pack;
- sf::Int8 request = 3;
- pack << request;
- pack << none_bt << riichi_bt << oriichi_bt << tsumo_bt << ron_bt << chi_bt << pon_bt << kan_bt << reshuffle_bt;
- Client.Send(pack);
- network_stream << std::endl << update_st() << "Sent Request-ID 3 to " << ip << " with " << pack.GetDataSize() << "B" <<std::endl;
- pack.Clear();
- }
- void send_player_update(sf::SocketTCP& TClient, sf::IPAddress& tip)
- {
- sf::Packet pack;
- sf::Int8 request = 1;
- pack << request;
- sf::Int8 men_size = menzen.size();
- sf::Int8 open_size = open.size();
- sf::Int8 twind=wind;
- pack << twind;
- pack << men_size;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- pack << menzen[a];
- }
- pack << tsumopai;
- pack << open_size;
- for(unsigned int a=0; a!=open.size(); a++)
- {
- sf::Int8 open2_size = open[a].size();
- pack << open2_size;
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- pack << open[a][b];
- }
- }
- sf::Int8 disc_size = discards.size();
- pack << disc_size;
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- pack << discards[a];
- }
- pack << riichi;
- pack << pts;
- if(TClient.Send(pack)==sf::Socket::Done)
- {
- network_stream << std::endl << update_st() << "Sent Request-ID 1 to " << tip << " with " << pack.GetDataSize() << "B" <<std::endl;
- }
- else
- {
- network_stream << std::endl << update_st() << "Sending of Request ID 1 to " << tip << " failed!" <<std::endl;
- }
- pack.Clear();
- }
- void send_other_player_update(sf::SocketTCP& TClient, sf::IPAddress& tip, int mode=0)
- {
- sf::Packet pack;
- sf::Int8 request = 4;
- pack << request;
- sf::Int8 men_size = menzen.size();
- sf::Int8 open_size = open.size();
- sf::Int8 twind=wind;
- pack << twind;
- pack << men_size;
- std::vector<Tile> tmenzen=menzen;
- for(unsigned int a=0; a!=tmenzen.size(); a++)
- {
- if(!openriichi&&mode==0)
- {
- tmenzen[a]=Tile(m,1);
- }
- pack << tmenzen[a];
- }
- Tile ttsumopai=tsumopai;
- if(ttsumopai!=deftile&&!openriichi&&mode==0)
- {
- ttsumopai=Tile(m,1);
- }
- pack << ttsumopai;
- pack << open_size;
- for(unsigned int a=0; a!=open.size(); a++)
- {
- sf::Int8 open2_size = open[a].size();
- pack << open2_size;
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- pack << open[a][b];
- }
- }
- sf::Int8 disc_size = discards.size();
- pack << disc_size;
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- pack << discards[a];
- }
- pack << riichi;
- pack << pts;
- TClient.Send(pack);
- network_stream << std::endl << update_st() << "Sent Request-ID 4 to " << tip << " with " << pack.GetDataSize() << "B" <<std::endl;
- pack.Clear();
- }
- int receive_clickpos(int mode=0)
- {
- if(ai&&tsumopai!=deftile)
- {
- sf::Sleep(0.500);
- return -1;
- }
- else if(ai)
- {
- sf::Sleep(0.500);
- return 0;
- }
- if(stopbutton)
- {
- return 0;
- }
- sf::Packet pack;
- sf::Int8 request = 0;
- pack << request;
- sf::Int8 tmode=mode;
- pack << tmode;
- Client.Send(pack);
- network_stream << std::endl << update_st() << "Sent Request-ID 0 to " << ip << " with " << pack.GetDataSize() << "B" <<std::endl;
- pack.Clear();
- sf::Packet pack2;
- Client.Receive(pack2);
- sf::Int32 tclickpos;
- pack2 >> tclickpos;
- pack2.Clear();
- int clickpos=tclickpos;
- network_stream << std::endl << update_st() << "Received Clickpos " << clickpos << " from " << ip << std::endl;
- return clickpos;
- }
- void request_udpclickpos(int pos, Tile& kantile)
- {
- sf::Packet pack;
- sf::Int8 request = 9;
- pack << request;
- sf::Int8 tpos=pos;
- pack << tpos;
- pack << kantile;
- Client.Send(pack);
- network_stream << std::endl << update_st() << "Sent Request-ID 9 to " << ip << " with " << pack.GetDataSize() << "B" <<std::endl;
- pack.Clear();
- }
- void darken_hand(std::vector<int>& works)
- {
- tsumopai.highlight=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- menzen[a].highlight=0;
- }
- for(unsigned int a=0; a!=works.size(); a++)
- {
- if(works[a]==-1)
- {
- tsumopai.highlight=1;
- }
- else
- {
- menzen[works[a]].highlight=1;
- }
- }
- }
- void darken_hand()
- {
- tsumopai.highlight=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- menzen[a].highlight=0;
- }
- }
- void darken_hand(std::vector<std::vector<int> >& works)
- {
- tsumopai.highlight=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- menzen[a].highlight=0;
- }
- for(unsigned int a=0; a!=works.size(); a++)
- {
- for(unsigned int b=0; b!=works[a].size(); b++)
- {
- if(works[a][b]==-1)
- {
- tsumopai.highlight=1;
- }
- else
- {
- menzen[works[a][b]].highlight=1;
- }
- }
- }
- }
- void undarken_hand()
- {
- tsumopai.highlight=1;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- menzen[a].highlight=1;
- }
- }
- void sort_hand()
- {
- std::sort(menzen.begin(),menzen.end());
- }
- void walldraw(std::vector<Tile>& wall)
- {
- for(unsigned int a=0; a!=wall.size(); a++)
- {
- if(wall[a]!=deftile)
- {
- tsumopai=wall[a];
- wall[a]--;
- break;
- }
- }
- }
- void init_hand(std::vector<Tile>& wall)
- {
- int count=0;
- for(unsigned int a=0; count!=13; a++)
- {
- if(wall[a]!=deftile)
- {
- menzen.push_back(wall[a]);
- count++;
- wall[a]--;
- }
- }
- sort_hand();
- }
- void kandraw(std::vector<Tile>& wall)
- {
- int pos=0;
- if(wall[134]!=deftile)
- {
- pos = 134;
- }
- else if(wall[135]!=deftile)
- {
- pos = 135;
- }
- else if(wall[132]!=deftile)
- {
- pos = 132;
- }
- else if(wall[133]!=deftile)
- {
- pos=133;
- }
- tsumopai=wall[pos];
- wall[pos]--;
- }
- void flip_dora(std::vector<Tile>& wall)
- {
- if(wall[124].visible)
- {
- wall[122].visible=1;
- }
- else if(wall[126].visible)
- {
- wall[124].visible=1;
- }
- else if(wall[128].visible)
- {
- wall[126].visible=1;
- }
- else if(wall[130].visible)
- {
- wall[128].visible=1;
- }
- else
- {
- wall[130].visible=1;
- }
- }
- void discard(const int& pos)
- {
- if(pos==-1||pos==tsumopai_tile)
- {
- discards.push_back(tsumopai);
- tsumopai--;
- return;
- }
- else
- {
- if(rtilepon)
- {
- menzen[pos].position=1;
- rtilepon=false;
- }
- discards.push_back(menzen[pos]);
- menzen.erase(menzen.begin()+pos);
- if(tsumopai!=deftile)
- {
- menzen.push_back(tsumopai);
- }
- tsumopai--;
- sort_hand();
- }
- }
- void rdiscard(const int& pos)
- {
- if(pos==-1||pos==tsumopai_tile)
- {
- tsumopai.position=1;
- discards.push_back(tsumopai);
- tsumopai--;
- return;
- }
- else
- {
- menzen[pos].position=1;
- discards.push_back(menzen[pos]);
- menzen.erase(menzen.begin()+pos);
- if(tsumopai!=deftile)
- {
- menzen.push_back(tsumopai);
- }
- tsumopai--;
- sort_hand();
- }
- }
- int relpos(const player& p2)
- {
- if(wind==ton)
- {
- if(p2.wind==nan2)
- {
- return 1;
- }
- if(p2.wind==shaa)
- {
- return 2;
- }
- if(p2.wind==pei)
- {
- return 3;
- }
- }
- else if(wind==nan2)
- {
- if(p2.wind==ton)
- {
- return 3;
- }
- if(p2.wind==shaa)
- {
- return 1;
- }
- if(p2.wind==pei)
- {
- return 2;
- }
- }
- else if(wind==shaa)
- {
- if(p2.wind==nan2)
- {
- return 3;
- }
- if(p2.wind==ton)
- {
- return 2;
- }
- if(p2.wind==pei)
- {
- return 1;
- }
- }
- else if(wind==pei)
- {
- if(p2.wind==nan2)
- {
- return 2;
- }
- if(p2.wind==shaa)
- {
- return 3;
- }
- if(p2.wind==ton)
- {
- return 1;
- }
- }
- return 0;
- }
- void ponchi(player& p2, int pos1, int pos2)
- {
- Tile called=p2.discards[p2.discards.size()-1];
- if(called.position)
- {
- p2.rtilepon=true;
- }
- called.position=1;
- p2.discards[p2.discards.size()-1].norend=1;
- std::vector<Tile> tmp;
- if(relpos(p2)==1)
- {
- tmp.push_back(called);
- tmp.push_back(menzen[pos2]);
- tmp.push_back(menzen[pos1]);
- }
- if(relpos(p2)==2)
- {
- tmp.push_back(menzen[pos2]);
- tmp.push_back(called);
- tmp.push_back(menzen[pos1]);
- }
- if(relpos(p2)==3)
- {
- tmp.push_back(menzen[pos2]);
- tmp.push_back(menzen[pos1]);
- tmp.push_back(called);
- }
- open.push_back(tmp);
- menzen.erase(menzen.begin()+pos2);
- menzen.erase(menzen.begin()+pos1);
- }
- void kan(int pos1, int pos2,int pos3, int pos4)
- {
- std::vector<Tile> tmp;
- std::vector<int> postmp;
- postmp.push_back(pos1);
- postmp.push_back(pos2);
- postmp.push_back(pos3);
- postmp.push_back(pos4);
- std::sort(postmp.begin(),postmp.end());
- pos1=postmp[0];
- pos2=postmp[1];
- pos3=postmp[2];
- pos4=postmp[3];
- if(pos1==-1)
- {
- pos1=postmp[1];
- pos2=postmp[2];
- pos3=postmp[3];
- pos4=-1;
- }
- tmp.push_back(menzen[pos1]);
- tmp.push_back(menzen[pos2]);
- tmp.push_back(menzen[pos3]);
- if(pos4==-1)
- {
- tmp.push_back(tsumopai);
- tsumopai--;
- }
- else
- {
- tmp.push_back(menzen[pos4]);
- menzen.erase(menzen.begin()+pos4);
- }
- menzen.erase(menzen.begin()+pos3);
- menzen.erase(menzen.begin()+pos2);
- menzen.erase(menzen.begin()+pos1);
- tmp[0].visible=false;
- tmp[3].visible=false;
- open.push_back(tmp);
- kans++;
- if(tsumopai!=deftile)
- {
- menzen.push_back(tsumopai);
- tsumopai--;
- }
- sort_hand();
- }
- void latekan(const int& pos)
- {
- if(pos==-1)
- {
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(std::count(open[a].begin(),open[a].end(),tsumopai))
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- if(open[a][b].position)
- {
- Tile inserting=tsumopai;
- inserting.position=1;
- open[a].insert(open[a].begin()+b,inserting);
- break;
- }
- }
- break;
- }
- }
- tsumopai--;
- }
- else
- {
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(std::count(open[a].begin(),open[a].end(),menzen[pos]))
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- if(open[a][b].position)
- {
- Tile inserting=menzen[pos];
- inserting.position=1;
- open[a].insert(open[a].begin()+b,inserting);
- break;
- }
- }
- break;
- }
- }
- menzen.erase(menzen.begin()+pos);
- menzen.push_back(tsumopai);
- tsumopai--;
- sort_hand();
- }
- kans++;
- sort_hand();
- }
- void daiminkan(player& p2, const int& pos1, const int& pos2, const int& pos3)
- {
- Tile called=p2.discards[p2.discards.size()-1];
- if(called.position)
- {
- p2.rtilepon=true;
- }
- called.position=1;
- p2.discards[p2.discards.size()-1];
- std::vector<Tile> tmp;
- if(relpos(p2)==1)
- {
- tmp.push_back(called);
- tmp.push_back(menzen[pos3]);
- tmp.push_back(menzen[pos2]);
- tmp.push_back(menzen[pos1]);
- }
- if(relpos(p2)==2)
- {
- tmp.push_back(menzen[pos3]);
- tmp.push_back(menzen[pos2]);
- tmp.push_back(called);
- tmp.push_back(menzen[pos1]);
- }
- if(relpos(p2)==3)
- {
- tmp.push_back(menzen[pos3]);
- tmp.push_back(menzen[pos2]);
- tmp.push_back(menzen[pos1]);
- tmp.push_back(called);
- }
- open.push_back(tmp);
- menzen.erase(menzen.begin()+pos3);
- menzen.erase(menzen.begin()+pos2);
- menzen.erase(menzen.begin()+pos1);
- kans++;
- }
- int count_dora(const std::vector<Tile>& wall)
- {
- int dorano=0;
- std::vector<Tile> doras;
- for(unsigned int a=0; a!=wall.size(); a++)
- {
- if(wall[a].visible)
- {
- doras.push_back(wall[a]+1);
- }
- }
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=0; b!=doras.size(); b++)
- {
- if(menzen[a]==doras[b])
- {
- dorano++;
- }
- }
- }
- for(unsigned int a=0; a!=open.size(); a++)
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- for(unsigned int c=0; c!=doras.size(); c++)
- {
- if(open[a][b]==doras[c])
- {
- dorano++;
- }
- }
- }
- }
- return dorano;
- }
- int count_udora(const std::vector<Tile>& wall, const Tile& wtile)
- {
- int dorano=0;
- //uradora
- std::vector<Tile> doras;
- for(unsigned int a=0; a!=wall.size(); a++)
- {
- if(wall[a].visible)
- {
- doras.push_back(wall[a+1]+1);
- }
- }
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=0; b!=doras.size(); b++)
- {
- if(menzen[a]==doras[b])
- {
- dorano++;
- }
- }
- }
- for(unsigned int a=0; a!=open.size(); a++)
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- for(unsigned int c=0; c!=doras.size(); c++)
- {
- if(open[a][b]==doras[c])
- {
- dorano++;
- }
- }
- }
- }
- for(unsigned int a=0; a!=doras.size(); a++)
- {
- if(doras[a]==wtile)
- {
- dorano++;
- break;
- }
- }
- return dorano;
- }
- unsigned int get_han(const int& rwind, const int& wturn, const int& tileno, const Tile& wtile, const int& winmode, const handconfig& config, const int& fu, int dorano, int akadorano, int uradorano, int& yakuman_only)
- {
- yakuman_only=false;
- bool ippatsu=false;
- int poscount=0;
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- if(discards[a].position)
- {
- poscount++;
- if(a==discards.size()-1)
- {
- ippatsu=true;
- }
- }
- }
- if(poscount>1)
- {
- ippatsu=false;
- }
- int hantotal=0;
- int yakuman=0;
- int add_yakuman=0;
- std::vector<Tile> tmenzen=menzen; //menzen+wtile
- tmenzen.push_back(wtile);
- for(unsigned int a=0; a!=settings.yakulist.size(); a++)
- {
- if(settings.yakulist[a].check_true(tmenzen,open, rwind, wind, riichi, wturn, tileno, wtile, winmode, config,fu,openriichi,ippatsu))
- {
- if(check_(open))
- {
- hantotal+=settings.yakulist[a].openhan;
- if(settings.yakulist[a].openhan>=26)
- {
- add_yakuman+=settings.yakulist[a].openhan/13;
- }
- else if(settings.yakulist[a].openhan>=13)
- {
- yakuman++;
- }
- }
- else
- {
- hantotal+=settings.yakulist[a].han;
- if(settings.yakulist[a].han>=26)
- {
- add_yakuman+=settings.yakulist[a].han/13;
- }
- else if(settings.yakulist[a].han>=13)
- {
- yakuman++;
- }
- }
- }
- }
- hantotal+=dorano;
- hantotal+=akadorano;
- hantotal+=uradorano;
- if(!settings.han_max)
- {
- settings.han_max=hantotal;
- }
- if(settings.aotenjou)
- {
- return std::max(hantotal,settings.han_max);
- }
- if(hantotal>=13&&!yakuman)
- {
- return std::max(hantotal,settings.han_max);
- }
- if(!yakuman)
- {
- return hantotal;
- }
- if(settings.yakuman_mode==0&&add_yakuman)
- {
- yakuman_only=true;
- return (yakuman+add_yakuman)*13;
- }
- if(settings.yakuman_mode==0&&yakuman)
- {
- yakuman_only=true;
- return yakuman*13;
- }
- if(settings.yakuman_mode==1&&add_yakuman)
- {
- yakuman_only=true;
- return 26;
- }
- if(settings.yakuman_mode==1&&yakuman)
- {
- yakuman_only=true;
- return 13;
- }
- if(settings.yakuman_mode==2&&yakuman)
- {
- yakuman_only=true;
- return yakuman*13;
- }
- if(settings.yakuman_mode==3&&yakuman)
- {
- yakuman_only=true;
- return 13;
- }
- return 0;
- }
- int get_fu(const handconfig& config=handconfig(), const int& rwind=ton, const int& winmode=0, const Tile& wtile=deftile)
- {
- //check Chiitoitsu
- if(config.size()==7)
- {
- return 25;
- }
- //Fuutei
- int futotal=20;
- //Menzen Ron / Min Tsumo
- if(winmode==0&&!check_(open))
- {
- futotal+=10;
- }
- if(winmode==1&&check_(open))
- {
- futotal+=2;
- }
- int ank=0;
- //Mentsu
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(open[a].size()==4&&open[a][0].value>1&&open[a][0].value<9&&open[a][0].visible==false)
- {
- futotal+=16;
- ank++;
- }
- else if(open[a].size()==4&&(open[a][0].value==1||open[a][0].value>8)&&open[a][0].visible==false)
- {
- futotal+=32;
- ank++;
- }
- else if(open[a].size()==4&&open[a][0].value>1&&open[a][0].value<9)
- {
- futotal+=8;
- }
- else if(open[a].size()==4&&(open[a][0].value==1||open[a][0].value>8))
- {
- futotal+=16;
- }
- else if(m_type(open[a])==2&&open[a][0].value>1&&open[a][0].value<9)
- {
- futotal+=2;
- }
- else if(m_type(open[a])==2&&(open[a][0].value==1||open[a][0].value>8))
- {
- futotal +=4;
- }
- }
- for(unsigned int a=0; a!=config.size(); a++)
- {
- if(m_type(config[a])==2&&config[a][0].value>1&&config[a][0].value<9)
- {
- if(config[a][0]==wtile)
- {
- int roncnt=0;
- for(unsigned int c=0; c!=config.size(); c++)
- {
- for(unsigned int d=0; d!=config[c].size(); d++)
- {
- if(config[c][d]==wtile)
- {
- roncnt++;
- }
- }
- }
- if(roncnt<4)
- {
- futotal+=2;
- }
- else
- {
- futotal+=4;
- ank++;
- }
- }
- else
- {
- futotal+=4;
- ank++;
- }
- }
- else if(m_type(config[a])==2&&(config[a][0].value==1||config[a][0].value>8))
- {
- if(config[a][0]==wtile)
- {
- int roncnt=0;
- for(unsigned int c=0; c!=config.size(); c++)
- {
- for(unsigned int d=0; d!=config[c].size(); d++)
- {
- if(config[c][d]==wtile)
- {
- roncnt++;
- }
- }
- }
- if(roncnt<4)
- {
- futotal+=4;
- }
- else
- {
- futotal+=8;
- ank++;
- }
- }
- else
- {
- futotal+=8;
- ank++;
- }
- }
- else if(m_type(config[a])==3&&config[a][0]==rwind&&rwind==wind)
- {
- futotal +=4;
- }
- else if(m_type(config[a])==3&&(config[a][0].value==haku||config[a][0].value==hatsu||config[a][0].value==chun||config[a][0].value==rwind||config[a][0].value==wind))
- {
- futotal+=2;
- }
- }
- //checking possible waits
- bool ryanmen(false),shanpon(false),tanki(false),penchan(false), kanchan(false);
- for(unsigned int a=0; a!=config.size(); a++)
- {
- for(unsigned int b=0; b!=config[a].size(); b++)
- {
- if(config[a][b]!=wtile)
- {
- continue;
- }
- std::vector<Tile> temp = config[a];
- temp.erase(temp.begin()+b);
- if(temp.size()==1)
- {
- tanki=true;
- break;
- }
- else if(temp[1]==temp[0]+1&&temp[0]!=1&&temp[0]!=8)
- {
- ryanmen=true;
- break;
- }
- else if(temp[1]==temp[0]+1&&(temp[0]==1||temp[0]==8))
- {
- penchan=true;
- break;
- }
- else if(temp[1]==temp[0]+2)
- {
- kanchan=true;
- break;
- }
- else if(temp[1]==temp[0])
- {
- shanpon=true;
- break;
- }
- }
- }
- //prioritize han from yaku (sanankou,pinfu) over fu from waits
- if((futotal==20||(winmode==0&&futotal==30))&&!check_(open)&&ryanmen)
- {
- return futotal;
- }
- else if(ank>=3&&tanki&&ryanmen)
- {
- return futotal;
- }
- else if(tanki||penchan||kanchan)
- {
- futotal+=2;
- }
- //Kuipinfu
- if(futotal<=20&&check_(open))
- {
- return 30;
- }
- return futotal;
- }
- g3::big_int get_payment(const player& p2, const int& rwind, const int& wturn, const int& tileno, const Tile& wtile, const int& winmode, const int& dorano, const int& udorano, std::vector<std::string>& yakunames, std::vector<int>& hanvalues, std::string& totals, bool wareme)
- {
- bool ron;
- if(winmode==1||winmode==3)
- {
- ron=true;
- }
- else
- {
- ron=false;
- }
- bool ippatsu=false;
- int poscount=0;
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- if(discards[a].position)
- {
- poscount++;
- if(a==discards.size()-1)
- {
- ippatsu=true;
- }
- }
- }
- if(poscount>1)
- {
- ippatsu=false;
- }
- std::vector<Tile> tmenzen=menzen;
- tmenzen.push_back(wtile);
- std::vector<handconfig> posconf = get_config(tmenzen);
- std::vector<g3::big_int> pospay(posconf.size(),0);
- std::vector<int> poshan(posconf.size(),0);
- std::vector<g3::big_int> posfu(posconf.size(),0);
- std::vector<int> yakuman_only(posconf.size(),0);
- int akadora=0;
- if(wtile.aka)
- {
- akadora++;
- }
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a].aka)
- {
- akadora++;
- }
- }
- for(unsigned int a=0; a!=open.size(); a++)
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- if(open[a][b].aka)
- {
- akadora++;
- }
- }
- }
- for(unsigned int a=0; a!=posconf.size(); a++)
- {
- g3::big_int payment;
- g3::big_int fu=get_fu(posconf[a], rwind, winmode, wtile);
- int multiplier;
- if(wind==ton&&!ron)
- {
- multiplier=2;
- }
- else if(wind==ton&&ron)
- {
- multiplier=6;
- }
- else if(!ron&&p2.wind!=ton)
- {
- multiplier=1;
- }
- else if(!ron&&p2.wind==ton)
- {
- multiplier=2;
- }
- else if(ron)
- {
- multiplier=4;
- }
- if(fu!=25)
- {
- fu.round_fu();
- }
- int t_uradorano=0;
- if(riichi&&(settings.uradora==1||settings.uradora==3))
- {
- t_uradorano=udorano;
- }
- else if(!riichi&&(settings.uradora==2||settings.uradora==3))
- {
- t_uradorano=udorano;
- }
- int han = get_han(rwind, wturn, tileno, wtile, winmode, posconf[a],fu, dorano, akadora, t_uradorano,yakuman_only[a]);
- payment=g3::Get2powX(han+2);
- payment *= fu;
- //limits
- if(!settings.aotenjou)
- {
- if(han<6&&payment>2000)
- {
- payment=2000;
- }
- else if(han==6||han==7)
- {
- payment=3000;
- }
- else if(han==8||han==9||han==10)
- {
- payment=4000;
- }
- else if(han==11||han==12)
- {
- payment=6000;
- }
- else if(han>=13)
- {
- payment=8000;
- payment*=(han/13);
- }
- }
- payment *= multiplier;
- if(wareme)
- {
- payment *=settings.wareme_multi;
- }
- payment.round_100();
- pospay[a]=payment;
- posfu[a]=fu;
- poshan[a]=han;
- }
- int highest=0;
- int highpos=0;
- for(unsigned int a=0; a!=pospay.size(); a++)
- {
- if(pospay[a]>highest)
- {
- highest=pospay[a];
- highpos=a;
- }
- }
- std::stringstream sstr;
- sstr << poshan[highpos] << " Han ";
- if(!settings.aotenjou&&poshan[highpos]==5)
- {
- sstr << ": Mangan";
- }
- else if(!settings.aotenjou&&(poshan[highpos]==6||poshan[highpos]==7))
- {
- sstr << ": Haneman";
- }
- else if(!settings.aotenjou&&(poshan[highpos]==8||poshan[highpos]==9||poshan[highpos]==10))
- {
- sstr << ": Baiman";
- }
- else if(!settings.aotenjou&&(poshan[highpos]==11||poshan[highpos]==12))
- {
- sstr << ": Sanbaiman";
- }
- else if(!settings.aotenjou&&poshan[highpos]>=13)
- {
- sstr << ": Kazoe Yakuman";
- }
- else
- {
- sstr << posfu[highpos] << " Fu";
- }
- if(yakuman_only[highpos])
- {
- sstr.clear();
- int yakuman_number = poshan[highpos]/13;
- switch(yakuman_number)
- {
- case 2: sstr << "Double ";break;
- case 3: sstr << "Triple ";break;
- case 4: sstr << "Quadruple ";break;
- case 5: sstr << "Quintuple ";break;
- case 6: sstr << "Sextuple ";break;
- case 7: sstr << "Septuple ";break;
- case 8: sstr << "Octuple ";break;
- case 9: sstr << "Nonuple ";break;
- default: break;
- }
- sstr << "Yakuman";
- }
- totals = sstr.str();
- if(yakunames.size()!=0)
- {
- return pospay[highpos];
- }
- if(dorano&&!yakuman_only[highpos])
- {
- yakunames.push_back("Dora");
- hanvalues.push_back(dorano);
- }
- if(akadora&&!yakuman_only[highpos])
- {
- yakunames.push_back("Akadora");
- hanvalues.push_back(akadora);
- }
- if(udorano&&riichi&&!yakuman_only[highpos])
- {
- yakunames.push_back("Uradora");
- hanvalues.push_back(udorano);
- }
- for(unsigned int a=0; a!=settings.yakulist.size(); a++)
- {
- std::vector<Tile> tmenzen=menzen;
- tmenzen.push_back(wtile);
- if(settings.yakulist[a].check_true(tmenzen,open, rwind, wind, riichi, wturn, tileno, wtile, winmode, posconf[highpos],posfu[highpos],openriichi,ippatsu))
- {
- if(yakuman_only[highpos])
- {
- if(check_(open)&&settings.yakulist[a].openhan>=13)
- {
- yakunames.push_back(settings.yakulist[a].name);
- int push_back_han = settings.yakulist[a].openhan;
- if(push_back_han>=26&&(settings.yakuman_mode==2||settings.yakuman_mode==3))
- {
- push_back_han=13;
- }
- hanvalues.push_back(push_back_han);
- }
- else if(!check_(open)&&settings.yakulist[a].han>=13)
- {
- yakunames.push_back(settings.yakulist[a].name);
- int push_back_han = settings.yakulist[a].han;
- if(push_back_han>=26&&(settings.yakuman_mode==2||settings.yakuman_mode==3))
- {
- push_back_han=13;
- }
- hanvalues.push_back(push_back_han);
- }
- }
- else
- {
- if(check_(open))
- {
- yakunames.push_back(settings.yakulist[a].name);
- hanvalues.push_back(settings.yakulist[a].openhan);
- }
- else
- {
- yakunames.push_back(settings.yakulist[a].name);
- hanvalues.push_back(settings.yakulist[a].han);
- }
- }
- }
- }
- return pospay[highpos];
- }
- bool check_tenpai()
- {
- bool tp=is_tenpai(menzen,waits);
- if(!tp)
- {
- return false;
- }
- //check if wait isn't already 4times in hand
- for(unsigned int a=0; a!=waits.size(); a++)
- {
- int count=0;
- for(unsigned int b=0; b!=menzen.size(); b++)
- {
- if(waits[a]==menzen[b])
- {
- count++;
- }
- }
- for(unsigned int b=0; b!=open.size(); b++)
- {
- for(unsigned int c=0; c!=open[b].size(); c++)
- {
- if(waits[a]==open[b][c])
- {
- count++;
- }
- }
- }
- if(count>=4)
- {
- waits.erase(waits.begin()+a);
- a--;
- }
- }
- return tp&&waits.size();
- }
- int check_furiten()
- {
- if(settings.furiten_mode==0)
- {
- return 0;
- }
- if(!check_tenpai())
- {
- return 0;
- }
- if(riichifuri&&settings.riichi_furiten&&(settings.furiten_mode==1||settings.furiten_mode==4))
- {
- std::cout << "RiichiFuriten!" << std::endl;
- return 2;
- }
- //0=no furiten, 1=furiten for turn, 2=completely furiten
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- for(unsigned int b=0; b!=waits.size(); b++)
- {
- if(discards[a]==waits[b]&&(settings.furiten_mode==1||settings.furiten_mode==4))
- {
- std::cout << "Furiten!" << std::endl;
- return 2;
- }
- }
- }
- for(unsigned int a=0; a!=furitile.size(); a++)
- {
- for(unsigned int b=0; b!=waits.size(); b++)
- {
- if(furitile[a]==waits[b]&&(settings.furiten_mode==2||settings.furiten_mode==3||settings.furiten_mode==4))
- {
- std::cout << "Temporary Furiten!" << std::endl;
- return 1;
- }
- }
- }
- return 0;
- }
- bool check_win(const Tile& wtile, const int& rwind, const int& wturn, const int& tileno, const int& winmode)
- {
- if(winmode!=2&&winmode!=4&&check_furiten())
- {
- return false;
- }
- std::vector<Tile> temp = menzen;
- temp.push_back(wtile);
- std::sort(temp.begin(),temp.end());
- std::vector<handconfig> posconf = get_config(temp);
- for(unsigned int a=0; a!=posconf.size(); a++)
- {
- g3::big_int payment;
- g3::big_int fu=get_fu(posconf[a], rwind, winmode, wtile);
- int tmp_ym;
- if(get_han(rwind, wturn, tileno, wtile, winmode, posconf[a],fu,0,0,0,tmp_ym)&&is_winning_hand(temp))
- {
- return true;
- };
- }
- return false;
- }
- int get_clickpos(sf::RenderWindow& GameWindow, int mode=0)
- {
- if(ai&&tsumopai!=deftile)
- {
- sf::Sleep(0.500);
- return -1;
- }
- else if(ai)
- {
- sf::Sleep(0.500);
- return 0;
- }
- int choice = NOTHING;
- bool clicked = false;
- int start = 0;
- while(choice == NOTHING&&!stopbutton)
- {
- choice = NOTHING;
- static bool pressed = false;
- if(pressed==false)
- {
- if(GameWindow.GetInput().IsMouseButtonDown(sf::Mouse::Left))
- {
- pressed = true;
- }
- }
- if(pressed==true)
- {
- pressed = GameWindow.GetInput().IsMouseButtonDown(sf::Mouse::Left);
- if(pressed == false)
- {
- choice = get_choice(GameWindow);
- int clicktime = std::clock();
- int time_past = clicktime - start;
- if(clicked&&choice==NOTHING&&time_past<200)
- {
- if(mode==0)
- {
- choice = None;
- }
- else if(mode==2)
- {
- choice = NOTHING;
- }
- else
- {
- choice = tsumopai_tile;
- }
- clicked = false;
- }
- else if(choice==NOTHING)
- {
- clicked=true;
- start=std::clock();
- }
- if(choice == tsumopai_tile && !tsumopai.highlight)
- {
- choice = NOTHING;
- }
- else if(choice>=hand0&&choice<Chi&&!menzen[choice].highlight)
- {
- choice = NOTHING;
- }
- }
- }
- if(stopbutton)
- {
- std::cout << std::endl << "ABORTED CLICKPOS" << std::endl;
- }
- }
- none_bt=false;
- riichi_bt=false;
- oriichi_bt=false;
- tsumo_bt=false;
- ron_bt=false;
- chi_bt=false;
- pon_bt=false;
- kan_bt=false;
- reshuffle_bt=false;
- send_buttons();
- if(stopbutton)
- {
- stopbutton=false;
- choice = None;
- }
- return choice;
- }
- int get_button(player& p2, std::vector<int>& works, std::vector<std::vector<int> >& chiworks, const int& rwind, const int& wturn, const int& tileno, const Tile& kantile, sf::RenderWindow& GameWindow, int mode=0)
- {
- //0=none, 1=tsumo, 2=riichi, 3=chi, 4=pon, 5=closedkan, 6=latekan, 7=daimin, 8=ron
- if(ai)
- {
- return None; //AI doesn't call
- }
- Tile calltile;
- if(p2.discards.size())
- {
- calltile=p2.discards[p2.discards.size()-1];
- }
- bool tsumo(false),riichi_tempbool(false),chi(false),pon(false),closedkan(false),latek(false),daimin(false),ron(false);
- std::vector<int> riichiwk, ponwk,kanwk;
- std::vector<std::vector<int> > chiwk;
- //tsumo (rinshan)
- if(tsumopai!=deftile&&kantile==tsumopai)
- {
- if(check_win(tsumopai, rwind, wturn, tileno, 3))
- {
- tsumo=true;
- }
- }
- //tsumo (normal)
- else if(tsumopai!=deftile)
- {
- if(check_win(tsumopai, rwind, wturn, tileno, 1))
- {
- tsumo=true;
- }
- }
- //riichi
- if(!riichi&&tsumopai!=deftile&&(!check_(open)||settings.minriichi)&&tileno>=18)
- {
- std::vector<Tile> triichi=menzen;
- triichi.push_back(tsumopai);
- for(unsigned int a=0; a!=triichi.size(); a++)
- {
- std::vector<Tile> ttriichi=triichi;
- ttriichi.erase(ttriichi.begin()+a);
- std::sort(ttriichi.begin(),ttriichi.end());
- if(is_tenpai(ttriichi))
- {
- if(a==triichi.size()-1)
- {
- riichi_tempbool=true;
- riichiwk.push_back(-1);
- }
- else
- {
- riichi_tempbool=true;
- riichiwk.push_back(a);
- }
- }
- }
- }
- //chi
- if(tsumopai==deftile&&relpos(p2)==3&&!riichi&&tileno>=18)
- {
- //get valid pairs
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=a; b!=menzen.size(); b++)
- {
- if(a==b||menzen[a].suit!=menzen[b].suit||menzen[a].suit!=calltile.suit||menzen[a].suit==j)
- {
- continue;
- }
- std::vector<int> tmp(2);
- tmp[0]=a;
- tmp[1]=b;
- //ryanmen
- if(menzen[b].value==menzen[a].value+1&&menzen[a].value!=1&&menzen[a].value!=8&&(calltile.value==menzen[a].value-1||calltile.value==menzen[b].value+1))
- {
- chiwk.push_back(tmp);
- }
- //penchan
- else if(menzen[b].value==menzen[a].value+1&&menzen[a].value==1&&calltile.value==3)
- {
- chiwk.push_back(tmp);
- }
- else if(menzen[b].value==menzen[a].value+1&&menzen[a].value==8&&calltile.value==7)
- {
- chiwk.push_back(tmp);
- }
- //kanchan
- else if(menzen[b].value==menzen[a].value+2&&calltile.value==menzen[a].value+1)
- {
- chiwk.push_back(tmp);
- }
- }
- }
- //sort vectors
- for(unsigned int a=0; a!=chiwk.size(); a++)
- {
- std::sort(chiwk[a].begin(),chiwk[a].end());
- }
- //remove same position-pairs
- for(unsigned int a=0; a!=chiwk.size(); a++)
- {
- for(unsigned int b=a; b!=chiwk.size(); b++)
- {
- if(a==b)
- {
- continue;
- }
- if(chiwk[a]==chiwk[b])
- {
- chiwk.erase(chiwk.begin()+b);
- b--;
- }
- }
- }
- if(chiwk.size())
- {
- chi=true;
- }
- }
- //pon
- if(tsumopai==deftile&&!riichi&&tileno>=18)
- {
- int poncnt=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==calltile)
- {
- poncnt++;
- if(ponwk.size()<2)
- {
- ponwk.push_back(a);
- }
- }
- }
- if(poncnt>=2)
- {
- pon=true;
- }
- }
- //kan (daimin)
- if(tsumopai==deftile&&!riichi&&tileno>=18)
- {
- int kancnt=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==calltile)
- {
- kancnt++;
- kanwk.push_back(a);
- }
- }
- if(kancnt>=3)
- {
- daimin=true;
- }
- }
- //kan (chakan)
- if(tsumopai!=deftile&&!riichi&&tileno>=18)
- {
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=0; b!=open.size(); b++)
- {
- if(std::count(open[b].begin(),open[b].end(),menzen[a])==3)
- {
- kanwk.push_back(a);
- latek=true;
- }
- }
- }
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(std::count(open[a].begin(),open[a].end(),tsumopai)==3)
- {
- kanwk.push_back(-1);
- latek=true;
- }
- }
- }
- //kan (closed)
- if(tsumopai!=deftile&&tileno>=18)
- {
- bool tpai=false;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- int tilecnt=0;
- for(unsigned int b=0; b!=menzen.size(); b++)
- {
- if(menzen[a]==menzen[b])
- {
- tilecnt++;
- }
- }
- bool tp=false;
- if(tsumopai==menzen[a])
- {
- tilecnt++;
- tp=true;
- }
- if(tilecnt==4)
- {
- tpai=tp;
- kanwk.push_back(a);
- closedkan=true;
- }
- }
- if(tpai)
- {
- kanwk.push_back(-1);
- }
- //if riichi, check if config won't be changed
- if(riichi&&closedkan)
- {
- for(unsigned int a=0; a!=kanwk.size(); a++)
- {
- if(kanwk[a]!=-1&&menzen[kanwk[a]]!=tsumopai)
- {
- kanwk.erase(kanwk.begin()+a);
- a--;
- }
- }
- if(!kanwk.size())
- {
- closedkan=false;
- }
- else
- {
- handconfig pos_hands;
- for(unsigned int a=0; a!=waits.size(); a++)
- {
- std::vector<Tile> tmphand=menzen;
- tmphand.push_back(waits[a]);
- std::sort(tmphand.begin(),tmphand.end());
- pos_hands.push_back(tmphand);
- }
- std::vector<handconfig> pos_configs;
- for(unsigned int a=0; a!=pos_hands.size(); a++)
- {
- std::vector<handconfig> tmpconfs = get_config(pos_hands[a]);
- for(unsigned int b=0; b!=tmpconfs.size(); b++)
- {
- pos_configs.push_back(tmpconfs[b]);
- }
- }
- for(unsigned int a=0; a!=pos_configs.size(); a++)
- {
- for(unsigned int b=0; b!=pos_configs[a].size(); b++)
- {
- for(unsigned int c=0; c!=pos_configs[a][b].size(); c++)
- {
- if(pos_configs[a][b][c]==tsumopai)
- {
- if(m_type(pos_configs[a][b])!=2)
- {
- closedkan=false;
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- //ron (chakan)
- if(tsumopai==deftile&&calltile==kantile&&kantile!=deftile)
- {
- if(check_win(calltile, rwind, wturn, tileno, 4))
- {
- ron=true;
- if(riichi)
- {
- riichifuri=true;
- }
- }
- }
- //ron (normal)
- else if(tsumopai==deftile)
- {
- if(check_win(calltile, rwind, wturn, tileno, 0))
- {
- ron=true;
- }
- }
- works=std::vector<int>();
- int a=0;
- if(!tsumo&&!riichi_tempbool&&!chi&&!pon&&!closedkan&&!daimin&&!latek&&!ron)
- {
- return None;
- }
- //0=none, 1=tsumo, 2=riichi, 3=chi, 4=pon, 5=kan, 6=ron
- if(tsumopai==deftile)
- {
- none_bt = true;
- }
- else
- {
- none_bt = false;
- }
- if(tsumo)
- {
- tsumo_bt=true;
- }
- else
- {
- tsumo_bt = false;
- }
- if(riichi_tempbool)
- {
- riichi_bt=true;
- }
- else
- {
- riichi_bt=false;
- }
- if(chi)
- {
- chi_bt=true;
- }
- else
- {
- chi_bt=false;
- }
- if(pon)
- {
- pon_bt=true;
- }
- else
- {
- pon_bt=false;
- }
- if(closedkan||latek||daimin)
- {
- kan_bt=true;
- }
- else
- {
- kan_bt=false;
- }
- if(ron)
- {
- ron_bt=true;
- }
- else
- {
- ron_bt = false;
- }
- send_buttons();
- if(tsumopai==deftile)
- {
- darken_hand();
- if(mode==0)
- {
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- }
- }
- if(mode==0)
- {
- a = receive_clickpos();
- }
- else
- {
- a = get_clickpos(GameWindow);
- }
- if(stopbutton)
- {
- return None;
- }
- if(tsumopai==deftile)
- {
- undarken_hand();
- if(mode==0)
- {
- send_player_update(Client,ip);
- }
- }
- switch(a)
- {
- case Tsumo:
- if(tsumo)
- {
- return Tsumo;
- }
- else
- {
- return None;
- }
- case Riichi:
- if(riichi_tempbool)
- {
- works=riichiwk;
- return Riichi;
- }
- else
- {
- return None;
- }
- case Chi:
- if(chi)
- {
- chiworks=chiwk;
- return Chi;
- }
- else
- {
- return None;
- }
- case Pon:
- if(pon)
- {
- works=ponwk;
- return Pon;
- }
- else
- {
- return None;
- }
- case Kan:
- if(closedkan||latek||daimin)
- {
- works=kanwk;
- return Kan;
- }
- else
- {
- return None;
- }
- case Ron:
- if(ron)
- {
- return Ron;
- }
- else
- {
- return None;
- }
- case None:
- if(tsumopai==deftile)
- {
- return None;
- }
- else
- {
- return 999;
- }
- default:
- return a+1000;
- }
- }
- int get_maxpri(player& p2, const int& rwind, const int& wturn, const int& tileno, const Tile& kantile)
- {
- //0=none, 1=chi, 2=pon/kan, 3=ron
- if(ai)
- {
- return 0; //AI doesn't call
- }
- Tile calltile;
- if(p2.discards.size())
- {
- calltile=p2.discards[p2.discards.size()-1];
- }
- bool chi(false),pon(false),closedkan(false),latek(false),daimin(false),ron(false);
- std::vector<int> riichiwk, ponwk,kanwk;
- std::vector<std::vector<int> > chiwk;
- //chi
- if(tsumopai==deftile&&relpos(p2)==3&&!riichi)
- {
- //get valid pairs
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=a; b!=menzen.size(); b++)
- {
- if(a==b||menzen[a].suit!=menzen[b].suit||menzen[a].suit!=calltile.suit||menzen[a].suit==j)
- {
- continue;
- }
- std::vector<int> tmp(2);
- tmp[0]=a;
- tmp[1]=b;
- //ryanmen
- if(menzen[b].value==menzen[a].value+1&&menzen[a].value!=1&&menzen[a].value!=8&&(calltile.value==menzen[a].value-1||calltile.value==menzen[b].value+1))
- {
- chiwk.push_back(tmp);
- }
- //penchan
- else if(menzen[b].value==menzen[a].value+1&&menzen[a].value==1&&calltile.value==3)
- {
- chiwk.push_back(tmp);
- }
- else if(menzen[b].value==menzen[a].value+1&&menzen[a].value==8&&calltile.value==7)
- {
- chiwk.push_back(tmp);
- }
- //kanchan
- else if(menzen[b].value==menzen[a].value+2&&calltile.value==menzen[a].value+1)
- {
- chiwk.push_back(tmp);
- }
- }
- }
- //sort vectors
- for(unsigned int a=0; a!=chiwk.size(); a++)
- {
- std::sort(chiwk[a].begin(),chiwk[a].end());
- }
- //remove same position-pairs
- for(unsigned int a=0; a!=chiwk.size(); a++)
- {
- for(unsigned int b=a; b!=chiwk.size(); b++)
- {
- if(a==b)
- {
- continue;
- }
- if(chiwk[a]==chiwk[b])
- {
- chiwk.erase(chiwk.begin()+b);
- b--;
- }
- }
- }
- if(chiwk.size())
- {
- chi=true;
- }
- }
- //pon
- if(tsumopai==deftile&&!riichi)
- {
- int poncnt=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==calltile)
- {
- poncnt++;
- if(ponwk.size()<2)
- {
- ponwk.push_back(a);
- }
- }
- }
- if(poncnt>=2)
- {
- pon=true;
- }
- }
- //kan (daimin)
- if(tsumopai==deftile&&!riichi)
- {
- int kancnt=0;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==calltile)
- {
- kancnt++;
- kanwk.push_back(a);
- }
- }
- if(kancnt>=3)
- {
- daimin=true;
- }
- }
- //kan (chakan)
- if(tsumopai!=deftile&&!riichi)
- {
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- for(unsigned int b=0; b!=open.size(); b++)
- {
- if(std::count(open[b].begin(),open[b].end(),menzen[a])==3)
- {
- kanwk.push_back(a);
- latek=true;
- }
- }
- }
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(std::count(open[a].begin(),open[a].end(),tsumopai)==3)
- {
- kanwk.push_back(-1);
- latek=true;
- }
- }
- }
- //kan (closed)
- if(tsumopai!=deftile)
- {
- bool tpai=false;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- int tilecnt=0;
- for(unsigned int b=0; b!=menzen.size(); b++)
- {
- if(menzen[a]==menzen[b])
- {
- tilecnt++;
- }
- }
- bool tp=false;
- if(tsumopai==menzen[a])
- {
- tilecnt++;
- tp=true;
- }
- if(tilecnt==4)
- {
- tpai=tp;
- kanwk.push_back(a);
- closedkan=true;
- }
- }
- if(tpai)
- {
- kanwk.push_back(-1);
- }
- //if riichi, check if config won't be changed
- if(riichi&&closedkan)
- {
- for(unsigned int a=0; a!=kanwk.size(); a++)
- {
- if(kanwk[a]!=-1&&menzen[kanwk[a]]!=tsumopai)
- {
- kanwk.erase(kanwk.begin()+a);
- a--;
- }
- }
- if(!kanwk.size())
- {
- closedkan=false;
- }
- else
- {
- handconfig pos_hands;
- for(unsigned int a=0; a!=waits.size(); a++)
- {
- std::vector<Tile> tmphand=menzen;
- tmphand.push_back(waits[a]);
- std::sort(tmphand.begin(),tmphand.end());
- pos_hands.push_back(tmphand);
- }
- std::vector<handconfig> pos_configs;
- for(unsigned int a=0; a!=pos_hands.size(); a++)
- {
- std::vector<handconfig> tmpconfs = get_config(pos_hands[a]);
- for(unsigned int b=0; b!=tmpconfs.size(); b++)
- {
- pos_configs.push_back(tmpconfs[b]);
- }
- }
- for(unsigned int a=0; a!=pos_configs.size(); a++)
- {
- for(unsigned int b=0; b!=pos_configs[a].size(); b++)
- {
- for(unsigned int c=0; c!=pos_configs[a][b].size(); c++)
- {
- if(pos_configs[a][b][c]==tsumopai)
- {
- if(m_type(pos_configs[a][b])!=2)
- {
- closedkan=false;
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- //ron (chakan)
- if(tsumopai==deftile&&calltile==kantile&&kantile!=deftile)
- {
- if(check_win(calltile, rwind, wturn, tileno, 4))
- {
- ron=true;
- if(riichi)
- {
- riichifuri=true;
- }
- }
- }
- //ron (normal)
- else if(tsumopai==deftile)
- {
- if(check_win(calltile, rwind, wturn, tileno, 0))
- {
- ron=true;
- }
- }
- if(!chi&&!pon&&!closedkan&&!daimin&&!latek&&!ron)
- {
- return 0;
- }
- //0=none, 1=chi, 2=pon/kan, 3=ron
- if(ron)
- {
- return 3;
- }
- if(pon||closedkan||daimin||latek)
- {
- return 2;
- }
- if(chi)
- {
- return 1;
- }
- return 0;
- }
- int call(player& p2, const int& rwind, const int& wturn, const int& tileno, const Tile& kantile, sf::RenderWindow& GameWindow,int button,std::vector<int>& works,std::vector<std::vector<int> >& chiworks)
- {
- if(ai) //ai doesn't call
- {
- return 0;
- }
- //0=none, 1=chi, 2=closedkan, 3=tsumo, 4=ron, 5=chakan/daimin,6=riichi, 7=pon
- //Tile
- if(button>100)
- {
- return button;
- }
- //none
- else if(button==None)
- {
- return 0;
- }
- //tsumo
- else if(button==Tsumo)
- {
- if(kantile!=deftile)
- {
- won=4;
- }
- else
- {
- won=2;
- }
- win_pai=tsumopai;
- return 3;
- }
- //riichi
- else if(button==Riichi)
- {
- darken_hand(works);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- rdiscard(receive_clickpos(1));
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- riichi=wturn;
- pts-=1000;
- return 6;
- }
- //chi
- else if(button==Chi)
- {
- //remove exactly same tiles
- for(unsigned int a=0; a!=chiworks.size(); a++)
- {
- for(unsigned int b=a; b!=chiworks.size(); b++)
- {
- if(a==b)
- {
- continue;
- }
- if(sametile(menzen[chiworks[a][0]],menzen[chiworks[b][0]])&&sametile(menzen[chiworks[a][1]],menzen[chiworks[b][1]]))
- {
- chiworks.erase(chiworks.begin()+b);
- break;
- }
- }
- }
- //only one possibility
- if(chiworks.size()==1)
- {
- ponchi(p2,chiworks[0][0],chiworks[0][1]);
- return 1;
- }
- //several possibilities
- //get possibilites after first click
- darken_hand(chiworks);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- int clickpos=receive_clickpos();
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- std::vector<std::vector<int> > tint;
- for(unsigned int a=0; a!=chiworks.size(); a++)
- {
- for(unsigned int b=0; b!=chiworks[a].size(); b++)
- {
- if(chiworks[a][b]==clickpos)
- {
- tint.push_back(chiworks[a]);
- break;
- }
- }
- }
- //distinct possibility
- if(tint.size()==1)
- {
- ponchi(p2,tint[0][0],tint[0][1]);
- return 1;
- }
- //non-distinct, get next click
- //remove obsolete entries from chiworks
- for(unsigned int a=0; a!=chiworks.size(); a++)
- {
- bool remain=false;
- for(unsigned int b=0; b!=chiworks[a].size(); b++)
- {
- //check if first click exists within possible group
- if(chiworks[a][b]==clickpos)
- {
- remain=true;
- break;
- }
- }
- //remove all groups that didn't contain the first click
- if(!remain)
- {
- chiworks.erase(chiworks.begin()+a);
- a--;
- }
- }
- //create temporary vector chiworks2 that doesn't contain the first click
- std::vector<std::vector<int> > chiworks2 = chiworks;
- for(unsigned int a=0; a!=chiworks2.size(); a++)
- {
- for(unsigned int b=0; b!=chiworks2[a].size(); b++)
- {
- if(chiworks2[a][b]==clickpos)
- {
- chiworks2[a].erase(chiworks2[a].begin()+b);
- break;
- }
- }
- }
- //get second click from temporary vector
- darken_hand(chiworks2);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- int click2=receive_clickpos();
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- //check which group contains second click too (using original vector) and ponchi with it
- for(unsigned int a=0; a!=chiworks.size(); a++)
- {
- for(unsigned int b=0; b!=chiworks[a].size(); b++)
- {
- if(chiworks[a][b]==click2)
- {
- ponchi(p2,chiworks[a][0],chiworks[a][1]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 1;
- }
- }
- }
- }
- //pon
- else if(button==Pon)
- {
- //only one possibility
- if(works.size()==2)
- {
- ponchi(p2,works[0],works[1]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 7;
- }
- //several possibilities
- //check if exactly the same
- if(works.size()==3&&sametile(works[0],works[1])&&sametile(works[1],works[2]))
- {
- ponchi(p2,works[0],works[1]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 7;
- }
- //not exactly the same
- //get first click
- darken_hand(works);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- int clickpos=receive_clickpos();
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- std::vector<int> t_works=works;
- for(unsigned int a=0; a!=t_works.size(); a++)
- {
- if(t_works[a]==clickpos)
- {
- t_works.erase(t_works.begin()+a);
- break;
- }
- }
- std::sort(t_works.begin(),t_works.end());
- //possibilities after first click
- //other 2 exactly the same
- if(t_works.size()==2&&sametile(works[0],works[1]))
- {
- std::vector<int> t_tworks;
- t_tworks.push_back(works[0]);
- t_tworks.push_back(clickpos);
- std::sort(t_tworks.begin(),t_tworks.end());
- ponchi(p2,t_tworks[0],t_tworks[1]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 7;
- }
- //not exactly the same tiles
- darken_hand(t_works);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- int clickpos2=receive_clickpos();
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- std::vector<int> temp_works;
- temp_works.push_back(clickpos);
- temp_works.push_back(clickpos2);
- std::sort(temp_works.begin(),temp_works.end());
- ponchi(p2,temp_works[0],temp_works[1]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 7;
- }
- //ron
- else if(button==Ron)
- {
- if(kantile!=deftile)
- {
- won=3;
- }
- else
- {
- won=1;
- }
- win_pai=p2.discards[p2.discards.size()-1];
- won_from=p2.pid;
- return 4;
- }
- //kan
- else if(button==Kan)
- {
- //daimin-kan
- if(tsumopai==deftile)
- {
- daiminkan(p2,works[0],works[1],works[2]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 5;
- }
- //check number of different tile in works
- std::vector<Tile> counted;
- int count=0;
- for(unsigned int a=0; a!=works.size(); a++)
- {
- bool cont=false;
- for(unsigned int b=0; b!=counted.size(); b++)
- {
- if(works[a]==-1&&tsumopai==counted[b])
- {
- cont=true;
- break;
- }
- if(menzen[works[a]]==counted[b])
- {
- cont=true;
- break;
- }
- }
- if(cont)
- {
- continue;
- }
- count++;
- if(works[a]==-1)
- {
- counted.push_back(tsumopai);
- }
- else
- {
- counted.push_back(menzen[works[a]]);
- }
- }
- //only one possibility
- if(count==1)
- {
- //kan (chakan)
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(works[0]==-1)
- {
- if(std::count(open[a].begin(),open[a].end(),tsumopai)==3)
- {
- latekan(works[0]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 5;
- }
- }
- else
- {
- if(std::count(open[a].begin(),open[a].end(),menzen[works[0]])==3)
- {
- latekan(works[0]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 5;
- }
- }
- }
- //kan (closed)
- if(works.size()==4)
- {
- kan(works[0],works[1],works[2],works[3]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 2;
- }
- }
- //several possibilites, get clickpos
- darken_hand(works);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- int clickpos=receive_clickpos();
- undarken_hand();
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- //chakan
- for(unsigned int a=0; a!=open.size(); a++)
- {
- if(clickpos==-1)
- {
- if(std::count(open[a].begin(),open[a].end(),tsumopai)==3)
- {
- latekan(clickpos);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 5;
- }
- }
- else
- {
- if(std::count(open[a].begin(),open[a].end(),menzen[clickpos])==3)
- {
- latekan(clickpos);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 5;
- }
- }
- }
- //closed kan
- works.clear();
- if(clickpos==-1)
- {
- works.push_back(-1);
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==tsumopai)
- {
- works.push_back(a);
- }
- }
- }
- else
- {
- if(tsumopai==menzen[clickpos])
- {
- works.push_back(-1);
- }
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- if(menzen[a]==menzen[clickpos])
- {
- works.push_back(a);
- }
- }
- }
- if(works.size()==4)
- {
- kan(works[0],works[1],works[2],works[3]);
- send_player_update(Client,ip);
- network_stream << std::endl << update_st() << " SEND PLAYER FROM PLAYER.H" << std::endl;
- return 2;
- }
- }
- return 0;
- }
- std::string handlog()
- {
- std::stringstream sstr;
- for(unsigned int a=0; a!=menzen.size(); a++)
- {
- sstr << menzen[a].tilelog();
- }
- if(tsumopai!=deftile)
- {
- sstr << " T: ";
- sstr << tsumopai.tilelog();
- }
- sstr << " || ";
- for(unsigned int a=0; a!=open.size(); a++)
- {
- for(unsigned int b=0; b!=open[a].size(); b++)
- {
- sstr << open[a][b].tilelog();
- }
- if(a!=open.size()-1)
- {
- sstr<<"|";
- }
- }
- sstr << " __||__ ";
- for(unsigned int a=0; a!=discards.size(); a++)
- {
- sstr << discards[a].tilelog();
- }
- return sstr.str();
- }
- bool operator==(const player &rhs) const
- {
- return wind==rhs.wind;
- }
- bool operator!=(const player &rhs) const
- {
- return wind!=rhs.wind;
- }
- };
- #endif // PLAYER_H_INCLUDED
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement