Compare commits

...

10 Commits

42 changed files with 1718 additions and 9573 deletions

View File

@ -1,12 +0,0 @@
[*]
indent_style = space
indent_size = 4
[*.sass]
indent_size = 2
[*.json]
indent_size = 2
[*.yaml]
indent_size = 2

27
.gitignore vendored
View File

@ -1,21 +1,26 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.vscode
*.suo
*.ntvs*
*.njsproj

1
.npmrc
View File

@ -1 +0,0 @@
shamefully-hoist=true

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

24
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,24 @@
pipeline {
agent any
environment {
PATH = "/var/lib/jenkins/.nvm/versions/node/v20.9.0/bin:/var/lib/jenkins/bin:${env.PATH}"
}
stages {
stage('Install') {
steps {
sh 'pnpm i'
}
}
stage('Build') {
steps {
sh './node_modules/.bin/vite build'
}
}
stage('Deploy') {
steps {
sh 'rm -rf /var/www/rimajon-fe/*'
sh 'cp -r ./dist/* /var/www/rimajon-fe/'
}
}
}
}

View File

@ -1,19 +1,40 @@
# rimajon
# rimajon-vue
## Project setup
```
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
pnpm install
```
### Compiles and hot-reloads for development
```
pnpm run serve
### Compile and Hot-Reload for Development
```sh
pnpm dev
```
### Compiles and minifies for production
```
pnpm run build
```
### Type-Check, Compile and Minify for Production
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
```sh
pnpm build
```

View File

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

1
env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

19
index.html Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RiMaJon - Mahjong con cartas</title>
<link href="https://fonts.googleapis.com/css2?family=PT+Serif&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Secular+One&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/resources/phosphor.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -1,35 +1,30 @@
{
"name": "rimajon",
"version": "0.1.0",
"name": "rimajon-vue",
"version": "0.0.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --port 3000",
"build": "vue-cli-service build --modern"
"dev": "vite",
"build": "run-p type-check \"build-only {@}\" --",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "3.0.0",
"vue-router": "4.0.2",
"vuex": "4.0.0-rc.2",
"pug": "^3.0.2",
"sass": "^1.69.5",
"vue": "^3.3.4",
"vue-router": "^4.2.5",
"vuex": "^4.1.0",
"vuex-persist": "^3.1.3"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0",
"phosphor-vue": "^1.0.0",
"pug": "2.0.4",
"pug-plain-loader": "1.0.0",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"typescript": "~3.9.3"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.18.5",
"@vitejs/plugin-vue": "^4.4.0",
"@vue/tsconfig": "^0.4.0",
"npm-run-all2": "^6.1.1",
"typescript": "~5.2.0",
"vite": "^4.4.11",
"vue-tsc": "^1.8.19"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
/* /index.html 200

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -1,20 +0,0 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>RiMaJon - Mahjong con cartas</title>
<link href="https://fonts.googleapis.com/css2?family=PT+Serif&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Secular+One&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/resources/phosphor.css">
</head>
<body class="tema-automatico">
<noscript>
<strong>Para jugar RiMaJon necesitas activar JavaScript.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -1,14 +1,9 @@
<template>
<router-view/>
<div style="display: none;">{{ modoColor }}</div>
</template>
<script setup lang="ts">
import { RouterView } from 'vue-router'
import { useStore } from 'vuex';
import { computed, onMounted, watch } from 'vue';
<script lang="ts">
import { defineComponent, computed, watch } from "vue";
import { useStore } from "vuex";
export default defineComponent({
setup() {
const store = useStore();
const modoColorUsuario = computed<string>(() => store.state.modoColorUsuario);
@ -42,10 +37,10 @@ export default defineComponent({
}
})();
return {
modoColor: modoColorUsuario
}
}
});
</script>
<template>
<RouterView />
<div style="display: none;">{{ modoColor }}</div>
</template>

View File

@ -4,8 +4,7 @@ body
color: var(--color-texto)
margin: 0
// Claro
.tema-automatico
@mixin tema-claro
--color-fondo: #ffffff
--color-texto: #151515
--color-fondo-transparente: rgba(255, 255, 255, 0.8)
@ -18,26 +17,17 @@ body
--color-fondo-reyes: #ffffff
--color-texto-reyes: #2E7D32
--color-mesa-1: #E3F2FD
--color-mesa-2: #90CAF9
.tema-claro
--color-fondo: #ffffff
--color-texto: #151515
--color-fondo-transparente: rgba(255, 255, 255, 0.8)
--color-borde: gray
--color-texto-carta-roja: #b71c1c
--color-fondo-carta-roja: #ffffff
--color-fondo-dragon-rojo: #ffffff
--color-fondo-dragon-verde: #ffffff
--color-fondo-dragon-azul: #ffffff
--color-fondo-reyes: #ffffff
--color-texto-reyes: #2E7D32
--color-fondo-resaltado-carta-roja: #64B5F6
--color-fondo-resaltado-carta-negra: #64B5F6
--color-fondo-resaltado-dragon-rojo: #64B5F6
--color-fondo-resaltado-dragon-verde: #64B5F6
--color-fondo-resaltado-dragon-azul: #64B5F6
--color-fondo-resaltado-reyes: #64B5F6
--color-mesa-1: #E3F2FD
--color-mesa-2: #90CAF9
.tema-oscuro
@mixin tema-oscuro
--color-fondo: #151515
--color-texto: #dedede
--color-fondo-transparente: rgba(21, 21, 21, 0.85)
@ -50,22 +40,26 @@ body
--color-fondo-reyes: #2E7D32
--color-texto-reyes: #ffffff
--color-fondo-resaltado-carta-roja: #e57373
--color-fondo-resaltado-carta-negra: #757575
--color-fondo-resaltado-dragon-rojo: #e57373
--color-fondo-resaltado-dragon-verde: #66BB6A
--color-fondo-resaltado-dragon-azul: #29B6F6
--color-fondo-resaltado-reyes: #66BB6A
--color-mesa-1: #004D40
--color-mesa-2: #003027
// Claro
.tema-claro
@include tema-claro
.tema-oscuro
@include tema-oscuro
.tema-automatico
@include tema-claro
@media (prefers-color-scheme: dark)
.tema-automatico
--color-fondo: #151515
--color-texto: #dedede
--color-fondo-transparente: rgba(21, 21, 21, 0.85)
--color-borde: #c1c1c1
--color-texto-carta-roja: #dedede
--color-fondo-carta-roja: #b71c1c
--color-fondo-dragon-rojo: #b71c1c
--color-fondo-dragon-verde: #2E7D32
--color-fondo-dragon-azul: #1565C0
--color-fondo-reyes: #2E7D32
--color-texto-reyes: #ffffff
--color-mesa-1: #004D40
--color-mesa-2: #003027
@include tema-oscuro

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -179,13 +179,8 @@ export default defineComponent({
.cont-carta
margin-left: 1px
.c-carta-resaltada
transform: translateY(calc(var(--phx) * -1))
filter: saturate(1.75) !important
opacity: 1 !important
.c-carta
opacity: 0.85
position: relative
font:
size: calc(var(--phx) * 4 * var(--escala))
@ -218,7 +213,7 @@ export default defineComponent({
top: -95%
width: 100%
height: 100%
background-image: linear-gradient(135deg, rgba(210, 210, 210, 0.0) 0%, rgba(210, 210, 210, 0.0) 45%, rgba(210, 210, 210, 0.3) 55%, rgba(210, 210, 210, 0.9) 63%, rgba(210, 210, 210, 0.3) 67%, rgba(210, 210, 210, 0.0) 75%, rgba(210, 210, 210, 0.0) 100%)
background-image: linear-gradient(135deg, rgba(169, 169, 169, 0.0) 0%, rgba(169, 169, 169, 0.0) 45%, rgba(169, 169, 169, 0.3) 55%, rgba(169, 169, 169, 0.9) 63%, rgba(169, 169, 169, 0.3) 67%, rgba(169, 169, 169, 0.0) 75%, rgba(169, 169, 169, 0.0) 100%)
transition: transform 1000ms
animation-duration: 4s
animation-name: brillocarta
@ -274,26 +269,47 @@ export default defineComponent({
background-color: var(--color-fondo)
color: var(--color-texto)
.carta-cNegro.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-negra) !important
.carta-cRojo
background-color: var(--color-fondo-carta-roja)
color: var(--color-texto-carta-roja)
.carta-cRojo.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-roja) !important
.carta-cReyes
background-color: var(--color-fondo-reyes)
color: var(--color-texto-reyes)
.carta-cReyes.c-carta-resaltada
background-color: var(--color-fondo-resaltado-reyes) !important
.carta-dNegro
background-color: var(--color-fondo)
.carta-dNegro.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-negra) !important
.carta-dRojo
background-color: var(--color-fondo-dragon-rojo)
.carta-dRojo.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-rojo) !important
.carta-dVerde
background-color: var(--color-fondo-dragon-verde)
.carta-dVerde.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-verde) !important
.carta-dAzul
background-color: var(--color-fondo-dragon-azul)
.carta-dAzul.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-azul) !important
.carta-
opacity: 0

View File

@ -1,5 +1,5 @@
import { computed } from "vue";
import { RiMaJonState } from "@/store";
import type { RiMaJonState } from "../store/index";
import { Store } from "vuex";
export const getEsOscuro = (store: Store<RiMaJonState>) => {

View File

@ -1,6 +1,7 @@
import { Store } from "vuex";
import { RiMaJonState } from "@/store";
import { computed, ComputedRef } from "vue";
import type { RiMaJonState } from "../store";
import { computed} from "vue";
import type { ComputedRef } from "vue";
export const getClaseDora = (valor: ComputedRef<number>, store: Store<RiMaJonState>) => computed<string>(() => {
const [dora1] = store.state.dora;

View File

@ -1,11 +1,12 @@
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import "./styles/global.sass";
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import "./assets/global.sass"
// @ts-ignore
createApp(App)
.use(store)
.use(router)
.mount('#app');
const app = createApp(App)
app.use(router)
app.use(store)
app.mount('#app')

View File

@ -1,9 +1,11 @@
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import { createRouter, createWebHistory } from 'vue-router'
import Inicio from "../views/Inicio/Inicio.vue";
import Sala from "@/views/Sala/Sala.vue";
import Juego from "@/views/Juego/Juego.vue";
import Sala from "../views/Sala/Sala.vue";
import Juego from "../views/Juego/Juego.vue";
const routes: Array<RouteRecordRaw> = [
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'Home',
@ -19,59 +21,56 @@ const routes: Array<RouteRecordRaw> = [
name: "Juego",
component: Juego
},
{
path: "/ayuda/",
name: "Ayuda",
component: () => import(/* webpackChunkName: "ayuda" */ "../views/Ayuda/Ayuda.vue")
component: () => import("../views/Ayuda/Ayuda.vue")
},
{
path: "/tutorial/",
name: "Tutorial",
component: () => import(/* webpackChunkName: "tutorial" */ "../views/Tutorial/Tutorial.vue"),
component: () => import("../views/Tutorial/Tutorial.vue"),
children: [
{
path: "",
component: () => import(/* webpackChunkName: "tutorial_index" */ "../views/Tutorial/views/Index.vue")
component: () => import("../views/Tutorial/views/Index.vue")
},
{
path: "cartas/",
component: () => import(/* webpackChunkName: "tutorial_cartas" */ "../views/Tutorial/views/Cartas.vue")
component: () => import( "../views/Tutorial/views/Cartas.vue")
},
{
path: "mano/",
component: () => import(/* webpackChunkName: "tutorial_mano" */ "../views/Tutorial/views/Mano.vue")
component: () => import("../views/Tutorial/views/Mano.vue")
},
{
path: "mano/par/",
component: () => import(/* webpackChunkName: "tutorial_mano_par" */ "../views/Tutorial/views/Mano/Par.vue")
component: () => import("../views/Tutorial/views/Mano/Par.vue")
},
{
path: "mano/secuencia/",
component: () => import(/* webpackChunkName: "tutorial_mano_secuencia" */ "../views/Tutorial/views/Mano/Secuencia.vue")
component: () => import("../views/Tutorial/views/Mano/Secuencia.vue")
},
{
path: "mano/triple/",
component: () => import(/* webpackChunkName: "tutorial_mano_triple" */ "../views/Tutorial/views/Mano/Triple.vue")
component: () => import("../views/Tutorial/views/Mano/Triple.vue")
},
{
path: "mano-lista/",
component: () => import(/* webpackChunkName: "tutorial_flujo-juego" */ "../views/Tutorial/views/ManoLista.vue")
component: () => import( "../views/Tutorial/views/ManoLista.vue")
},
{
path: "bonus/",
component: () => import(/* webpackChunkName: "tutorial_bonus" */ "../views/Tutorial/views/Bonus.vue")
component: () => import("../views/Tutorial/views/Bonus.vue")
},
{
path: "puntaje/",
component: () => import(/* webpackChunkName: "tutorial_puntaje" */ "../views/Tutorial/views/Puntaje.vue")
component: () => import("../views/Tutorial/views/Puntaje.vue")
}
]
}
];
]
})
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
});
export default router;
export default router

5
src/shims-vue.d.ts vendored
View File

@ -1,5 +0,0 @@
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>
export default component
}

View File

@ -1,5 +1,5 @@
<template lang="pug">
div
div(:style="'--phx: ' + phx + '; --escala: ' + escala + ';'")
h1 Sobre el juego
p Ri Ma Jon es un juego inspirado en Mahjong, pero ejecutado con cartas.
@ -20,9 +20,9 @@ div
div.yaku
h4
i.ph-lock-bold.img-lock(title="Solo en mano cerrada")
| Mano completamente cerrada
p Ganar en tu turno con una mano cerrada
grupo-cartas(:cartas="[2, 4, 5, 7, 8, 42, 44, 46, 47, 48, 50]")
| Mano cerrada
p Ganar sin robar ninguna carta
grupo-cartas(:cartas="[2, 4, 4, 5, 6, 42, 44, 46, 47, 48, 50]")
div.yaku
h4
@ -31,11 +31,6 @@ div
p 2 secuencias iguales del mismo color en mano cerrada.
grupo-cartas(:cartas="[2, 2, 4, 5, 6, 7, 44, 45, 44, 128, 128]")
div.yaku
h4 Variedad
p Al menos una carta de cada tipo
grupo-cartas(:cartas="[10, 11, 35, 36, 39, 160, 160, 160, 192, 192, 192]")
div.yaku
h4 Realeza
p 1 triple de J, K o Q. Acumulable.
@ -103,6 +98,7 @@ div
| Triple triples cerrados
p 3 triples en mano cerrada
grupo-cartas(:cartas="[6, 6, 7, 48, 49, 49, 160, 160, 160, 192, 192]")
p No se acumula con "Triple triples".
h3 5 puntos
@ -113,7 +109,7 @@ div
grupo-cartas(:cartas="[35, 37, 38, 40, 42, 45, 47, 48, 51, 52, 52]")
p No se acumula con "escalera", "negro" o "rojo".
h3 7 puntos
h3 8 puntos
div.pad
@ -249,13 +245,14 @@ export default defineComponent({
</script>
<style lang="sass" vars="{phx, escala}">
<style lang="sass">
.pad
padding-left: 2rem
.tabla-puntos
padding-left: 2rem
h3
text-decoration: underline
font-size: 1.45rem

View File

@ -35,7 +35,7 @@ import {useStore} from "vuex";
import crearUsuario from "./components/crear-usuario.vue";
import crearSala from "./components/crear-sala.vue";
import entrarSala from "./components/entrar-sala.vue";
import { servidorF } from "@/variables";
import {servidorF} from "../../variables"
export default defineComponent({
name: "Inicio",

View File

@ -1,6 +1,9 @@
<template lang="pug">
div
div(
:style="'--escala: ' + escala + '; --pH: ' + pH + '; --phx: ' + phx + '; --pW: ' + pW + '; --pwx:' + pwx + ';'"
)
pantalla-ganador(:datos="datosJuego")
pantalla-empate(v-if="esEmpate")
contenedor-dora(:turnosRestantes="turnosDora")
div.con-int-juego
div.cont-2-juego
@ -21,15 +24,16 @@ div
</template>
<script lang="ts">
import {defineComponent, ref, onMounted, onUnmounted} from "vue";
import { defineComponent, ref, computed, onMounted, onUnmounted } from "vue";
import { useRoute } from "vue-router";
import { useDimensions } from "@/components/useDimensions";
import { useStore } from "vuex";
import { wsServidor } from "@/variables";
import contenedorDora from "./components/contenedor-dora.vue"
import contenedorDora from "./components/contenedor-dora.vue";
import mano from "@/views/Juego/components/mano.vue";
import contenedorCartas from "./components/contenedor-cartas.vue"
import pantallaGanador from "./components/pantalla-ganador.vue"
import contenedorCartas from "./components/contenedor-cartas.vue";
import pantallaGanador from "./components/pantalla-ganador.vue";
import pantallaEmpate from "./components/pantalla-empate.vue";
import { EstadoJuego } from "@/views/Juego/types/EstadoJuego";
import { DatosJuego } from "@/views/Juego/types/DatosJuego";
import { Dragon, Mano } from "@/views/Juego/types/Mano";
@ -52,7 +56,7 @@ const obtClave = (obj: any, valor: string): string | undefined => {
export default defineComponent({
name: "Juego",
components: {contenedorDora, mano, contenedorCartas, pantallaGanador},
components: {contenedorDora, mano, contenedorCartas, pantallaGanador, pantallaEmpate},
setup() {
const route = useRoute();
const store = useStore();
@ -200,6 +204,21 @@ export default defineComponent({
}
};
const esEmpate = computed(() => {
const juegoTerminado = datosJuego.value?.estadoJuego === "Terminado"
const manos = datosJuego.value?.manos
if (juegoTerminado && manos) {
for (const k in manos) {
const m = manos[k];
if (m.esGanador) return false;
}
return true;
} else {
return false;
}
});
const obtClaveMap = (s: string) => obtClave(map, s);
return {
dora,
@ -215,6 +234,7 @@ export default defineComponent({
turnoActual,
estadoJuego,
datosJuego,
esEmpate,
obtClaveMap,
descartarCarta,
pH,
@ -228,7 +248,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{pH, phx, pW, pwx, escala}">
<style lang="sass">
.con-int-juego
position: absolute
@ -242,7 +262,8 @@ export default defineComponent({
.cont-2-juego
position: absolute
border: solid 3px #795548
border: solid 5px #795548
border-radius: 5px
background: radial-gradient(var(--color-mesa-1), var(--color-mesa-2))
transform: rotateX(2deg)
width: 100%

View File

@ -1,5 +1,5 @@
<template lang="pug">
div.cont-cuadrante-descarte(:class="claseTurnoActual")
div.cont-cuadrante-descarte(:class="claseTurnoActual" :style="'--escala: ' + escala + ';'")
div(v-for="cartas in grupoCartas")
carta(v-for="(c, i) in cartas" :valor="c" :key="i")
@ -36,7 +36,7 @@ export default defineComponent({
},
escala: {
type: Number,
default: 0.75
default: 0.7
},
esTurnoActual: {
type: Boolean,
@ -56,18 +56,19 @@ export default defineComponent({
</script>
<style lang="sass" vars="{escala}">
<style lang="sass">
.cont-cuadrante-descarte
position: absolute
width: 26%
width: 23%
height: 20%
bottom: 17%
right: 37%
right: 38.5%
text-align: left
border-top-style: solid
border-top-width: calc(var(--phx) * 0.75 * var(--escala))
border-top-width: calc(var(--phx) / 2)
border-top-color: transparent
transition: border-top-color 250ms
.cont-cuadrante-descarte-turno-actual

View File

@ -1,5 +1,5 @@
<template lang="pug">
div.contenedor-dora
div.contenedor-dora(:style="'--escala: ' + escala + ';'")
carta(v-for="(c, i) in doraCerrado" :valor="c" :key="i")
br
carta(v-for="(c, i) in doraAbierto" :valor="c" :key="i")
@ -47,7 +47,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{escala}">
<style lang="sass">
.contenedor-dora
position: fixed

View File

@ -29,7 +29,7 @@ div.cont-cuadrante-2-mano(:style="'transform: rotate(' + posicionW + ')'")
carta(:valor="-1")
carta(:valor="mano.sigCarta" :fnDescartar="descartarCarta")
carta(:valor="-1")
div(v-for="g in mano.cartasReveladas" :style="{display: 'inline-block'}")
div(v-for="g in mano.cartasReveladas" :style="{display: 'inline-block', marginLeft: '5px'}")
carta(v-for="(c, i) in g" :valor="c" :key="i")
//

View File

@ -1,5 +1,5 @@
<template lang="pug">
div.opcion-mano(@click="enviarSolicitudIgnorarOportunidad" :style="{backgroundColor: '#9E9E9E'}")
div.opcion-mano(@click="enviarSolicitudIgnorarOportunidad" :style="'background-color: #9E9E9E; --tamano: ' + tamano + ';'")
| Ignorar
//
@ -51,7 +51,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{tamano}">
<style lang="sass">
.opcion-mano
display: inline-block

View File

@ -1,5 +1,7 @@
<template lang="pug">
div.opcion-mano(v-for="opcion in opciones" @click="enviarSolicitudSeq(opcion)" :style="{backgroundColor: '#009688'}")
div.opcion-mano(v-for="opcion in opciones" @click="enviarSolicitudSeq(opcion)"
:style="'background-color: #009688; --tamano: ' + tamano + '; --escala: ' + escala + ';'"
)
div.contenedor-cartas-opcion-mano
carta(v-for="(c, i) in obtCartasOrdenadas(opcion)"
:valor="c"
@ -76,7 +78,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{tamano, escala}">
<style lang="sass">
.contenedor-cartas-opcion-mano
position: absolute

View File

@ -1,5 +1,7 @@
<template lang="pug">
div.opcion-mano(@click="enviarSolicitudSeq()" :style="{backgroundColor: '#3F51B5'}")
div.opcion-mano(@click="enviarSolicitudSeq()"
:style="'background-color: #3F51B5; --tamano: ' + tamano + '; --escala: ' + escala + ';'"
)
div.contenedor-cartas-opcion-mano
carta(v-for="(c, i) in obtCartas()"
:valor="c"
@ -81,7 +83,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{tamano, escala}">
<style lang="sass">
.contenedor-cartas-opcion-mano
position: absolute

View File

@ -1,5 +1,7 @@
<template lang="pug">
div.opcion-mano(@click="enviarSolicitudWin()" :style="{backgroundColor: '#f44336'}")
div.opcion-mano(@click="enviarSolicitudWin()"
:style="'background-color: #f44336; --tamano: ' + tamano + ';'"
)
span Win
//
@ -54,7 +56,7 @@ export default defineComponent({
</script>
<style lang="sass" vars="{tamano}">
<style lang="sass">
.opcion-mano
position: relative

View File

@ -0,0 +1,35 @@
<template lang="pug">
div.contenedor-pantalla-empate
h1 Empate
hr
router-link(to="/") Ir al inicio
//
</template>
<script lang="ts">
export default {
name: "pantalla-empate"
}
</script>
<style lang="sass" scoped>
.contenedor-pantalla-empate
position: fixed
top: 10%
left: 10%
width: 80%
height: 80%
z-index: 100
background-color: var(--color-fondo-transparente)
padding: 1rem
h1, h2, h3, h4, h5
margin: 0
padding: 1rem 0
</style>

View File

@ -33,6 +33,10 @@ const aumentarValorA = (ref: Ref<number>, valorDestino: number) => {
};
const formulaPuntos = (x: number) => 1000 * Math.floor(
3 * x + (x ** 3 * 125) / 1000
);
export default defineComponent({
name: "pantalla-ganador",
components: {grupoCartas},
@ -92,11 +96,7 @@ export default defineComponent({
for (const y of yaku.value) {
n += obtValorYaku(y)
}
if (n === 0) return 100;
const preValor = 1000 + (270 * n ** 2) - (18 * n ** 3);
// Eliminar los 2 ultimos números.
return Math.floor(preValor / 100) * 100;
return formulaPuntos(n);
});
const obtTextoYaku = (y: Yaku) => {

View File

@ -1,50 +1,74 @@
export type Yaku =
// 10
| "DragonesFull"
| "Verde"
// 8
| "RealezaDragones"
| "RealezaFull"
| "TripleTriplesCerrados"
| "EscaleraPerfecta"
| "A10"
// 5
| "EscaleraFull"
// 3
| "TripleTriplesCerrados"
| "Exterior"
// 2
| "Escalera"
| "TripleCuadruples"
| "Negro"
| "Rojo"
| "SemiExterior"
| "ParUnico"
| "DragonJugador"
| "DragonPartida"
| "DobleSecuenciaPura"
// 1
| "Dragones"
| "Interior"
| "TripleTriples"
| "TripleSecuenciaCerrada"
| "Realeza"
| "DobleSecuenciaPura"
| "Cerrado"
| "DobleSecuencia"
| "ManoCerrada"
export const obtValorYaku = (y: Yaku): number => {
switch (y) {
case "DragonesFull": return 10
case "Verde": return 10
case "RealezaDragones": return 7
case "RealezaFull": return 7
case "TripleTriplesCerrados": return 3
case "EscaleraFull": return 3
case "Exterior": return 3
case "Escalera": return 2
case "TripleCuadruples": return 2
case "Negro": return 2
case "Rojo": return 2
case "SemiExterior": return 2
case "ParUnico": return 1
case "DragonJugador": return 1
case "DragonPartida": return 1
case "Interior": return 1
case "TripleTriples": return 1
case "TripleSecuenciaCerrada": return 1
case "Realeza": return 1
case "DobleSecuenciaPura": return 1
case "Cerrado": return 0
case "DragonesFull":
return 10;
case "Verde":
return 10;
case "RealezaDragones":
return 8;
case "RealezaFull":
return 8;
case "EscaleraPerfecta":
return 8;
case "A10":
return 8;
case "EscaleraFull":
return 5;
case "TripleTriplesCerrados":
return 3;
case "Exterior":
return 3;
case "Escalera":
return 2;
case "Negro":
return 2;
case "Rojo":
return 2;
case "SemiExterior":
return 2;
case "DobleSecuenciaPura":
return 2;
case "Dragones":
return 1;
case "Interior":
return 1;
case "TripleTriples":
return 1;
case "Realeza":
return 1;
case "DobleSecuencia":
return 1;
case "ManoCerrada":
return 1;
}
}

View File

@ -50,12 +50,12 @@ div
td= (valorBonus * 3) / 10 + ' puntos'
tr
td 2 indicadores
td= (valorBonus * 3) / 10 + ' puntos'
td= (valorBonus * 6) / 10 + ' puntos'
td= (valorBonus * 2) / 10 + ' puntos'
td= (valorBonus * 4) / 10 + ' puntos'
td -
tr
td 3 indicadores
td= (valorBonus * 9) / 10 + ' puntos'
td= (valorBonus * 4) / 10 + ' puntos'
td -
td -
tr

View File

@ -4,7 +4,11 @@ div
p Primero se obtienen los puntos otorgados por los yaku.
p Luego se obtienen los puntos otorgados por los bonus.
p La suma de estos dos es la cantidad de puntos total. Luego se busca esa cantidad en la tabla:
p La suma de estos dos es la cantidad de puntos total. Para obtener las monedas se usa la formula:
img(:src="'/img/formula-puntaje.png'" style="height: 100px; width: auto;")
p En la siguiente tabla se muestran los valores comunes:
table.tabla-puntaje
thead
@ -12,9 +16,12 @@ div
td Puntos
td Monedas
tbody
tr(v-for="(p, i) in puntos")
td {{ i * 0.5 }}
td {{ p }}
tr(v-for="i in puntos")
td {{ i }}
td {{ formulaPuntos(i) }}
p La cantidad maxima de puntos es 10
p Cada jugador inicia con 100,000 monedas
//
</template>
@ -22,35 +29,38 @@ div
<script lang="ts">
import { defineComponent } from "vue";
const formulaPuntos = (x: number) => 1000 * Math.floor(
3 * x + (x ** 3 * 125) / 1000
);
const puntos = [
0,
0,
1000,
2000,
3000,
4000,
6000,
8000,
10000,
13000,
17000,
21000,
25000,
30000,
35000,
37000,
39000,
41000,
43000,
45000,
50000
1,
1.5,
2,
2.5,
3,
3.5,
4,
4.5,
5,
5.5,
6,
6.5,
7,
7.5,
8,
8.5,
9,
9.5,
10
];
export default defineComponent({
name: "Puntaje",
setup() {
return {
puntos
puntos,
formulaPuntos
}
}
});

12
tsconfig.app.json Normal file
View File

@ -0,0 +1,12 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}

View File

@ -1,39 +1,11 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
{
"path": "./tsconfig.app.json"
}
]
}

16
tsconfig.node.json Normal file
View File

@ -0,0 +1,16 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"nightwatch.conf.*",
"playwright.config.*"
],
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"types": ["node"]
}
}

16
vite.config.ts Normal file
View File

@ -0,0 +1,16 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})