[go: up one dir, main page]

Menu

[r9]: / trunk / card.h  Maximize  Restore  History

Download this file

219 lines (196 with data), 4.9 kB

  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
/*
* FreeCell for C.L.I. (Command Line Interface)
*
* File : card.h
* Author : Anupam Srivastava
* E-Mail : anupam.srivastava@gmail.com
* Purpose : C++ header file which defines Card class. It is deliberately
* generic for use with any other program.
*
* NOTE:
* This program is derived from FreeCell for DOS v 1.1 by me. It was for Turbo
* C++ v 3.0, and used custom libraries. Most of such code is removed and aim
* of this program is to just be in standard c++. The original program was not
* throughly checked for bugs.
* Any comments and improvements are invited at anupam.srivastava@gmail.com.
*
* Indentation is left to Vim editor.
*
* LICENSE:
* This program is in public domain. If you find this program helpful in
* anyway, you can send me an email and satisfy my narcissistic needs, thus
* making me happy. ;)
*/
#ifndef _CARD_H
#define _CARD_H
#include <string>
#include <sstream>
const int TWO_2 = 2;
const int THREE_3 = 3;
const int FOUR_4 = 4;
const int FIVE_5 = 5;
const int SIX_6 = 6;
const int SEVEN_7 = 7;
const int EIGHT_8 = 8;
const int NINE_9 = 9;
const int TEN_10 = 10;
const int JAILER_11 = 11;
const int QUEEN_12 = 12;
const int KING_13 = 13;
const int ACE_14 = 14;
const char SPADES = 'S';
const char DIAMONDS = 'D';
const char CLUBS = 'C';
const char HEARTS = 'H';
const int INIT_VALUE = 0;
const char INIT_FACE = '\0';
/* Card class represents a playing card with following values:
* TWO_2, THREE_3, FOUR_4, FIVE_5, SIX_6, SEVEN_7, EIGHT_8, NINE_9, TEN_10
* JAILER_11, QUEEN_12, KING_13, ACE_14
* of following suits:
* SPADES, DIAMONDS, CLUBS, HEARTS
*/
class Card {
private:
int value;
char face;
static bool is_valid_value(int card_value);
static bool is_valid_face(char card_face);
public:
Card() : value(INIT_VALUE), face(INIT_FACE) {
}
void reset();
bool set_value(int card_value);
bool set_face(char card_face);
/* bool set_card(int card_value, char card_face);*/
bool is_valid();
std::string get_output_string();
int get_value();
int get_face();
bool is_equal_to(Card card);
bool next_small_alternate(Card card2);
bool next_large_same(Card card2);
};
inline
bool Card::is_valid_value(int card_value) {
if (TWO_2 <= card_value && card_value <= ACE_14) {
return true;
}
return false;
}
inline
bool Card::is_valid_face(char card_face) {
switch (card_face) {
case SPADES:
case DIAMONDS:
case CLUBS:
case HEARTS:
return true;
break;
}
return false;
}
inline
void Card::reset() {
value = INIT_VALUE;
face = INIT_FACE;
}
inline
bool Card::set_value(int card_value) {
if (is_valid_value(card_value)) {
value = card_value;
return true;
}
return false;
}
inline
bool Card::set_face(char card_face) {
if (is_valid_face(card_face)) {
face = card_face;
return true;
}
return false;
}
/* NOTE:
* We can actually define the below function also as following:
*
* bool Card::set_card(int value, char face) {
* returnn set_value(value) && set_face(face);
* }
*
* This will work because of scoping rules in C++. Arguement
* "value" overrides class-global "value".
*/
/*inline
bool Card::set_card(int card_value, char card_face) {
return set_value(card_value) && set_face(card_face);
}*/
inline
bool Card::is_valid() {
return is_valid_value(value) && is_valid_face(face);
}
std::string Card::get_output_string() {
std::string output = "";
if (is_valid()) {
if (value == TEN_10) {
output = "10";
} else if (value == JAILER_11) {
output = "J";
} else if (value == QUEEN_12) {
output = "Q";
} else if (value == KING_13) {
output = "K";
} else if (value == ACE_14) {
output = "A";
} else {
std::stringstream ss;
ss << value;
output = ss.str();
}
output += face;
}
return output;
}
inline
int Card::get_value() {
return value;
}
inline
int Card::get_face() {
return face;
}
inline
bool Card::is_equal_to(Card card) {
return (value == card.get_value() && face == card.get_face());
}
/* card2 comes after card1 (this)
* but in decreasing order and alternate colour
*/
bool Card::next_small_alternate(Card card2) {
bool card2_is_red = false;
bool card1_is_red = false;
if (card2.get_face() == DIAMONDS || card2.get_face() == HEARTS) {
card2_is_red = true;
}
if (face == DIAMONDS || face == HEARTS) {
card1_is_red = true;
}
/* Either value + 1 of card1 = value of card2
* or value of card1 = ACE_14 and value of card2 = 2
*/
return (card2_is_red != card1_is_red
&& ((card2.get_value() + 1 == value)
|| card2.get_value() - ACE_14 + 2 == value));
}
/* card2 comes after card1 (this)
* but in increasing order
*/
bool Card::next_large_same(Card card2) {
/* Either value + 1 of card1 = value of card2
* or value of card1 = ACE_14 and value of card2 = 2
*/
return (face == card2.get_face()
&& (value + 1 == card2.get_value()
|| value - ACE_14 + 2 == card2.get_value()));
}
#endif /* _CARD_H */