[C + +] Mahjong Poker algorithm

Source: Internet
Author: User

Mahjong play rules are numerous, the core of the game is consistent, this article will be based on MediaTek 2017 programming challenge of the rules to achieve the title.

How the cards are represented
ABCDEFGHIRepresenting one to nine, representing one to abcdefghi nine, 123456789 representing one to nine loaves

Three kinds of Hu brand type

  • Ordinary card type, 14 cards, shaped like: 3+3+3+3+2 . Where 2 the number represents two identical cards can be a group, shaped like XX . 3the number represents three identical or consecutive cards that can be formed into a set of XXX shapes XYZ .
  • Dragon Seven pairs, 14 sheets as: 2+2+2+2+2+2+2 .
  • With a bar, that is, ordinary card type three cards XXX can be upgraded XXXX to, called a bar. Each number of bars, the total number of cards can be added one. There can be up to 4 bars, so the number of cards with bars can be up to 18.

Sample Example

  • ABCeee345456DDHu Card, the Group of Cards for ABC+EEE+345+456+DD, ordinary card type.
  • ABeeee345456DDFried, because AB two cards failed to form a group card.
  • AAAABC123456333Fried hu, although looks like the group card OK (aaa+abc+124+345+456+333) but does not conform to any kind of Hu card type.
  • AADDFF1133aaggHu, dark seven pair.
  • AAAABBBBCCCCDDDD88Hu brand, 3+3+3+3+2 card type, upgraded 4-way bar.
  • AAA123789Blows, does not conform to any kind of card type.
  • AAA111345666DEF88Blows, does not conform to any kind of card type.
Algorithm realization Idea

1, the ordinary card type is the form of 3n+2, and the Dragon 7 pair are 14 cards, if there is a bar of up to 18 cards, so the first step can be judged, if the number of cards is less than 14 or greater than, it must not be HU card;

2, the card from small to large sorting, convenient follow-up judgment. If the number of hands is 14, you can first determine whether it is the Dragon 7 pair (pair of Hu), which is characterized by each odd bit of cards are equal to the card after one . If not to Hu, then go to step 3;

3, 3n+2 form of the ordinary card type inside there is a pair, so judge is not a card type, you can first find one of the pairs. A card may have 2 or 4, you can make up a pair or a dark bar or a bar, or the back of the cards to form a straight son. Regardless of the number of situations, the pair must appear in a repeating card, as long as each traverse removes a pair . Next go to step 4;

4, after the removal of a pair, determine whether it is a 3n card type, that is, whether it is all composed of straight or dark bars. Since the cards have been sorted, just watch the first card.

    • If the number of the first card is only one or two , then this card must be the same as the following cards to make a straight, otherwise you can not be a card. If there is such a straight, remove the straight
    • If the number of the first card is three or four , it may be composed of a dark bar, or the following cards make up a straight (regardless of the case of the bar), remove the Dark Bar (CIS)

Always cycle above the judgment, meet the conditions to remove the three cards, until the number of cards is 0 o'clock, return to "Hu ", or back to step 3, put the previously removed pairs back, continue to delete the next pair. if all the pairs in step 3 have not satisfied the HU condition, then return "no card";

5, if the number of cards is 15, it will contain at least a 4-card bar, or not a card. If there are multiple bars, then walk through the deletion of a bar, and then go to step 3 to determine whether the 3n card type. If after traversing all the bars can not be a card, then return "no card";

6, if the number of cards is 16, then at least 2 bars, followed by the deletion of the combination of a pair of bars, the remaining similar to step 5. Similarly, the number of cards is 17 and 18 when the method is similar.

C + + source code
#include <iostream> #include <vector> #include <algorithm>using std::vector;using std::cout; Template <typename t>void showvector (vector <T> & lst), vector <int> Findreptpos (vector <char > & LST), bool Isddh (const vector <char> & LST), bool ishu3n (vector <char> & lst), Vector <char > deldui (const vector <char> & LST, const int x), bool is3n (vector <char> lst), int numoffirst (vector &lt ;char> lst); bool CheckGroup (vector <char> LST, const int num), void Delgroup (vector <char> & LST, const int num), vector <char> Delgang (const vector <char> & LST, const int x), vector <int> Findgangpos (cons    T vector <char> & LST); int main (int argc, char **argv) {char *mahjong = argv[1];        Vector <char> lst;    for (int i = 0; Mahjong[i]! = ' + '; ++i) {lst.push_back (mahjong[i]);  } std::sort (Lst.begin (), Lst.end ()); From small to large sort/*cout << "Sort: ";  Showvector (LST); */int num = Lst.size (); Number of Mahjong tiles if (num < 14) | |    (num > 18))        {cout << "bad";    return 0;            } if (num = = 14)//14 cards, 2 kinds of Hu FA {if (ISDDH (LST))///If yes to Hu {cout << "good";        return 0;        } if (Ishu3n (LST)) {cout << "good";        } else {cout << "bad";             } return 0;  } if (num = =) {Vector <int> pos = findgangpos (LST);        Find the position of the bar if (Pos.size () < 1) {cout << "bad";                } else {//delete a bar in turn, and then determine if it is a 3N card type for (int i = 0; i < pos.size (); ++i) {                Vector <char> newlst = Delgang (LST, pos[i]);                /*cout << "delgang/"; Showvector (NEWLST); */if (ishu3n (Newlst)) {cout << "good";                return 0;        }} cout << "bad";  }} if (num = =) {Vector <int> pos = findgangpos (LST);        Find the position of the bar if (Pos.size () < 2)//Less than 2 bars is definitely not a flop {cout << "bad";            } else {//delete the different 2-bar combinations in turn, and then determine if it is a 3N card type for (int i = 0; i < pos.size ()-1; ++i)                     {for (int j = i + 1; j < Pos.size (); ++j) {//note remove the rear bar first, otherwise the position will change                    Vector <char> newLst1 = Delgang (LST, pos[j]);                    Vector <char> newLst2 = Delgang (NewLst1, pos[i]);                    /*cout << "delgang/"; Showvector (NEWLST2); */if (ishu3n (NewLst2)) {cout << "                        Good ";                    return 0; }}} cout << "Bad";  }} if (num = =) {Vector <int> pos = findgangpos (LST);        Find the position of the bar if (Pos.size () < 3)//Less than 3 bars is definitely not a flop {cout << "bad";            } else {//delete the different 3-bar combinations in turn, and then determine if it is a 3N card type for (int i = 0; i < pos.size ()-2; ++i)  {for (int j = i + 1, J < Pos.size ()-1; ++j) {for (int k = j + 1; K < Pos.size ();  ++K) {//note remove the rear bar first, otherwise the position will change vector <char> newLst1 =                        Delgang (LST, pos[k]);                        Vector <char> newLst2 = Delgang (NewLst1, pos[j]);                        Vector <char> newLst3 = Delgang (NewLst2, pos[i]);                        /*cout << "delgang/"; Showvector (NEWLST3); */if (ishu3n (NEWLST3)) {Cou            T << "good";                return 0;        }}}} cout << "bad";  }} if (num = =) {Vector <int> pos = findgangpos (LST);        Find the position of the bar if (pos.size ()! = 4)//Not 4 bar definitely not a flop {cout << "bad";            } else {//delete 4 bar vectors <char> newLst1 = Delgang (LST, pos[3]);            Vector <char> newLst2 = Delgang (NewLst1, pos[2]);            Vector <char> newLst3 = Delgang (NewLst2, pos[1]);            Vector <char> newLst4 = Delgang (NewLst3, pos[0]);            /*cout << "delgang/";            Showvector (NEWLST4); */if (newlst4[0] = = Newlst4[1]) {cout << "good";            } else {cout << "bad"; }}} return 0;} Display List contents template <typename t>void showvector (vector <T> & LST) {   Vector <t>::iterator iter;    Iterator for (iter = Lst.begin (); ITER! = Lst.end (); iter++) {cout << *iter << ""; } cout << "\ n";}  Find the position of the duplicate hand vector <int> Findreptpos (vector <char> & lst) {vector <int> pos;    The position where the duplicate card is stored int temp_pos = 0;    if (Lst.size () <= 1)//card number is less than or equal to 1, directly return {return pos;    }//Lst.size () >= 2 vector <char>::iterator iter2;    Iter2 = Lst.begin ();  ++iter2;    The iterator does not support arithmetic operations, only ++/--/advance chained operations if (lst.front () = = *iter2) {pos.push_back (temp_pos);    } vector <char>::iterator It_front;    Vector <char>::iterator It_back;  for (Auto iter1 = iter2; Iter1! = (--lst.end ()); iter1++)//from second to penultimate {++temp_pos; Location update it_front = Iter1;        --it_front; It_back = Iter1;        ++it_back; Not equal to the previous if (*iter1! = *it_front) && (*iter1 = = *it_back)) {Pos.push_back (temp_p        OS);   } } return POS;}    Whether it is pair of HU bool Isddh (const vector <char> & LST) {vector <char> newlst = LST;        for (int i = 0; I <=; ++i) {if (Newlst[i]! = newlst[i + 1]) {return false;    } ++i; } return true;  is the normal card type 3nbool ishu3n (vector <char> & lst) {vector <int> pos = findreptpos (LST); Find the position of the duplicate card for (int i = 0; i < pos.size (); ++i)//Remove duplicate pairs {vector <char> newlst = Deldui (LST, p  Os[i]);        Delete a pair of cards/*cout << "deldui/";        Showvector (NEWLST); */if (is3n (Newlst)) {return true; }} return false;}    Whether it is n straight or dark bar bool is3n (vector <char> lst) {if (lst.size ()% 3! = 0) {return false;  } while (Lst.size () > 0) {if (Lst.size () >= 3) {int num = Numoffirst (LST);   Calculates the number of repetitions of the first card if (CheckGroup (LST, num))//Check if there is a first straight or dark bar {                             Delgroup (LST, num);            Delete this set of straight or dark bars} else {return false;        }}/*cout << "//"; Showvector (LST); */} return true;  Check if there is a first straight or dark bar bool CheckGroup (vector <char> LST, const int num) {if (num = 1) && (lst[1] = = Lst[0] +            1) {//second number may have duplicate for (int i = 2; I < lst.size (); ++i) {if (Lst[i]! = lst[1])                {if (lst[i] = = Lst[0] + 2) {return true;                } else {return false;        }}}} if ((num = = 2) && (lst[2] = = Lst[1] + 1) {//The third number may be duplicated  for (int i = 3; I < lst.size (); ++i) {if (Lst[i]! = lst[2]) {if (Lst[i]                   = = Lst[1] + 2) { return true;                } else {return false;    }}}} if (num >= 3) {return true; } return false;} Delete this set of straight or dark bars void Delgroup (vector <char> & LST, const int num) {if (num = = 1) {vector <char        >::iterator iter = ++lst.begin ();            for (int i = 2; I < lst.size (); ++i) {++iter;                if (lst[i] = = (1 + lst[1])) {lst.erase (ITER);                Lst.erase (Lst.begin ());                Lst.erase (Lst.begin ());            Break        }}} if (num = = 2) {vector <char>::iterator iter = + + (++lst.begin ());            for (int i = 3; I < lst.size (); ++i) {++iter;                if (lst[i] = = (1 + lst[2])) {lst.erase (ITER);  Lst.erase (++lst.begin ()); Remove the second-digit card lst.erase (++lst.begIn ());            Break        }}} if (num >= 3) {lst.erase (Lst.begin ());        Lst.erase (Lst.begin ());    Lst.erase (Lst.begin ());    }}//calculates the number of repetitions of the first card int numoffirst (vector <char> lst) {if (lst[0]! = lst[1]) {return 1;    } if ((lst[0] = = lst[1]) && (lst[1]! = lst[2])) {return 2;        } if (lst[0] = = Lst[2]) {if (lst.size () = = 3) {return 3;        } if ((Lst.size () >= 4) && (lst[2]! = lst[3]))//lst[3] must be guaranteed size>=4 {return 3;    }} if ((lst[0] = = Lst[3]) && (Lst.size () >= 4)) {return 4; } return 0;} Remove the X and x+1 positions of a pair of vector <char> Deldui (const vector <char> & LST, const int x) {vector <char> newls    T for (int i = 0; i < lst.size (); ++i) {if ((i! = x) && (i! = (x + 1)) {Newlst.pus        H_back (Lst[i]); }} returnNewlst;} Remove the bar starting at x (4 cards) vector <char> Delgang (const vector <char> & LST, const int x) {vector <char> NE    WLst; for (int i = 0; i < lst.size (); ++i) {if ((I < x) | |        (i > x + 3))        {Newlst.push_back (lst[i]); }} return newlst;}    Find the position of the bar vector <int> findgangpos (const vector <char> & LST) {vector <int> pos;    int temp_pos = 0;    if (Lst.size () < 4) {return pos; } for (int i = 0; i < lst.size ()-3; ++i) {if (lst[i] = = Lst[i + 3]) {Pos.pus        H_back (Temp_pos);  } ++temp_pos; Location update} return POS;}
Program Run Results

The program obtains input data from command-line parameters, and the data is a string representing a deck of cards. If this deck reaches the condition of the license, the output good, otherwise the output bad.

[C + +] Mahjong Poker algorithm

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.