-
Notifications
You must be signed in to change notification settings - Fork 0
/
Chess.h
453 lines (407 loc) · 12.8 KB
/
Chess.h
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
#ifndef CHESS_H_INCLUDED
#define CHESS_H_INCLUDED
#include "ChessExceptions.h"
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Audio/Music.hpp>
#include <SFML/Audio/Sound.hpp>
#include <list>
#include <assert.h>
using namespace std;
using namespace sf;
//Estructura del Ajedrez
struct Chess{
// Carga strings estaticos constantes para colocar las direcciones de las texturas de tablero y piezas
static const string BOARD_SPRITESHEET_FILENAME;
static const string PIECES_SPRITESHEET_FILENAME;
};
static const string TIMER_FRAME_FILE = "./assets/Marco_reloj.png";
static const string TIMER_HAND_FILE = "./assets/Manecilla.png";
// Metodo para cargar las texturas
static Texture loadResource(string filename){
Texture texture;
cout <<filename<<"\n"; // DEV
if(!texture.loadFromFile(filename)){
throw ChessImageException();
}
return texture;
}
// Estructura que almacena el manejo de cordenadas en el tablero por cada pieza
struct ChessCoord {
// Declaración de la constante estática de tamaño para la unidad de pixeles
static const int SIZE;
int valueX, y;
char x;
ChessCoord() {
x = 'A';
valueX = 1;
y = 1;
}
ChessCoord(char x, int y) {
setX(x);
setY(y);
}
ChessCoord(int x, int y) {
setValueX(x);
setY(y);
}
void setX(char _x) {
int _valueX = getValueFromX(_x);
assert(_valueX >= 0 && _valueX <= 8);
x = _x;
valueX = _valueX;
}
void setY(int _y) {
assert(_y >= 0 && _y <= 8);
y = _y;
}
void setValueX(int _valueX) {
assert(_valueX >= 0 && _valueX <= 8);
valueX = _valueX;
x = getXFromValue(_valueX);
}
static int getValueFromX(char x) {
return ((int)x - 64);
}
static char getXFromValue(int x) {
return ((char)x + 64);
}
Vector2f getScreenPosition() {
Vector2f result((float) SIZE * (valueX - 1), (float) SIZE * (y - 1));
return result;
}
template <typename T>
static ChessCoord getChessPosition(T pxX, T pxY) {
int pxX_I=pxX/ChessCoord::SIZE+1;
int pxY_I=pxY/ChessCoord::SIZE+1;
return ChessCoord(pxX_I,pxY_I);
}
ChessCoord operator + (const ChessCoord& obj) {
ChessCoord result;
result.y = y + obj.y;
result.valueX = valueX + obj.valueX;
assert(result.valueX >= 0 && result.valueX <= 8);
assert(result.y >= 0 && result.y <= 8);
result.x = getXFromValue(result.valueX);
return result;
}
ChessCoord operator - (const ChessCoord& obj) {
ChessCoord result;
result.y = y - obj.y;
result.valueX = valueX - obj.valueX;
assert(result.valueX >= 0 && result.valueX <= 8);
assert(result.y >= 0 && result.y <= 8);
result.x = getXFromValue(result.valueX);
return result;
}
ChessCoord operator += (const ChessCoord& obj) {
*this = *this + obj;
return *this;
}
ChessCoord operator -= (const ChessCoord& obj) {
*this = *this - obj;
return *this;
}
bool operator == (const ChessCoord& obj) {
return (this->valueX==obj.valueX&&this->y==obj.y);
}
bool operator != (const ChessCoord& obj) {
return (this->valueX!=obj.valueX||this->y!=obj.y);
}
friend ostream& operator <<(ostream& os, ChessCoord& coord) {
os << coord.x << coord.y;
return os;
}
friend istream& operator >>(istream& iStream, ChessCoord& coord) {
iStream >> coord.x >> coord.y;
return iStream;
}
};
// Estructura de tipos de piezas
struct ChessPieceTypes{
static const int K=0; // King
static const int Q=1; // Queen
static const int B=2; // Bishop
static const int H=3; // Horse
static const int T=4; // Tower
static const int P=5; // Pawn
// Regresa el área del spritesheet en el que se encuentra la pieza con el color y el tipo mandados
static IntRect getSpriteIntRectByColorType(int color, int pieceType){
try{
validate(pieceType,color);
}catch(PieceTypeException& Piece){
cout<<"Excepcion de pieza atrapada: " << Piece.what() << endl;
}catch(PieceColorException& Color){
cout<<"Excepcion de color atrapada: " << Color.what() << endl;
}catch(...){
cout<<"ERROR 404 :C\n";
}
int pieceTypePX=pieceType*ChessCoord::SIZE;
int colorPX=color*ChessCoord::SIZE;
return IntRect(pieceTypePX, colorPX, ChessCoord::SIZE, ChessCoord::SIZE);
}
// Validar si la pieza es valida según el tipo y el color
static void validate(int pieceType, int color){
try{
if(pieceType<0||pieceType>= 6){
throw PieceTypeException();
}else if(color<0||color>=2){
cout<<"The color isn't valid\n";
throw PieceColorException();
}
}catch(bad_alloc& memoria){
cout << "Error en la memoria..." << memoria.what();
}
}
};
//Estructura de piezas, importante para la creacion y el manejo de cada una
struct ChessPiece
{
/* Atributos estáticos de piezas */
static const Texture spriteSheet;
static int numberOfPieces;
static const int COLOR_WHITE=0;
static const int COLOR_BLACK=1;
static const int TYPE_PAWN=5;
/* Metodos estáticos de piezas */
// Implementación del metodo estático para crear piezas, que se encuentra dentro de ChessPiece
static ChessPiece* createPiece(ChessCoord _position, int pieceType, int color){
ChessPiece *newPiece=new ChessPiece(_position, pieceType, color);
numberOfPieces++;
return newPiece;
}
static void operator delete(void *ptr) {
numberOfPieces--;
::operator delete(ptr);
}
/* Atributos de piezas*/
ChessCoord position;
Sprite sprite;
int pieceType;
/* Constructores de piezas */
ChessPiece()
{
cout<<this<<"\n"; // DEV
position = ChessCoord(0, 0);
}
ChessPiece(ChessCoord _position, int _pieceType, int color)
{
cout<<"C: "<<this<<"\n"; // DEV
pieceType = _pieceType;
setPosition(_position);
setSprite(pieceType, color);
}
ChessPiece(ChessCoord _position, Sprite sprite)
{
cout<<"C: "<<this<<"\n"; // DEV
setPosition(_position);
setSprite(sprite);
}
////////////// METHODS
void setPosition(ChessCoord _position)
{
position = _position;
sprite.setPosition(position.getScreenPosition());
}
void setSprite(int pieceType, int color)
{
sprite = Sprite(spriteSheet,
ChessPieceTypes::getSpriteIntRectByColorType(color,pieceType)
);
sprite.setPosition(position.getScreenPosition());
}
void setSprite(Sprite _sprite)
{
sprite = _sprite;
sprite.setPosition(position.getScreenPosition());
}
friend ostream& operator <<(ostream& os, ChessPiece& piece)
{
os << piece.pieceType<<"("<<piece.position<<")";
return os;
}
bool operator == (const ChessPiece& obj) {
return (position == obj.position && pieceType == obj.pieceType);
}
};
// Inicializar el contador de piezas a 0
int ChessPiece::numberOfPieces=0;
/* Estructura de peón */
struct Pawn : public ChessPiece
{
char icon = 'P';
Pawn()
{
position = ChessCoord(1, 1);
}
Pawn(ChessCoord position, int color)
{
this->position = position;
setSprite(ChessPieceTypes::P, color);
}
Pawn(ChessCoord position, Sprite sprite)
{
this->position = position;
setSprite(sprite);
}
};
struct ChessPlayer{
static int numberOfPlayers;
static ChessPlayer* players;
static int playerInTurn;
static int rivalInTurn;
int numberOfPlayer;
// ChessPiece** pieces;
// Inicialización de lista de apuntadores a piezas, que guardará una lista con todas las piezas en juego.
vector<ChessPiece*> pieces;
int pieceColor;
ChessPlayer(){}
ChessPlayer(int _pieceColor){
numberOfPlayer = numberOfPlayers++;
if(_pieceColor == ChessPiece::COLOR_WHITE){
playerInTurn = numberOfPlayer;
rivalInTurn = (numberOfPlayer+1)%2;
}
pieceColor=_pieceColor;
// pieces = new ChessPiece*[8];
initPieces(_pieceColor);
}
//Metodo para inicializar las piezas
void initPieces(int color) {
int row=1;
if(numberOfPlayer%2==1){
row=8;
}
for (int i = 0; i < 8; i++) {
pieces.push_back(
ChessPiece::createPiece(
ChessCoord(i + 1, row), ChessPiece::TYPE_PAWN, color
)
);
}
}
/* Metodo para crear jugador y retornarlo */
static ChessPlayer createPlayer(int _pieceColor){
ChessPlayer* result=new ChessPlayer(_pieceColor);
return *result;
}
/* Metodo que realiza la busqueda de la pieza a comer */
static void eatPieceRival(ChessPiece* rivalPiece){
vector<ChessPiece*>::iterator aux=players[rivalInTurn].pieces.begin();
for(ChessPiece* piece:players[rivalInTurn].pieces){
if(piece==rivalPiece){
players[rivalInTurn].pieces.erase(aux);
break;
}
aux++;
}
delete rivalPiece;
}
/* Método para realizar la lógica de actualización de turno*/
static void updatePlayerInTurn(){
playerInTurn=rivalInTurn;
rivalInTurn=(rivalInTurn+1)%2;
}
// Obtener piezas del jugador en el turno actual en una posición a partir de los pixeles recibidos
template <typename T>
static ChessPiece** getPiecesOfPlayerInTurnAtPosition(T pxX, T pxY){
ChessCoord coord=ChessCoord::getChessPosition(pxX,pxY);
ChessPiece** results=new ChessPiece*[2];
results[0]=NULL;
results[1]=NULL;
int counter=0;
for(
ChessPiece* piece: players[playerInTurn].pieces
){
if(piece->position==coord){
// cout<<*piece<<" "; // DEV
results[counter]=piece;
counter++;
}
}
return results;
}
// Obtener piezas del rival en el turno actual en una posición a partir de los pixeles recibidos
template <typename T>
static ChessPiece** getPiecesOfRivalInTurnAtPosition(T pxX, T pxY){
ChessCoord coord=ChessCoord::getChessPosition(pxX,pxY);
ChessPiece** results=new ChessPiece*[2];
results[0]=NULL;
results[1]=NULL;
int counter=0;
for(
ChessPiece* piece:players[rivalInTurn].pieces
){
if(piece->position==coord){
// cout<<*piece<<" "; // DEV
results[counter]=piece;
counter++;
}
}
return results;
}
// Obtener piezas del jugador en el turno actual en una posición a partir de la coordenada de ajedrez
static ChessPiece** getPiecesOfPlayerInTurnAtPosition(ChessCoord coord){
ChessPiece** results=new ChessPiece*[2];
results[0]=NULL;
results[1]=NULL;
int counter=0;
for(
ChessPiece* piece:players[playerInTurn].pieces
){
if(piece->position==coord){
// cout<<*piece<<" "; // DEV
results[counter]=piece;
counter++;
}
}
return results;
}
// Obtener piezas del rival en el turno actual en una posición a partir de la coordenada de ajedrez
static ChessPiece** getPiecesOfRivalInTurnAtPosition(ChessCoord coord){
ChessPiece** results=new ChessPiece*[2];
results[0]=NULL;
results[1]=NULL;
int counter=0;
for(
ChessPiece* piece:players[rivalInTurn].pieces
){
if(piece->position==coord){
// cout<<*piece<<" "; // DEV
results[counter]=piece;
counter++;
}
}
return results;
}
};
int ChessPlayer::numberOfPlayers=0;
int ChessPlayer::playerInTurn=0;
int ChessPlayer::rivalInTurn=1;
ChessPlayer* ChessPlayer::players=NULL;
// Estructura del tablero
struct ChessBoard
{
/* Atributos del tablero*/
static const IntRect LIMITS;
Sprite sprite;
Texture texture;
/* Constructores del tablero*/
ChessBoard() {
setBoardImage(Chess::BOARD_SPRITESHEET_FILENAME);
}
ChessBoard(string boardImageFilename) {
setBoardImage(boardImageFilename);
}
/// Cargar la imagen del tablero
void setBoardImage(string boardImageFilename){
try{
texture=loadResource(boardImageFilename);
sprite = Sprite(texture);
}catch(...){
throw BoardImageException();
exit(0);
}
}
};
#endif // CHESS_H_INCLUDED