Compare commits

..

No commits in common. "339d6876f36ba7f9c2b360b97d4b6fa55df73c7e" and "ee70ef1090be5a49a42a8f450e0b1a6df031d704" have entirely different histories.

42 changed files with 9475 additions and 1620 deletions

12
.editorconfig Normal file
View File

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

27
.gitignore vendored
View File

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

1
.npmrc Normal file
View File

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

View File

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

24
Jenkinsfile vendored
View File

@ -1,24 +0,0 @@
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,40 +1,19 @@
# rimajon-vue # rimajon
This template should help get you started developing with Vue 3 in Vite. ## Project setup
```
## 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 pnpm install
``` ```
### Compile and Hot-Reload for Development ### Compiles and hot-reloads for development
```
```sh pnpm run serve
pnpm dev
``` ```
### Type-Check, Compile and Minify for Production ### Compiles and minifies for production
```sh
pnpm build
``` ```
pnpm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
babel.config.js Normal file
View File

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

1
env.d.ts vendored
View File

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

View File

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

File diff suppressed because it is too large Load Diff

1
public/_redirects Normal file
View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

20
public/index.html Normal file
View File

@ -0,0 +1,20 @@
<!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,23 +1,28 @@
<script setup lang="ts"> <template>
import { RouterView } from 'vue-router' <router-view/>
import { useStore } from 'vuex'; <div style="display: none;">{{ modoColor }}</div>
import { computed, onMounted, watch } from 'vue'; </template>
<script lang="ts">
import { defineComponent, computed, watch } from "vue";
import { useStore } from "vuex";
const store = useStore(); export default defineComponent({
const modoColorUsuario = computed<string>(() => store.state.modoColorUsuario); setup() {
const store = useStore();
const modoColorUsuario = computed<string>(() => store.state.modoColorUsuario);
const query = window.matchMedia("(prefers-color-scheme: dark)"); const query = window.matchMedia("(prefers-color-scheme: dark)");
const funActualizarMediaQuery = (ev: MediaQueryListEvent | MediaQueryList) => { const funActualizarMediaQuery = (ev: MediaQueryListEvent | MediaQueryList) => {
store.commit( store.commit(
"setModoColorUsuario", "setModoColorUsuario",
ev.matches ? "oscuro" : "claro" ev.matches ? "oscuro" : "claro"
); );
}; };
query.addEventListener("change", funActualizarMediaQuery); query.addEventListener("change", funActualizarMediaQuery);
funActualizarMediaQuery(query); funActualizarMediaQuery(query);
watch(modoColorUsuario, (v) => { watch(modoColorUsuario, (v) => {
console.log("Modo actualizado"); console.log("Modo actualizado");
if (v === "oscuro") { if (v === "oscuro") {
document.body.className = "tema-oscuro"; document.body.className = "tema-oscuro";
@ -26,21 +31,21 @@ watch(modoColorUsuario, (v) => {
} else { } else {
document.body.className = "tema-automatico"; document.body.className = "tema-automatico";
} }
}); });
(() => { (() => {
const modo = localStorage.getItem("modoColorUsuario"); const modo = localStorage.getItem("modoColorUsuario");
if (modo === "claro" || modo === "oscuro") { if (modo === "claro" || modo === "oscuro") {
store.commit("setModoColorUsuario", modo); store.commit("setModoColorUsuario", modo);
} else { } else {
store.commit("setModoColorUsuario", ""); store.commit("setModoColorUsuario", "");
} }
})(); })();
return {
modoColor: modoColorUsuario
}
}
});
</script> </script>
<template>
<RouterView />
<div style="display: none;">{{ modoColor }}</div>
</template>

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -179,8 +179,13 @@ export default defineComponent({
.cont-carta .cont-carta
margin-left: 1px margin-left: 1px
.c-carta-resaltada
transform: translateY(calc(var(--phx) * -1))
filter: saturate(1.75) !important
opacity: 1 !important
.c-carta .c-carta
opacity: 0.85
position: relative position: relative
font: font:
size: calc(var(--phx) * 4 * var(--escala)) size: calc(var(--phx) * 4 * var(--escala))
@ -213,7 +218,7 @@ export default defineComponent({
top: -95% top: -95%
width: 100% width: 100%
height: 100% height: 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%) 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%)
transition: transform 1000ms transition: transform 1000ms
animation-duration: 4s animation-duration: 4s
animation-name: brillocarta animation-name: brillocarta
@ -269,47 +274,26 @@ export default defineComponent({
background-color: var(--color-fondo) background-color: var(--color-fondo)
color: var(--color-texto) color: var(--color-texto)
.carta-cNegro.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-negra) !important
.carta-cRojo .carta-cRojo
background-color: var(--color-fondo-carta-roja) background-color: var(--color-fondo-carta-roja)
color: var(--color-texto-carta-roja) color: var(--color-texto-carta-roja)
.carta-cRojo.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-roja) !important
.carta-cReyes .carta-cReyes
background-color: var(--color-fondo-reyes) background-color: var(--color-fondo-reyes)
color: var(--color-texto-reyes) color: var(--color-texto-reyes)
.carta-cReyes.c-carta-resaltada
background-color: var(--color-fondo-resaltado-reyes) !important
.carta-dNegro .carta-dNegro
background-color: var(--color-fondo) background-color: var(--color-fondo)
.carta-dNegro.c-carta-resaltada
background-color: var(--color-fondo-resaltado-carta-negra) !important
.carta-dRojo .carta-dRojo
background-color: var(--color-fondo-dragon-rojo) background-color: var(--color-fondo-dragon-rojo)
.carta-dRojo.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-rojo) !important
.carta-dVerde .carta-dVerde
background-color: var(--color-fondo-dragon-verde) background-color: var(--color-fondo-dragon-verde)
.carta-dVerde.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-verde) !important
.carta-dAzul .carta-dAzul
background-color: var(--color-fondo-dragon-azul) background-color: var(--color-fondo-dragon-azul)
.carta-dAzul.c-carta-resaltada
background-color: var(--color-fondo-resaltado-dragon-azul) !important
.carta- .carta-
opacity: 0 opacity: 0

View File

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

View File

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

View File

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

View File

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

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

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

View File

@ -4,7 +4,8 @@ body
color: var(--color-texto) color: var(--color-texto)
margin: 0 margin: 0
@mixin tema-claro // Claro
.tema-automatico
--color-fondo: #ffffff --color-fondo: #ffffff
--color-texto: #151515 --color-texto: #151515
--color-fondo-transparente: rgba(255, 255, 255, 0.8) --color-fondo-transparente: rgba(255, 255, 255, 0.8)
@ -17,17 +18,26 @@ body
--color-fondo-reyes: #ffffff --color-fondo-reyes: #ffffff
--color-texto-reyes: #2E7D32 --color-texto-reyes: #2E7D32
--color-fondo-resaltado-carta-roja: #64B5F6 --color-mesa-1: #E3F2FD
--color-fondo-resaltado-carta-negra: #64B5F6 --color-mesa-2: #90CAF9
--color-fondo-resaltado-dragon-rojo: #64B5F6
--color-fondo-resaltado-dragon-verde: #64B5F6 .tema-claro
--color-fondo-resaltado-dragon-azul: #64B5F6 --color-fondo: #ffffff
--color-fondo-resaltado-reyes: #64B5F6 --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-mesa-1: #E3F2FD --color-mesa-1: #E3F2FD
--color-mesa-2: #90CAF9 --color-mesa-2: #90CAF9
@mixin tema-oscuro .tema-oscuro
--color-fondo: #151515 --color-fondo: #151515
--color-texto: #dedede --color-texto: #dedede
--color-fondo-transparente: rgba(21, 21, 21, 0.85) --color-fondo-transparente: rgba(21, 21, 21, 0.85)
@ -40,26 +50,22 @@ body
--color-fondo-reyes: #2E7D32 --color-fondo-reyes: #2E7D32
--color-texto-reyes: #ffffff --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-1: #004D40
--color-mesa-2: #003027 --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) @media (prefers-color-scheme: dark)
.tema-automatico .tema-automatico
@include tema-oscuro --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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,35 +0,0 @@
<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,10 +33,6 @@ const aumentarValorA = (ref: Ref<number>, valorDestino: number) => {
}; };
const formulaPuntos = (x: number) => 1000 * Math.floor(
3 * x + (x ** 3 * 125) / 1000
);
export default defineComponent({ export default defineComponent({
name: "pantalla-ganador", name: "pantalla-ganador",
components: {grupoCartas}, components: {grupoCartas},
@ -96,7 +92,11 @@ export default defineComponent({
for (const y of yaku.value) { for (const y of yaku.value) {
n += obtValorYaku(y) n += obtValorYaku(y)
} }
return formulaPuntos(n); 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;
}); });
const obtTextoYaku = (y: Yaku) => { const obtTextoYaku = (y: Yaku) => {

View File

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

View File

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

View File

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

View File

@ -1,16 +0,0 @@
{
"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"]
}
}

View File

@ -1,16 +0,0 @@
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))
}
}
})