-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBuscaminas.cpp
445 lines (352 loc) · 12.5 KB
/
Buscaminas.cpp
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
#include <iostream> //Liberaria para utilizar entrada y salida de datos (cout y cin)
#include <stdlib.h> //Libreria para ejecutar comando externo(system)
#include <time.h> //Libreria para la función aleatoria
void titulo();
void nombre(char usuario[]);
void ingresobomba(int *nbombas); //Declaración
void limpiarmatriz(int tablero[][10], int aux[][10], int aux2[][10]);
void generarbomba(int tablero[][10], int nbombas); //Prototipos de los subprogramas utilizados
void jugada(int aux[][10], int *x, int *y, int *njugadas, int *puntaje, int nbombas);//las variables que están acompañadas de asteriscos se pasan por referencia
void establecernum(int tablero[][10]);
void tablero1(int tablero[][10], int aux[][10], int x, int y);
void ganarperder(int tablero[][10], int x, int y, int njugadas, int nbombas, int *ganados, int *perdidos, int destapados);
void informacion();
void menu(int *opcion);
void partidas(char usuario[], int perdidos, int ganados, int puntaje);
void destaparadyac(int aux[][10], int x, int y);
void destapadas(int aux[][10], int x, int y, int *destapados, int aux2[][10]);
using namespace std; //Para pasar un arreglo bidimensional como parámetro se necesita especificar el tamaño de la segunda dimensión
int main(){ //PROGRAMA PRINCIPAL
int tablero[10][10],aux[10][10],x,y,nbombas=0,bombas=9,njugadas=0,puntaje=0,ganados=0,perdidos=0,jugar=0,opcion,destapados=0, aux2[10][10];
char usuario[50];
do{
menu(&opcion);
switch(opcion)
{
case 1:
system("cls");
do{
titulo();
nombre(usuario);
ingresobomba(&nbombas);
limpiarmatriz(tablero, aux, aux2); //En cada inicio del bucle se reinicia el tablero
generarbomba(tablero, nbombas); //Llamada a los subprogramas //Estos subprogramas se repiten una vez, ya que no están adentro del ciclo
establecernum(tablero);
njugadas=0; //Al iniciar el bucle se reinicia el num de jugadas y el puntaje
puntaje=0;
x=-4;
y=-4; //Se borra registro de la última casilla seleccionada, y se dan las coordenadas (-4, -4) para evitar que coincida con alguna casilla del tablero
destapados=0; //Se reinicia las casillas destapadas para volver a jugar
while(tablero[x][y]!=bombas || destapados!=(64-nbombas)) //los subprogramas seleccionadas se encuentran en un ciclo while para repetirlos cierta cantidad de veces
{
titulo();
tablero1(tablero, aux, x, y);
destapadas(aux, x, y, &destapados, aux2);
ganarperder(tablero, x, y, njugadas, nbombas, &ganados, &perdidos, destapados); //las variables que están acompañadas con andpersand se pasan por referencia //Se revisa la cantidad de casillas destapadas (aux[i][j]=1)
if(tablero[x][y]==bombas || destapados==(64-nbombas)) //si pierde o gana se muestra partidas, sino sigue jugando
{
partidas(usuario, perdidos, ganados, puntaje);
break;
}
else
{
jugada(aux, &x, &y, &njugadas, &puntaje, nbombas);
}
}
cout<<"¿Desea volver a jugar?"<<endl;
cout<<"\n"<<"5. Si."<<endl;
cout<<"6. No."<<endl;
cout<<"\n"<<"Opcion: ";
cin>>jugar;
while(!cin)
{
cin.clear();
cin.ignore();
cin>>jugar;
}
system("cls");
}while(jugar!=6);
case 2:
system("cls");
informacion();
break;
case 3:
break;
default:
cout<<"\n"<<"Opcion no valida."<<endl;
}
}while(opcion!=3);
return 0;
}
void titulo()
{
cout<<" *----------------------------------*"<<endl;
cout<<" *----------------------*"<<endl;
cout<<" BUSCAMINAS"<<endl;
cout<<" *----------------------*"<<endl;
cout<<" *----------------------------------*"<<endl;
cout<<" "<<endl;
}
void nombre(char usuario[])
{
cout<<"\n"<<"\t"<<"Nombre del jugador: ";
cin>>usuario;
}
void ingresobomba(int *nbombas) //Se pasa por referencia para mantener el valor durante la ejecución de otros subprogramas
{
cout<<"\n"<<"\t"<<"Ingrese cantidad de bombas (1 - 64): "; //Cantidad de bombas que ingresa el usuario con las que desea jugar
do{
cin>>*nbombas;
if(*nbombas<1 || *nbombas>64)
{
cout<<"\n"<<"Ingrese un numero valido. "<<endl;
}
while(!cin) //Condicion para evitar que el usuario ingrese otro tipo de dato diferente al entero
{
cout<<endl<<"\n"<<"Ingrese un numero entero: "; //Si ingresa un tipo de dato diferente entonces entra en el ciclo while
cin.clear();
cin.ignore(); //Limpia el contenido basura en el buffer de entrada e ignora los caracteres y lo vuelve a pedir mientras sea diferente a entero
cin>>*nbombas;
}
}while(*nbombas<1 || *nbombas>64); //Hacer mientras no cumpla con los requisitos
system("cls"); //Limpiar pantalla para la siguiente ejecución
}
void generarbomba(int tablero[][10], int nbombas)
{
int i,j,p;
srand(time(NULL)); //Inicializa el generador de números aleatorios diferentes en cada ejecución
for(p=0;p<nbombas;p++) //Repetir hasta la cantidad de bombas ingresadas
{
int bombas=9;
do{
i = 1+rand()%8; //generar bombas de forma aleatoria, dandole un valor aleatorio a "x" e "y" entre 1 y 8
j = 1+rand()%8;
}while(tablero[i][j]==bombas); //Control para que no se repitan las coordenadas para colocar bomba
//Si en una coordenada generada de forma aleatoria ya existe bomba entonces genera otras
tablero[i][j]=bombas; //Esa posición generada equivale a una bomba(9)
}
}
void limpiarmatriz(int tablero[][10], int aux[][10], int aux2[][10])
{
int i,j,bombas=9; //La variable bomba se identifica con el número 9
for(i=1;i<9;i++)
{
for(j=1;j<9;j++)
{ //Limpiar matrices para reiniciar el tablero
tablero[i][j]=0;
aux[i][j]=0; //Matriz auxiliar para marcar las casillas destapadas
aux2[i][j]=0; //Matriz auxiliar para marcar las casillas revisadas
}
}
}
void jugada(int aux[][10], int *x, int *y, int *njugadas, int *puntaje, int nbombas)
{
do
{
cout<<"----------------------------------------------"<<endl;
cout<<" Puntos: "<<*puntaje<<endl;
cout<<" Jugadas: "<<*njugadas<<endl;
cout<<" Bombas: "<<nbombas<<endl; //Interfaz del usuario
cout<<"------------------"<<endl;
cout<<"Jugada: "<<endl;
cout<<"------------------"<<endl;
cout<<"Ingrese fila: ";
cin>>*x;
while(!cin)
{
cout<<"Ingrese un numero entero: "<<endl;
cin.clear();
cin.ignore();
cin>>*x;
} //Usuario ingresa fila(x) y columna(y) para seleccionar la casilla correspondiente al tablero
cout<<"Ingrese columna: ";
cin>>*y;
while(!cin)
{
cout<<"Ingrese un numero entero: "<<endl;
cin.clear();
cin.ignore();
cin>>*y;
}
if((*x>1 && *x<9) && (*y>1 && *y<9) && (aux[*x][*y]!=1))
{
*njugadas=*njugadas+1;
*puntaje=*puntaje+10; //Se incrementa las veces jugadas y el puntaje cada vez que el usuario juega y cumple las condiciones
}
else
{
cout<<"\n"<<"Ingrese numeros validos."<<endl;
cout<<" "<<endl;
}
}while((*x<1 || *x>9) || (*y<1 || *y>9)); //Hacer mientras no ingrese números que se salgan de la matriz
aux[*x][*y]=1; //Matriz lógica usada para marcar una casilla destapada, dicha casilla se identifica con el valor 1
system("cls"); //Se limpia la pantalla cada vez que el usuario juega
}
void establecernum(int tablero[][10])
{
int i,j,num,bombas=9;
for(i=1;i<9;i++)
{
for(j=1;j<9;j++)
{
num = 0; //El valor de num se reinicia en cada iteración para asignarle el nuevo valor a la casilla siguiente
if (tablero[i][j]!=bombas) //Si en la casilla no existe bomba entonces se coloca un numero dependiendo de la cantidad de bombas alrededor
{
if (tablero[i+1][j]==9)
num++;
if (tablero[i][j+1]==9)
num++;
if (tablero[i-1][j]==9)
num++;
if (tablero[i][j-1]==9)
num++; //Contar bombas en casillas adyacentes para asignarle el valor a dicha casilla
if (tablero[i+1][j+1]==9)
num++;
if (tablero[i-1][j-1]==9)
num++;
if (tablero[i-1][j+1]==9)
num++;
if (tablero[i+1][j-1]==9)
num++;
tablero[i][j]=num;
} //Almacena todos los numeros en la matriz
}
}
}
void tablero1(int tablero[][10], int aux[][10], int x, int y)
{
int i,j,bombas=9;
cout<<"----------------------------------------------"<<endl;
cout<<" [X] ";
for(j=1;j<9;j++)
{
cout<<"[ "<<j<<" ]";
}
cout<<endl<<"----------------------------------------------"<<endl; //generar tablero
for(i=1;i<9;i++)
{
cout<<"[ "<<i<<" ]";
for(j=1;j<9;j++)
{
if(tablero[x][y]==0) //Si la posición seleccionada contiene el valor cero entonces..
{
destaparadyac(aux, x, y); //Se marcan las casillas adyacentes como destapadas para que abajo las mismas se muestran
} //Se coloca fuera del condicional para que itere desde el principio
if(x==i && y==j) //entra en el condicional si la casilla seleccionada equivale a la posicion del tablero
{
if(tablero[i][j]==bombas) //Si en la casilla hay bomba se muestra un asterisco
{
cout<<" "<<" * "<<" ";
}
if(tablero[i][j]!=bombas) //Si en la casilla no hay bomba entonces se muestra el numero correspondiente(i,j)
{
cout<<" "<<tablero[i][j]<<" ";
}
}
else if(aux[i][j]==1) //Si la casilla del tablero fue destapada entonces la misma se muestra de forma permanente en el tablero
{
cout<<" "<<tablero[i][j]<<" ";
}
else
{
cout<<" "<<" - "<<" "; //Si la casilla no fue destapada (!=1) entonces se mantiene tapada(-)
}
}
cout<<endl;
}
}
void ganarperder(int tablero[][10], int x, int y, int njugadas, int nbombas, int *ganados, int *perdidos, int destapados)
{
int i,j,bombas=9;
if(tablero[x][y]==bombas) //Si el usuario ingresa una casilla que contiene bomba entonces pierde
{
*perdidos=*perdidos+1;
cout<<" --------------------------------------------"<<endl;
cout<<"\n"<<"\t"<<"\t"<<"OH, HAS PERDIDO :( !"<<endl;
cout<<" "<<endl;
cout<<" --------------------------------------------"<<endl;
cout<<endl<<"SOLUCION: "<<endl; //Si pierde entonces se muestra la solución, es decir, la matriz destapada
cout<<"----------------------------------"<<endl;
cout<<" "<<endl;
for(i=1;i<9;i++)
{
for(j=1;j<9;j++)
{
if(tablero[i][j]==bombas)
{
cout<<" "<<" * "<<" "; //tablero mostrado despues de perder
}
else if(tablero[i][j]!=bombas)
{
cout<<" "<<tablero[i][j]<<" ";
}
}
cout<<endl;
}
}
else if(destapados==(64-nbombas)) //Condicion para ganar
{
*ganados=*ganados+1;
cout<<" --------------------------------------------"<<endl;
cout<<"\n"<<"\t"<<"\t"<<"¡FELICIDADES, HAS GANADO LA PARTIDA!"<<endl;
cout<<" "<<endl;
cout<<" --------------------------------------------"<<endl;
}
}
void informacion()
{
cout<<"\n"<<"\t"<<"\t"<<"#Codigo desarrollado por Tomas Ortiz."<<endl;
cout<<"\t"<<"\t"<<"#Licenciatura en Informatica y desarrollo de software."<<endl;
cout<<"\t"<<"\t"<<"#Version del juego: 1.0"<<endl;
}
void menu(int *opcion)
{
cout<<"\n"<<"\t"<<"\t"<<"\t"<<"\t"<<"MENU"<<endl;
cout<<"\t"<<"\t"<<"\t"<<"--------------------------"<<endl;
cout<<"\t"<<"\t"<<"\t"<<"1. Iniciar partida"<<"\n"<<endl;
cout<<"\t"<<"\t"<<"\t"<<"2. Informacion"<<"\n"<<endl;
cout<<"\t"<<"\t"<<"\t"<<"3. Salir"<<"\n"<<endl;
cout<<"\n"<<"Opcion: ";
cin>>*opcion;
while(!cin)
{
cin.clear();
cin.ignore();
cin>>*opcion;
}
}
void partidas(char usuario[], int perdidos, int ganados, int puntaje)
{
cout<<"\n"<<"----------------------------------"<<endl;
cout<<"Jugador: "<<usuario<<endl;
cout<<"Puntaje obtenido: "<<puntaje<<endl;
cout<<"Partidas ganadas: "<<ganados<<endl;
cout<<"Partidas perdidas: "<<perdidos<<endl;
cout<<"----------------------------------"<<endl;
}
void destaparadyac(int aux[][10], int x, int y)
{
aux[x-1][y-1]=1; //8 casillas alrededor de la seleccionada
aux[x-1][y]=1;
aux[x-1][y+1]=1; //Las casillas alrededores se marcan como ya destapadas (1) para que en tablero1 las mismas se muestren
aux[x][y-1]=1;
aux[x][y+1]=1;
aux[x+1][y-1]=1;
aux[x+1][y]=1;
aux[x+1][y+1]=1;
}
void destapadas(int aux[][10], int x, int y, int *destapados, int aux2[][10])
{
int i,j;
for(i=1;i<9;i++)
{
for(j=1;j<9;j++)
{
if(aux[i][j]==1 && aux2[i][j]!=2) //Se revisa cuantas casillas han sido destapadas, para luego hacer el calculo si gana
{
*destapados=*destapados+1;
aux2[i][j]=2; //Matriz auxiliar que marca las casillas que ya han sido contadas
}
}
}
}