Skip to content

Commit be08b64

Browse files
José Miguel Sánchez AlésJosé Miguel Sánchez Alés
authored andcommitted
Añade soluciones basadas en OO (Javascript)
1 parent ed1624b commit be08b64

File tree

3 files changed

+725
-0
lines changed

3 files changed

+725
-0
lines changed
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
"use strict";
2+
3+
/**
4+
* @file Realiza tiradas de dos dados hasta que en una misma tirada
5+
* los dos dados sacan la misma puntuación.
6+
* @license {@link https://www.mit.edu/~amini/LICENSE.md|MIT}
7+
* @author José Miguel Sánchez Alés <jsanale860@g.educaand.es>
8+
*/
9+
10+
/**
11+
* Número de datos lanzados en una tirada.
12+
* @type {number}
13+
*/
14+
const numDados = 2,
15+
/**
16+
* Número de caras de cada dado.
17+
* @type {number}
18+
*/
19+
numCaras = 6;
20+
21+
/**
22+
* Genera un entero aleatorio entre un límite inferior
23+
* y un límite superior
24+
*
25+
* @param {number} min - El límite inferior.
26+
* @param {number} max - El límite superior.
27+
*
28+
* @example
29+
* generarAleatorio(0, 10); // Entero entre 0 y 10 (ambos inclusive)
30+
*
31+
* @returns {number} - El entero aleatorio.
32+
*/
33+
function generarAleatorio(min, max) {
34+
return Math.round(Math.random()*(max - min)) + min;
35+
}
36+
37+
/**
38+
* Clase que representa un dado en los juegos de azar.
39+
* @class
40+
* @name Dado
41+
*
42+
* @example
43+
* const dado1 = new Dado(6), // Dos dados de seis caras.
44+
* dado2 = new Dado(6);
45+
* dado1.tirar();
46+
* dado2.tirar();
47+
*
48+
* let total = dado1 + dado2; // Se obtiene la puntuación de ambos dados.
49+
*/
50+
class Dado {
51+
52+
/**
53+
* Almacena el número de caras del dado.
54+
* @type {number}
55+
*/
56+
#caras;
57+
/**
58+
* Valor de la última tirada.
59+
* @type {number}
60+
*/
61+
valor;
62+
63+
/**
64+
* Crea el dado.
65+
* @param {number} caras
66+
*/
67+
constructor(caras) {
68+
this.#caras = caras;
69+
}
70+
71+
/**
72+
* Simula el lanzamiento de un dado, generando un número al azar.
73+
*
74+
* @returns {Number} - El resultado aleatorio entre 1 y el número de caras.
75+
*/
76+
tirar() {
77+
return this.valor = generarAleatorio(1, this.#caras);
78+
}
79+
80+
/**
81+
* Vuelve el dado a su estado inicial antes de haberse tirado (valor está indefinido).
82+
*/
83+
reset() {
84+
delete this.valor;
85+
}
86+
87+
/**
88+
* Al tratarse como número, el dado devuelve su valor.
89+
* @returns {number} - El valor de la última tirada.
90+
*/
91+
valueOf() {
92+
return this.valor;
93+
}
94+
95+
/**
96+
* Número de caras del dado.
97+
* @type {number}
98+
*/
99+
get caras() {
100+
return this.#caras;
101+
}
102+
}
103+
104+
105+
/**
106+
* Clase para almacenar las tiradas en una partida de dados.
107+
*/
108+
class Registro {
109+
/**
110+
* Almacena las tiradas del registro.
111+
* @type {Number[][]}
112+
*/
113+
#log;
114+
/**
115+
* Función que define qué tiradas son ganadoras.
116+
*/
117+
#fin;
118+
119+
/**
120+
* Crea un registro de tiradas.
121+
* @param {Registro~finCallback} fin - Condición que determina el final del registro.
122+
*/
123+
constructor(fin) {
124+
this.#log = [];
125+
this.#fin = fin;
126+
}
127+
128+
/**
129+
* Comprueba si las tiradas son ganadoras.
130+
* @callback Registro~finCallback
131+
* @param {Number[][]} tiradas - Las tiradas de la partida.
132+
* @returns {boolean}
133+
*/
134+
135+
/**
136+
* Apunta la tirada en el registro.
137+
*
138+
* @param {Number[]} apunte - Resultados de la tirada de dados. Si la tirada
139+
* consiste en tirar dos dados, el array tendrá un tamaño de 2; si tres
140+
* dados, 3; y así sucesivamente.
141+
* @returns {Number[]} - El propio apunte.
142+
*/
143+
apuntar(apunte) {
144+
if(this.cerrado) return false;
145+
this.#log.push(apunte);
146+
return apunte;
147+
}
148+
149+
/**
150+
* Vacía el registro por completo.
151+
*/
152+
vaciar() {
153+
this.#log.length = 0;
154+
}
155+
156+
/**
157+
* Devuelve el tamaño del registro.
158+
* @type {number}
159+
*/
160+
get tamanho() {
161+
return this.#log.length;
162+
}
163+
164+
/**
165+
* Indica si el registro está cerrado, porque se alcanzó la tirada ganadora.
166+
*
167+
* @type {boolean}
168+
*/
169+
get cerrado() {
170+
return this.#fin(this.#log);
171+
}
172+
173+
/**
174+
* Indica si el registro no se ha usado aún.
175+
*
176+
* @type {boolean}
177+
*/
178+
get nuevo() {
179+
return this.#log.length === 0;
180+
}
181+
}
182+
183+
184+
/**
185+
* Modela una partida de dados.
186+
*/
187+
class Partida {
188+
/**
189+
* Dado para gestionar las tiradas de dados. Basta con uno solo, simplemente,
190+
* se usará todas las veces que sea necesario.
191+
* @type {Dado}
192+
*/
193+
#dado;
194+
/**
195+
* Número de dados por tirada que necesita el juego.
196+
* @type {number}
197+
*/
198+
#dados;
199+
/**
200+
* Registro que almacena los resultados de las tiradas.
201+
* @type {Registro}
202+
*/
203+
#registro;
204+
205+
/**
206+
*
207+
* @param {Partida~reglas} reglas - Reglas
208+
* para la creación de la partida. Se puede proporcionar un dado o un número de caras y, si
209+
* se proporcionan ambas, prevalece el dado.
210+
*
211+
* @example
212+
*
213+
* // Se gana la partida cuando se saca un 6.
214+
* const reglas = {
215+
* dados: 1,
216+
* caras: 6,
217+
* fin: (tiradas) => tiradas?.some(e => e[0] === 6)
218+
* }
219+
*
220+
* const partida = Partida(reglas);
221+
* while(!partida.fin) {}
222+
* console.log(`Ha tirado ${partida.ronda} veces hasta sacar un 6.`);
223+
*/
224+
constructor({dado, dados, caras, fin = () => false}) {
225+
// Con un dado basta para cubrir la partida.
226+
this.#dado = dado??new Dado(caras);
227+
this.#dados = dados;
228+
this.#registro = new Registro(fin);
229+
}
230+
231+
/**
232+
* @typedef {Object} Partida~reglas
233+
*
234+
* @property {Dado} dado - Dado que se usa en la partida.
235+
* @property {number} dados - Número de dados para cada tirada.
236+
* @property {number} caras - Número de caras del dado (opcional a dado).
237+
* @property {Registro~finCallback} fin - Función que comprueba si la tirada es ganadora.
238+
*/
239+
240+
/**
241+
* Simula una tirada de dados.
242+
* @returns {Number[]} - El resultado de la tirada de dados.
243+
*/
244+
lanzar() {
245+
return this.#registro.apuntar(Array(this.#dados).fill(null).map(_ => this.#dado.tirar()));
246+
}
247+
248+
/**
249+
* Cantidad de dados que necesita la tirada.
250+
*
251+
* @type {number}
252+
*/
253+
get dados() {
254+
return this.#dados;
255+
}
256+
257+
/**
258+
* Si la partida ha acabado, porque se alcanzó la tirada ganadora.
259+
*
260+
* @type {boolean}
261+
*/
262+
get fin() {
263+
return this.#registro.cerrado;
264+
}
265+
266+
/**
267+
* Indica si la partida no ha comenzado (aún no se han tirado dados)
268+
*
269+
* @type {boolean}
270+
*/
271+
get comienzo() {
272+
return this.#registro.nuevo;
273+
}
274+
275+
/**
276+
* Reinicia la partida.
277+
*/
278+
reset() {
279+
this.#registro.vaciar();
280+
}
281+
282+
/**
283+
* Devuelve el cantidad de rondas jugadas.
284+
*
285+
* @type {number}
286+
*/
287+
get ronda() {
288+
return this.#registro.tamanho;
289+
}
290+
}
291+
292+
// Programa principal
293+
294+
const reglas = {
295+
dados: 2,
296+
caras: 6,
297+
// Se gana cuando en la tirada se saca lo mismo con todos los dados.
298+
fin: (tiradas) => tiradas?.at(-1)?.every((e, _, arr) => e === arr[0])
299+
}
300+
301+
const partida = new Partida(reglas);
302+
while(!partida.fin) {
303+
console.log(`${partida.ronda + 1}ª tirada: ${partida.lanzar().join("-")}.`);
304+
}
305+
console.log(`Se han tardado ${partida.ronda} tiradas en acabar el juego.`);

0 commit comments

Comments
 (0)