Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
1 / 1 / 1
Регистрация: 28.07.2013
Сообщений: 41
1

Ошибки в покерной игре: 'players' was not declared in this scope

24.05.2015, 18:37. Показов 1722. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день.
Наверно вы меня уже тихонько ненавидите, но я все же снова напишу сюда
Я новичок - самоучка, и от этого у меня много пробелов в знаниях.
Решил попробовать написать покерную игру, но получаю ошибку за ошибкой. В данный момент не могу понять, почему компилятор ругается, подскажите пожалуйста.
Мой код:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <random>
#include <iomanip>
 
using namespace std;
 
random_device rd;
mt19937 gen(rd());
 
/*----------------------------------------------------------------------------*/
 
class Card
{
private:
    short numb;
    short suit;
public:
    Card(short Numb, short Suit)
    {
        numb = Numb;
        suit = Suit;
    }
    short getNumb() const
        { return numb; }
    short getSuit() const
        { return suit; }
    friend ostream& operator << (ostream&, Card&);
};
ostream& operator << (ostream& out, Card& card)
{
    out << card.getNumb() << card.getSuit();
    return out;
}
 
/*----------------------------------------------------------------------------*/
 
class Player
{
private:
    string username;
    short numb;
    short position;
    vector<Card> hand;
    double bankroll;
    bool readyToPlay;
public:
    Player(short Numb)
    {
        numb = Numb;
        bankroll = 100.0; //DBG
    }
    Player(short Numb, string Username)
    {
        numb = Numb;
        username = Username;
        bankroll = 100.0; //DBG
    }
    void setUsername(string Username)
        { username = Username; }
    void setNumb(short Numb)
        { numb = Numb; }
    void setPosition(short Position)
        { position = Position; }
    void setHand(vector<Card> Hand)
        { hand = Hand; }
    void setBankroll(double Bankroll)
        { bankroll = Bankroll; }
    void setReadyToPlay(bool ReadyToPlay)
        { readyToPlay = ReadyToPlay; }
    void setCardToPlayersHand(Card card)
        { hand.push_back(card); }
    string getUsername() const
        { return username; }
    short getNumb() const
        { return numb; }
    short getPosition() const
        { return position; }
    vector<Card> getHand() const
        { return hand; }
    double getBankroll() const
        { return bankroll; }
    bool getReadyToPlay() const
        { return readyToPlay; }
};
 
/*----------------------------------------------------------------------------*/
 
class cardDeck
{
private:
    vector<Card> deck;
public:
    cardDeck()
    {
        for(short i = 1; i <= 4; i++)
        {
            for(short j = 2; j <= 13 + 1; j++)
            {
                deck.push_back(Card(j, i));
            }
        }
    }
    vector<Card> getCardDeck()
        { return deck; }
    vector<Card>& shuffle()
    {
        std::shuffle(deck.begin(), deck.end(), gen);
        for(int i = 0; i < 52; i++)
            cout << deck[i] << ' ';
        return deck;
    }
};
 
/*----------------------------------------------------------------------------*/
 
class Table
{
private:
    vector<Player> players;
    static int tableId;
    bool emptySeats[9];
    short numberOfEmptySeats;
public:
    Table()
    {
        cout << "Create Table\n"; //DBG
        for(short i = 0; i < 9; i++)
        {
            emptySeats[i] = true;
        }
        // more
    }
    /* DEBUG BEGINS */
        ~Table()
        {
            cout << "Delete Table\n";
        }
    /* DEBUG ENDS */
    friend class Hand; /////////////////////////////////hmmmm...
    void countNumberOfEmptySeats()
    {
        short numb = 0;
        for(short i = 0; i < 9; i++)
            if(emptySeats[i] == true)
                numb++;
        numberOfEmptySeats = numb;
    }
    short getNumberOfEmptySeats()
        { return numberOfEmptySeats; }
    vector<Player>& getPlayers()
        { return players; }
};
 
/*----------------------------------------------------------------------------*/
 
class Hand
{
private:
    static int handId;
public:
    Hand()
    {
        cout << "Create Hand\n"; // DBG
        cardDeck deck;
        deck.shuffle();
    }
    /* DEBUG BEGINS */
        ~Hand()
        {
            cout << "Delete Hand\n";
        }
    /* DEBUG ENDS */
    void dealToPlayers(short count)
    {
        while(count > 0)
        {
            for(vector<Player> :: iterator it = players.begin(); it < players.end(); it++)
            {
                (*it).setCardToPlayersHand(deck.front());
                deck.erase(deck.begin());
            }
            count--;
        }
    }
};
 
/*----------------------------------------------------------------------------*/
 
int main()
{
    cout << "Main starts\n"; //DBG
    Table t;
    
//  do
//  {
        t.countNumberOfEmptySeats();
//      if(t.getNumberOfEmptySeats() < 8)
        {
            Hand h;
        }
//  }while(true)
    cout << "Main ends\n"; //DBG
    return 0;
}

Вот вывод компилятора:
Кликните здесь для просмотра всего текста
Код
hello_world.cpp: In member function 'void Hand::dealToPlayers(short int)':
hello_world.cpp:181:40: error: 'players' was not declared in this scope
    for(vector<Player> :: iterator it = players.begin(); it < players.end(); it++)
                                        ^
hello_world.cpp:183:44: error: 'deck' was not declared in this scope
                 (*it).setCardToPlayersHand(deck.front());
                                            ^

Почему он не хочет дружить - ума не приложу... Буду благодарен любым замечаниям!

P.S Если у кого то будет время бегло пробежаться по коду - буду премного благодарен замечаниям по общей архитектуре приложения, некорректности код и т. п..

Заранее благодарю!!!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.05.2015, 18:37
Ответы с готовыми решениями:

'arr' was not declared in this scope 'sum' was not declared in this scope такие вот ошибки.(
#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;ctime&gt; using namespace std; int main () { ...

Ошибки:х1,х2 was not declared in this scope
Выбивает ошибки:х1,х2 was not declared in this scope. Что делать? #include&lt;iostream&gt;...

Найти причины и способы исправления ошибки 'clrscr' was not declared in this scope (Dev C++)
Подскажите,почему не хочет компилироваться код? #include&lt;stdio.h&gt; #include&lt;conio.h&gt;...

Найти причины возникновения ошибки "stoi was not declared in this scope"
Добрый день! Подскажите, как все исправить компилятор выдает ошибку &quot;stoi was not declared in this...

26
45 / 21 / 6
Регистрация: 28.02.2013
Сообщений: 194
25.05.2015, 08:46 21
Author24 — интернет-сервис помощи студентам
hand_evaluator.h
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Convert hand value to unsined long number (32 bits)
//          4th byte                 3rd byte                    2nd byte                  1st byte
//   [7][6][5][4][3][2][1][0]  [7][6][5][4][3][2][1][0]  [7][6][5][4][3][2][1][0]  [7][6][5][4][3][2][1][0]
//    |  |  |  |  |  |  |  |    |  |  |  |  |  |  |  |    |  |  |  |  |  |  |  |    |  |  |  |  |  |  |  |
//                                           --- STRAIGHT FLUSH ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][1][0][0][1]  [0][0][0][0][0][0][0][0]  [0][0][0][0][*][*][*][*]
//                                         [ hand type]           Hi card in street(0-12)----->[          ]
//                                           --- FOUR OF A KIND ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][1][0][0][0]  [0][0][0][0][*][*][*][*]  [0][0][0][0][*][*][*][*]
//                                         [ hand type]              [   four   ]              [          ]<---Hi card from the rest of cards
//                                             --- FULL HOUSE ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][1][1][1]  [0][0][0][0][*][*][*][*]  [0][0][0][0][*][*][*][*]
//                                         [ hand type]              [   trips  ]              [   pair   ]
//                                                --- FLUSH ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][1][1][0]  [0][0][0][*][*][*][*][*][*][*][*][*][*][*][*][*]
//                                         [ hand type]           [         Fife hi cards in flush        ]
//                                              --- STRAIGHT ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][1][0][1]  [0][0][0][0][0][0][0][0]  [0][0][0][0][*][*][*][*]
//                                         [ hand type]           Hi card in street(0-12)----->[          ]
//                                           --- THREE OF A KIND ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][1][0][0]  [0][0][0][0][*][*][*][*][*][*][*][*][*][*][*][*]
//                                         [ hand type]              [  trips   ]  [    1st   ][   2nd    ]<---Values of two hi cards         ]
//                                             --- TWO PAIRS ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][0][1][1]  [0][0][0][0][*][*][*][*][*][*][*][*][*][*][*][*]
//                                         [ hand type]              [ Hi pair  ]  [ Low pair ][ hi card  ]
//                                                --- PAIR ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][0][1][0][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*][*]
//                                         [ hand type]  [   pair   ][          ]  [          ][          ]<---three hi cards
//                                              --- HI CARD ---
//   [0][0][0][0][0][0][0][0]  [0][0][0][0][0][0][0][1]  [0][0][0][*][*][*][*][*][*][*][*][*][*][*][*][*]
//                                         [ hand type]           [          five hi cards                ]
//
//
//
 
 
 
#include <string>
#include <stdint.h>
 
#include "cards.h"
 
 
#ifndef HOLDEM_HAND_EVALUATOR_H
#define HOLDEM_HAND_EVALUATOR_H
 
 
typedef uint32_t hand_value_t;
 
 
using namespace std;
 
 
hand_value_t GetHand(card_t* cards); //7 cards array needed
hand_value_t GetHand(card_t card0, card_t card1, card_t card2, card_t card3, card_t card4, card_t card5, card_t card6);
 
string HandValueToString(hand_value_t hand);
 
 
 
uint8_t IsStreet(uint32_t cards);
card_t GetHiCard(uint32_t cards);
card_t GetAndRemoveHiCard(uint32_t* cards);
 
 
 
 
#endif // HOLDEM_HAND_EVALUATOR_H


hand_evaluator.cpp
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#include "holdem_hand_evaluator.h"
#include <iostream>
#include <bitset>
 
hand_value_t GetHand(card_t* cards)
{
    uint32_t answer=0;
    uint32_t temp1=0;
    uint32_t temp2=0;
 
    uint32_t spades=0;
    uint32_t clubs=0;
    uint32_t diamonds=0;
    uint32_t hearts=0;
 
    for (int i=0; i<7; i++)
    {
    if(cards[i]>>4==0)spades|=(1<<((cards[i]&0xF)-1));
    if(cards[i]>>4==1)clubs|=(1<<((cards[i]&0xF)-1));
    if(cards[i]>>4==2)diamonds|=(1<<((cards[i]&0xF)-1));
    if(cards[i]>>4==3)hearts|=(1<<((cards[i]&0xF)-1));
    }
 
//    cout<<endl<<endl<<"      AKQJT98765432"<<endl<<"s: "<<bitset<16>(spades)<<endl<<"c: "<<bitset<16>(clubs)<<endl<<"d: "<<bitset<16>(diamonds)<<endl<<"h: "<<bitset<16>(hearts)<<endl<<endl;
 
    //  -----------------------  STRAIGHT FLASH  ------------------------------------------
    temp1=IsStreet(spades);
    if (temp1){answer=(9<<16)|temp1; return answer;};
    temp1=IsStreet(clubs);
    if (temp1){answer=(9<<16)|temp1; return answer;};
    temp1=IsStreet(diamonds);
    if (temp1){answer=(9<<16)|temp1; return answer;};
    temp1=IsStreet(hearts);
    if (temp1){answer=(9<<16)|temp1; return answer;};
 
    //  -----------------------  FOUR OF A KIND  ------------------------------------------
    temp1=spades&clubs&diamonds&hearts;
    if(temp1){
      temp2 = spades|clubs|diamonds|hearts;
      temp2&=~temp1;//гасим нашу 4ку
      answer = (8<<16)|(temp1<<8)|GetHiCard(temp2);
      return answer;
    }
 
    uint32_t trips=0;
    trips = (spades&clubs&diamonds)|(spades&clubs&hearts)|(spades&diamonds&hearts)|(clubs&diamonds&hearts);
    uint32_t pairs=0;
    pairs = (spades&clubs)|(spades&diamonds)|(spades&hearts)|(clubs&diamonds)|(clubs&hearts)|(diamonds&hearts);
    //  -----------------------  FULL HOUSE  -------------------------------------------
 
    if (trips){
      //находим старшую тройку
      uint8_t t;
      t = GetHiCard(trips);
      //ишем двойки
      pairs&=~(1<<t);//гасим в двойках старшую тройку (нестаршие тройки остаются)
      if (pairs){
        answer = (7<<16)|(t<<8)|GetHiCard(pairs);
        return answer;
      }
    }
    //  -----------------------  FLUSH  -------------------------------------------------
    uint8_t s=0,c=0,d=0,h=0;
    for(int i=0;i<=12;i++){
      if(spades&(1<<i))s++;
      if(clubs&(1<<i))c++;
      if(diamonds&(1<<i))d++;
      if(hearts&(1<<i))h++;
    }
 
    if(s>=5){
        answer = (6<<16);
        uint8_t t;
        t = GetAndRemoveHiCard(&spades);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&spades);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&spades);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&spades);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&spades);
        answer|=(1<<t);
        return answer;
    }
    if(c>=5){
        answer = (6<<16);
        uint8_t t;
        t = GetAndRemoveHiCard(&clubs);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&clubs);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&clubs);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&clubs);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&clubs);
        answer|=(1<<t);
        return answer;
    }
    if(d>=5){
        answer = (6<<16);
        uint8_t t;
        t = GetAndRemoveHiCard(&diamonds);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&diamonds);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&diamonds);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&diamonds);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&diamonds);
        answer|=(1<<t);
        return answer;
    }
    if(h>=5){
        answer = (6<<16);
        uint8_t t;
        t = GetAndRemoveHiCard(&hearts);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&hearts);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&hearts);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&hearts);
        answer|=(1<<t);
        t = GetAndRemoveHiCard(&hearts);
        answer|=(1<<t);
        return answer;
    }
 
    //  --------------------------  STRAIGHT  -----------------------------------------
    temp1 = IsStreet(spades|clubs|diamonds|hearts);
    if(temp1){answer=(5<<16)|temp1; return answer;}
 
    //  --------------------------  THREE OF A KIND  ----------------------------------
    if (trips){//если мы дошли сюда, то у нас может быть только 1 тройка
      uint8_t t;
      t = GetHiCard(trips);
      answer = (4<<16)|(t<<8);
      uint32_t all = spades|clubs|diamonds|hearts;
      all&=~trips;//гасим тройку
      answer |= (GetAndRemoveHiCard(&all)<<4);
      answer |= GetAndRemoveHiCard(&all);
      return answer;
    }
 
 
    //  ---------------------------  PAIR AND TWO PAIRS  -----------------------------------------
    if (pairs){
 
      uint32_t all = spades|clubs|diamonds|hearts;
      //находим старшую двойку
      uint8_t hi_pair = GetAndRemoveHiCard(&pairs);
      if (pairs){//если есть другие двойки кроме найденной
        uint8_t low_pair = GetAndRemoveHiCard(&pairs);
        all&=~(1<<hi_pair);//гасим старшую двойку
        all&=~(1<<low_pair);//гасим младшую двойку
        answer = (3<<16)|(hi_pair<<8)|(low_pair<<4)|GetAndRemoveHiCard(&all);
        return answer;
      }
      answer = (2<<16)|(hi_pair<<12);
      all&=~(1<<hi_pair);//гасим двойку
      answer |= (GetAndRemoveHiCard(&all)<<8);
      answer |= (GetAndRemoveHiCard(&all)<<4);
      answer |= GetAndRemoveHiCard(&all);
      return answer;
    }
 
    //  ------------------------------  HI CARD  -----------------------------
    uint32_t all = spades|clubs|diamonds|hearts;
    answer = (1<<16);
    answer|=(1<<GetAndRemoveHiCard(&all));
    answer|=(1<<GetAndRemoveHiCard(&all));
    answer|=(1<<GetAndRemoveHiCard(&all));
    answer|=(1<<GetAndRemoveHiCard(&all));
    answer|=(1<<GetAndRemoveHiCard(&all));
    return answer;
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
uint8_t IsStreet(uint32_t cards)
{
 
    cards&=0x1FFF;
    if ((cards&0x1F00)==0x1F00)return 13;
    if ((cards&0xF80)==0xF80)return 12;
    if ((cards&0x7C0)==0x7C0)return 11;
    if ((cards&0x3E0)==0x3E0)return 10;
    if ((cards&0x1F0)==0x1F0)return 9;
    if ((cards&0xF8)==0xF8)return 8;
    if ((cards&0x7C)==0x7C)return 7;
    if ((cards&0x3E)==0x3E)return 6;
    if ((cards&0x1F)==0x1F)return 5;
    if ((cards&0x100F)==0x100F)return 4;
    return 0;
}
// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t GetHiCard(uint32_t cards){
  uint8_t t=12;
  while((cards&(1<<t))==0){t--;}//на выходе t = старшая карта (от 12 до 0)
  return t;
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t GetAndRemoveHiCard(uint32_t* cards){
    if (*cards == 0) return 0;
    uint8_t t=12;
  while((*cards&(1<<t))==0){t--;}//на выходе t = старшая карта (от 12 до 0)
  *cards&=~(1<<t);//гасим бит старшей карты в cards
  return t;
}
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////
string HandValueToString(hand_value_t hand)
{
    string hand_type = "error";
    if (hand == 0) return "Null hand";
    if ((hand&0xF0000) == (9<<16)) hand_type = "Straight flush";
    if ((hand&0xF0000) == (8<<16)) hand_type = "Four of a kind";
    if ((hand&0xF0000) == (7<<16)) hand_type = "Full house";
    if ((hand&0xF0000) == (6<<16)) hand_type = "Flush";
    if ((hand&0xF0000) == (5<<16)) hand_type = "Straight";
    if ((hand&0xF0000) == (4<<16)) hand_type = "Three of a kind";
    if ((hand&0xF0000) == (3<<16)) hand_type = "Two pairs";
    if ((hand&0xF0000) == (2<<16)) hand_type = "Pair";
    if ((hand&0xF0000) == (1<<16)) hand_type = "Hi card";
    return hand_type;
}
 
hand_value_t GetHand(card_t card0, card_t card1, card_t card2, card_t card3, card_t card4, card_t card5, card_t card6){
    card_t Cards[7];
    Cards[0] = card0;
    Cards[1] = card1;
    Cards[2] = card2;
    Cards[3] = card3;
    Cards[4] = card4;
    Cards[5] = card5;
    Cards[6] = card6;
    return GetHand(Cards);
}


Дальше в развитии идёт фсмка (finite state machine) покера. Которая инкапсулирует в себя все покерные правила (включая неполный райз, множественые боковые банки (side pots) и деление фишек чётко с правилами до цента.
Её я планирую выложить в паблик чуть позже.

Так вот всё это - полная ерунда в сравнении с тем этапом когда playerу понадобится член ballance
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
25.05.2015, 13:10 22
nefton, Если вы любите быструю езду, это не означает что нельзя использовать классы.
С++ для это и был создан чтобы получить максимальную производительность не переходя на прорву мэджикнамберов и не расширяемость.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <vector>
#include <cstring>
 
enum Numb
{
    Two = 0x1, Three = 0x2, Four = 0x3, Five = 0x4, Six = 0x5, Seven = 0x6
};
 
enum Suit
{
    Spades = 0x0, Clubs = 0x1, Diamonds = 0x2, Hearts = 0x3
};
 
class Card
{
    uint8_t cardValue_;
public:
    Card(Numb numb, Suit suit) :
            cardValue_((unsigned char) suit << 4 | (unsigned char) numb)
    {
    }
 
    Numb numb() const
    {
        return Numb(cardValue_ & 0xF);
    }
 
    void numb(const Numb& val)
    {
        cardValue_ = (cardValue_ & 0xF0) | (unsigned char) val;
    }
 
    Suit suit() const
    {
        return Suit((cardValue_ & 0x30) >> 4);
    }
 
    void suit(const Suit& val)
    {
        cardValue_ = (cardValue_ & 0xF) | (unsigned char) val << 4;
    }
};
 
template<Numb N, Suit S>
struct StaticCard
{
private:
    static const uint8_t cardValue = (unsigned char) S << 4 | (unsigned char) N;
public:
 
    constexpr unsigned char data() const
    {
        return cardValue;
    }
 
    constexpr Numb numb() const
    {
        return N;
    }
 
    constexpr Suit suit() const
    {
        return S;
    }
};
 
template<class T, class ... Types>
class StaticHand: StaticHand<Types...>
{
    static const unsigned char data_ = (unsigned char) T::cardValue;
public:
    constexpr long int data() const
    {
        return (*(long int*) this);
    }
 
    constexpr long int numbData() const
    {
        return ((*(long int*) this) & 0xF0F0F0F0F0F0F0F);
    }
 
    constexpr long int suitData() const
    {
        return ((*(long int*) this) & 0xF0F0F0F0F0F0F0F0);
    }
};
 
template<class T>
struct StaticHand<T>
{
    static const unsigned char data = (unsigned char) (T::S) << 4 | (unsigned char) (T::N);
};
 
class Hand
{
public:
    Hand(const std::initializer_list<Card>& value) :
            cards_(value)
    {
    }
 
    std::vector<Card> cards_;
 
    inline long int data() const
    {
        long int ret = 0;
        memcpy(&ret, cards_.data(), cards_.size());
        return ret;
    }
 
    inline long int numbData() const
    {
        return data() & 0xF0F0F0F0F0F0F0F;
    }
 
    inline long int suitData() const
    {
        return data() & 0xF0F0F0F0F0F0F0F0;
    }
};
 
bool IsStreet(const Hand& hand)
{
    StaticHand<StaticCard<Numb::Two, Suit::Clubs>, StaticCard<Numb::Three, Suit::Clubs>, StaticCard<Numb::Four, Suit::Clubs>,
            StaticCard<Numb::Five, Suit::Clubs>, StaticCard<Numb::Six, Suit::Clubs>, StaticCard<Numb::Seven, Suit::Clubs>> h1;
 
    if ((hand.numbData() & h1.numbData()) == h1.numbData())
        return true;
    return false;
}
 
int main(int argC, char* argV[])
{
    Hand hand { { Numb::Three, Suit::Diamonds }, { Numb::Three, Suit::Diamonds }, { Numb::Three, Suit::Diamonds }, { Numb::Three,
            Suit::Diamonds }, { Numb::Three, Suit::Diamonds }, { Numb::Three, Suit::Diamonds } };
    Hand hand2 { { Numb::Two, Suit::Diamonds }, { Numb::Three, Suit::Hearts }, { Numb::Four, Suit::Clubs }, { Numb::Five,
            Suit::Clubs }, { Numb::Six, Suit::Spades }, { Numb::Seven, Suit::Clubs } };
    IsStreet(hand);
    IsStreet(hand2);
    std::cout << IsStreet(hand) << std::endl;
    std::cout << IsStreet(hand2) << std::endl;
}
0
45 / 21 / 6
Регистрация: 28.02.2013
Сообщений: 194
25.05.2015, 15:40 23
Цитата Сообщение от Nosey Посмотреть сообщение
enum Numb
{
* * Two = 0x1, Three = 0x2, Four = 0x3, Five = 0x4, Six = 0x5, Seven = 0x6
};
C++
1
enum class {Two, Three, Four, Five, Six, Seven}
но к чему это???

Цитата Сообщение от Nosey Посмотреть сообщение
enum Suit
{
* * Spades = 0x0, Clubs = 0x1, Diamonds = 0x2, Hearts = 0x3
};
аналогично

Цитата Сообщение от Nosey Посмотреть сообщение
Suit suit() const
* * {
* * * * return Suit((cardValue_ & 0x30) >> 4);
* * }
А вот и пошли магические номера. Парадигма enum class подразумевает отказ от номеров (даже порядковых)
надо:
C++
1
2
3
4
5
6
[CPP]
Suit suit() const
    {
         if (((cardValue_ & 0x30) >> 4) == 0) return Suit::spades;
         ......
     }
[/CPP]

Замечу привязка к битовой карте (которая должна быть гдето описанна по русски отдельно) - осталась
и все магические номера соответственно

Цитата Сообщение от Nosey Посмотреть сообщение
struct StaticCard
{
private:
* * static const uint8_t cardValue = (unsigned char) S << 4 | (unsigned char) N;
public:
constexpr unsigned char data() const
* * {
* * * * return cardValue;
* * }
constexpr Numb numb() const
* * {
* * * * return N;
* * }
constexpr Suit suit() const
* * {
* * * * return S;
* * }
};
Это настолько выше моего понимания что я даже представить не могу что это.

А теперь самое интересное чем теоретики отличаются от практиков )))
Hand - рука - вы вообще представляете что это и как с этим работать?
она состоит из 5ти карт (но выбирается из 7ми)
и самое главное её отношение с другими руками. она их либо "бьёт" либо не бьёт либо они одинаковые
где перегрузка операторов >,<,>=,<=,==,!= ???
и главное на что интересно будет похож этот код???? )
Цитата Сообщение от Nosey Посмотреть сообщение
bool IsStreet(const Hand& hand)
{
* * StaticHand<StaticCard<Numb::Two, Suit::Clubs>, StaticCard<Numb::Three, Suit::Clubs>, StaticCard<Numb::Four, Suit::Clubs>,
* * * * * * StaticCard<Numb::Five, Suit::Clubs>, StaticCard<Numb::Six, Suit::Clubs>, StaticCard<Numb::Seven, Suit::Clubs>> h1;
if ((hand.numbData() & h1.numbData()) == h1.numbData())
* * * * return true;
* * return false;
}
Стрит в покере это не просто стрит. стрит 789TJ бьёт 6789T
А ещё бывает стрит A2345, А вот стрита KA234 не бывает
Да и вообще функция изстрит - просто вспомогательная.
Реально надо только 1 функция перевода 7 карт в руку (4х байтное число) которое можно >,<,>=,<=,==,!=


И самое главное. Вы действительно думаете что карта в виде класса удобнее?
Неужели есть в жизни хоть 1 ситуация где функции string CardToString(card_t card) мало????

Мало того. Мне вообще за годы покер писательства ниразу не приходилось заглядывать внутрь этих файлов.
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
25.05.2015, 16:58 24
Цитата Сообщение от nefton Посмотреть сообщение
но к чему это??? ... аналогично ...
Я просто скопипастил ваше сжатие.
Я не занимался картами столько лет, точнее я вообще ими не занимался и о покере ничего не знаю
Цитата Сообщение от nefton Посмотреть сообщение
А вот и пошли магические номера. Парадигма enum class подразумевает отказ от номеров (даже порядковых)
надо:
C++
1
2
3
4
5
Suit suit() const
 {
 if (((cardValue_ & 0x30) >> 4) == 0) return Suit::spades;
 ......
 }
Я позволю сделать это компилятору вместо меня

Цитата Сообщение от nefton Посмотреть сообщение
Замечу привязка к битовой карте (которая должна быть гдето описанна по русски отдельно) - осталась
и все магические номера соответственно
Битовая карта конечно осталась, это правда отличная идея сжимать данные, если ими остаётся возможность пользоваться.
И собственно я написал лишь компайл тайм сжатие любой руки и не более. ( и я сжал в long, ибо не вкурил быстро ваш вариант)
И хотел показать что всё можно инкапсулировать и получить хорушую производительность на вашу фразу:
Цитата Сообщение от nefton
класс card - не нужен. Как ты потом будешь руки сравнивать?
ты если и напишешь эту функцию - то удалишь её сразу из за её убогости и тормознутости.
во всём мире давно руки сравнивают с помощью битовых операций.
Я не сомневаюсь что ваш код работает и достаточно хорошо, и вы его знаете и т.д., но для меня этот код - совершенно не понятен при первом просмотре, ибо там идёт "жесткая математка" без коммментариев и абстракций которые можно добавить ни в грамм ни ухудшив производительнось. Вам это не нужно, за годы вы всё точно там знаете и всё обдумали, но в тру ООП и бла бла бла, оно лишним никогда не будет, и человек тут учится не покеру а С++ .

Цитата Сообщение от nefton Посмотреть сообщение
Неужели есть в жизни хоть 1 ситуация где функции string CardToString(card_t card) мало????
Это просто не ООПшный подход, поэтому мне не нравится . Памяти тут экономится несказанно мало, процессор нужно смотреть насколько часто нужно вам строковое представление, предполагаю что вообще никогда , поэтому как-то неважен этот момент, но не тру ООП (если у меня добавить такую штуку, то тоже сжатие изменится)

Цитата Сообщение от nefton Посмотреть сообщение
Реально надо только 1 функция перевода 7 карт в руку (4х байтное число) которое можно >,<,>=,<=,==,!=
Я играю в покер только пьяным, так что не знаю точно всего этого, сорри Я лишь хотел показать что от ничего не говорящих конструкций:
C++
1
if ((cards&0x1F00)==0x1F00)return 13;
можно отказаться не ухудшив производительность, просто заменив калькулятор на компилятор


И я в примере немного загнался, в голове прочно сидел массив карт, поэтому появились constexpr, можно даже легче и без них сжать.
0
45 / 21 / 6
Регистрация: 28.02.2013
Сообщений: 194
25.05.2015, 17:46 25
Перестаньте писать классы

И рука (7 карт) компонуются в число не для экономии памяти или чегото там, а для того чтоб сравнить руки у 5ти человек к примеру кто победил.
Кроме моего подсчёта силы руки есть ещё с десяток вариантов, написанных независимо в разное время в разных частях света. И все они битовые
Ну есть конечно не битовые - только все что мне встречались - с ошибками. Тоесть не считают правильно все руки
Если бы использование классов реально привело б к хоть какойто удобочитаемости.... но это не тот случай. Тут не будет понятнее с классами. А вот скорость тут очень надо. В самом примитивном калькуляторе эта функция вызывается 100 000 раз при каждом подсчёте вероятностей.
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
25.05.2015, 18:34 26
Цитата Сообщение от nefton Посмотреть сообщение
Перестаньте писать классы
Иногда когда пишу на яве, я тоже хочу такое сказать )), но в большей степени я за "пишите классы, да не скромничайте", имхо, которое таки доказано немалыми проектами, но имхо, я не хочу холивара

Цитата Сообщение от nefton Посмотреть сообщение
Ну есть конечно не битовые - только все что мне встречались - с ошибками. Тоесть не считают правильно все руки
Если бы использование классов реально привело б к хоть какойто удобочитаемости.... но это не тот случай. Тут не будет понятнее с классами. А вот скорость тут очень надо. В самом примитивном калькуляторе эта функция вызывается 100 000 раз при каждом подсчёте вероятностей.
Я понимаю что это для производительности, поэтому и сохранил вашу идею, которая после компиляция превратится в вашу реализацию.
И удобочитаемость, это для вас удобно, вы много разных реализаций повидали и понимаете всю математику, а я только вашу, и мне она заходит тяжко. Это как еслиб я вместо инлайна умножение матриц в 3д явно писал))) (конечно неравноценный пример, но всё же).
Я не предлагаю переписать вам ваш проект, я за-то чтобы кто будет это читать понимали что есть такая возможность, не только для динамических рук, но и сравнение со статическими руками(разными комбинациями из правил игры)
0
1 / 1 / 1
Регистрация: 28.07.2013
Сообщений: 41
28.05.2015, 16:28  [ТС] 27
Всем спасибо, кто откликнулся, но вы меня напугали я же новичек...
Спасибо за коды, интересно, поучительно, но не все понятно. А так же хотелось бы уточнить: чем плохи классы? Роберт Лафоре учил создавать и не стесняться.
0
28.05.2015, 16:28
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.05.2015, 16:28
Помогаю со студенческими работами здесь

При запуске в code::blocks появляются ошибки "<название> was not declared in this scope"
Проект состоит из четырех файлов. Main.cpp, TestList.cpp, List.h, Sequence.h В последнем...

Список с дробями: Variable or field 'input' declared void 'pd' was not declared in this scope
почему не нравится 1ая функция? #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; struct rational_fraction...

Ошибки "... was not declared in this scope"
Здравствуйте. Помогите пожалуйста разобраться с ошибками. #include &lt;iostream&gt; #include &lt;stdio.h&gt;...

'...' was not declared in this scope
Доброго времени суток. Столкнулся с одной проблемой при создании класса: имеется описание класса :...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru