Objetivo: En esta ocasión vamos a explicar una de las maneras más sencillas de crear una máquina tragamonedas para Angular
- Disponible para todos los módulos de la aplicación
- Créditos configurables
- Costo por juego personalizado
- Listado de emojis personalizable
- Proyecto existente versión Angular 17 o superior
- Node Js compatible
- Angular standalone components
- Angular signals
- HTML y CSS
import { CommonModule } from '@angular/common';
import { Component, OnInit, input, model, signal } from '@angular/core';
import { winningCombinations } from '../../consts/winningCombinations';
@Component({
standalone: true,
imports: [CommonModule],
selector: 'app-slot-machine',
templateUrl: './slot-machine.component.html',
styleUrl: './slot-machine.component.css'
})
export class SlotMachineComponent implements OnInit {}reelscontendrá la matriz de combinacionescreditsRequirednúmero que representa los creditos necesarios para jugarwinCreditspropiedad de entrada que representa la cantidad de créditos ganadositemspropiedad de entrada que es requerida para rellenarreelscreditspropiedad de 2 vías para gestionar créditos del jugadortimeoutnúmero que representa tiempo de giro de la máquina
export class SlotMachineComponent implements OnInit {
reels = signal([['']]);
creditsRequired = input(1);
winCredits = input(10);
items = input.required<string[]>();
credits = model(1);
private timeout = 3000;
}Algoritmo:
- Crear const
newReelscon arreglo vacío - Iterar desde 0 hasta 3 de 1 en 1
- Crear const
randomEmojiscon arreglo vacío - Iterar desde 0 hasta 3 de 1 en 1
- Obtener índice aleatorio
- Obtener elemento aleatorio
- Agregar elemento a
randomEmojis
- Agregar fila a
newReels
- Crear const
- Asignar
newReelsareels
export class SlotMachineComponent {
//...
private loadReels(): void {
const newReels = [];
for (let i = 0; i < 3; i++) {
const reelEmojis = [];
for (let j = 0; j < 3; j++) {
const randomIndex = Math.floor(Math.random() * this.items().length);
const randomEmoji = this.items()[randomIndex];
reelEmojis.push(randomEmoji);
}
newReels.push(reelEmojis);
}
this.reels.set(newReels)
}
//...
}Archivo con combinaciones
export const winningCombinations = [
[[0, 0], [0, 1], [0, 2]], // Primera fila
[[1, 0], [1, 1], [1, 2]], // Segunda fila
[[2, 0], [2, 1], [2, 2]], // Tercera fila
[[0, 0], [1, 0], [2, 0]], // Primera columna
[[0, 1], [1, 1], [2, 1]], // Segunda columna
[[0, 2], [1, 2], [2, 2]], // Tercera columna
[[0, 0], [1, 1], [2, 2]], // Diagonal descendente
[[2, 0], [1, 1], [0, 2]], // Diagonal ascendente
];Algoritmo:
- Obtener
winningCombinations - Iterar
winningCombinations- Asignar constante
emojidesde las combinaciones - Validar si el emoji aparece en todas las combinaciones de la fila
- Asignar constante
- Retornar resultado
private validateReels(): string | null {
const combinations = winningCombinations;
for (const combination of combinations) {
const emoji = this.reels()[combination[0][0]][combination[0][1]];
if (
combination.every(([row, col]) => this.reels()[row][col] === emoji)
) {
return emoji;
}
}
return null;
}Algoritmo:
- Validar si se cuenta con los créditos requeridos
- Descontar créditos según los créditos requeridos
- Repetir
loadReelscada 100ms - Asignar cuenta atrás para detener repetición
- Validar combinaciones ganadoras para asignar créditos ganados
spin(): void {
if (this.credits() < this.creditsRequired()) return;
this.credits.update(value => value - this.creditsRequired());
const interval = setInterval( () => {
this.loadReels()
}, 100);
setTimeout(() => {
clearInterval(interval);
if (this.validateReels()) {
alert('ganador');
this.credits.update(value => value + this.winCredits());
}
}, this.timeout);
}Sólo queda agregar ngOnInit para llamar loadReels(). El archivo TS completo quedaría así:
import { CommonModule } from '@angular/common';
import { Component, OnInit, input, model, signal } from '@angular/core';
import { winningCombinations } from '../../consts/winningCombinations';
@Component({
standalone: true,
imports: [CommonModule],
selector: 'app-slot-machine',
templateUrl: './slot-machine.component.html',
styleUrl: './slot-machine.component.css'
})
export class SlotMachineComponent implements OnInit {
reels = signal([['']]);
creditsRequired = input(1);
winCredits = input(10);
items = input.required<string[]>();
credits = model(1);
private timeout = 3000;
ngOnInit(): void {
this.loadReels();
}
spin(): void {
if (this.credits() < this.creditsRequired()) return;
this.credits.update(value => value - this.creditsRequired());
const interval = setInterval( () => {
this.loadReels()
}, 100);
setTimeout(() => {
clearInterval(interval);
if (this.validateReels()) {
alert('ganador');
this.credits.update(value => value + this.winCredits());
}
}, this.timeout);
}
private loadReels(): void {
const newReels = [];
for (let i = 0; i < 3; i++) {
const reelEmojis = [];
for (let j = 0; j < 3; j++) {
const randomIndex = Math.floor(Math.random() * this.items().length);
const randomEmoji = this.items()[randomIndex];
reelEmojis.push(randomEmoji);
}
newReels.push(reelEmojis);
}
this.reels.set(newReels)
}
private validateReels(): string | null {
const combinations = winningCombinations;
for (const combination of combinations) {
const emoji = this.reels()[combination[0][0]][combination[0][1]];
if (
combination.every(([row, col]) => this.reels()[row][col] === emoji)
) {
return emoji;
}
}
return null;
}
}Plantilla básica
<div id="slotMachine">
@for (reel of reels(); track $index) {
@for (item of reel; track $index) {
{{item}}
}
}
<button (click)="spin()">JUGAR</button>
</div>Estilos
#slotMachine {
display: flex;
flex-wrap: wrap;
font-size: 96px;
width: 417px;
border: 4px solid #000;
border-radius: 40px;
padding: 16px;
margin: 32px;
background: #222;
}
button {
background: linear-gradient(25deg,blue, red);
border-radius: 8px;
border: none;
color:#ddd;
cursor: pointer;
font-size: 16px;
margin: auto;
padding: 16px;
transform: translateY(16px);
transition: all .3s;
width: 33%;
&:active {
transform: translateY(16px) scale(.7);
}
}Ésta es la versión más reciente de una máquina tragamonedas que he desarrollado y compartido. Lo considero una gran práctica para aprender signal.
- Te reto a agregar premios distintos según las combinaciones
Comentarios
Publicar un comentario