Issue: embedded rules language not updated when language is set (in Analyse, Game and Problems)
Also: if new live game starts in background, "new game" notify OK but not first move (not too serious however)
+On smartphone for Teleport, Chakart, Weiqi and some others: wait re-click to confirm "touch" move (in Board.vue)
https://www.chessvariants.com/crossover.dir/koopachess.html
--> Can a stunned piece capture? Maybe not. ...recover? After 5 moves? Never?
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
footer
router-link.menuitem(to="/about") {{ st.tr["About"] }}
- router-link.menuitem#newsMenu(to="/news") {{ st.tr["News"] }}
+ router-link.menuitem(to="/faq") F.A.Q.
a.menuitem(href="https://discord.gg/a9ZFKBe")
span Discord
img(src="/images/icons/discord.svg")
data: function() {
return { st: store.state };
},
- mounted: function() {
- ajax(
- "/newsts",
- "GET",
- {
- success: (res) => {
- if (this.st.user.newsRead < res.timestamp)
- document.getElementById("newsMenu").classList.add("somenews");
- }
- }
- );
- },
computed: {
userName: function() {
return (
height: 55px
display: block
padding: 5px 0
-
-.menuitem.somenews
- color: red
- &:link, &:visited, &:hover
- color: red
</style>
component: loadView("About")
},
{
- path: "/news",
- name: "news",
- component: loadView("News")
+ path: "/faq",
+ name: "faq",
+ component: loadView("Faq")
}
]
});
"New correspondance game:": "New correspondance game:",
"New game": "New game",
"New problem": "New problem",
- News: "News",
"No challenges found :( Click on 'New game'!": "No challenges found :( Click on 'New game'!",
"No games found :( Send a challenge!": "No games found :( Send a challenge!",
"No more problems": "No more problems",
--- /dev/null
+.question.
+ Where should I start?
+.answer.
+ The "Variants" menu on top contains the list of all playable games.
+ If you know what you want, the "prefix" filter might be useful.
+ Then, read the rules, and optionally watch an example game or play a game
+ against the computer. Keep in mind that the "engine" is generally quite weak.
+ It's here for illustration and learning purpose only.
+
+.question.
+ The bot is too weak! Where should I continue?
+.answer
+ | I'm glad you ask. Since I believe that a place is more fun with nice people
+ | around, the next step is to play against humans.
+ | Go to main "Hall" (upper left menu), and first look if a live or
+ | correspondance challenge interests you. If yes just click on it. Challenges
+ | highlighted in orange are targeted: someone wants to play against you,
+ | specifically, optionally from a custom starting position.
+ | If there aren't any interesting challenge, then click on "New game" in the
+ | upper right corner. Select a variant, and
+ ul
+ li.
+ Adjust the cadence: format is
+ 'main time + increment' with default units minutes and seconds.
+ If the main time is given in days then the game is considered by
+ correspondance.
+ li.
+ Select the randomness level: 'deterministic' always show the same setup,
+ the one you are generally used to.
+ | You can also click on "Who's there" and select a player to
+ | challenge. The "memorize" checkbox allows to store the challenge settings
+ | to re-issue it in one click later.
+
+.question.
+ I'm bored of being anonymous, I want a name!
+.answer.
+ Very good idea: click on "Login" in the upper right corner, and then switch
+ to the registration view (using the link appearing in dark red).
+ Only a username and an email are required.
+ Once signed up, you should log in within the next 24 hours or your 'account'
+ will be deleted (you can re-do this process anytime later of course).
+ This will also allow you to play correspondance games.
+ Note: the authentication is passwordless, as most websites should be.
+
+.question.
+ How can I talk to my opponent? Ask rematch?
+.answer.
+ Just click on the Chat icon on top. It turns purple when new messages arrive.
+ After the game ends, the Swords icon next to it is the rematch button:
+ it turns green when you receive a rematch offer.
+
+.question.
+ I made a bad move, I want to take it back!
+.answer
+ | It's not possible for now. However, there is a way to continue the game:
+ ol
+ li Click on the Analyze button, and go back just before the bad move.
+ li Copy the FEN displayed below the board (the weird long string).
+ li.
+ Go to main Hall, open "New game" window, select your opponent,
+ and then paste the FEN in the appropriate field.
+
+.question.
+ I'm streaming a game, and would like to use arrows and circles.
+.answer.
+ A right click on a square draws a purple circle inside, and a second right
+ click erases it.
+ 'Drag and drop' with the right mouse button from a square to another to draw
+ a purple arrow. Click anywhere with the left mouse button to erase all
+ drawings.
+
+.question.
+ I want to start from a custom position!
+.answer.
+ If the desired position is on a board on the website, just click on the
+ Analyze button (microscope icon), and then copy the string appearing
+ below the board. If the position is in your mind or on a physical board,
+ then you can either try to understand the FEN format by trials and errors
+ from the Analysis mode, or ask me - using the Contact form or on Discord.
+ By the way, FEN are required to post in the "Problems" menu as well.
+
+.question.
+ I want a rating! I want tournaments! I want a new poney!
+.answer.
+ In my experience, caring about a rating only complicate your life,
+ so there won't be any around here. There probably won't be any tournaments
+ support on the website, but some may be organized anyway. Do the pairings
+ somewhere else and ask people to challenge each other.
+
+.question.
+ You said "Problems" menu? What's that?
+.answer.
+ An area where you can upload interesting positions, which could be studies,
+ (self-)mate in 3 and so on. For the moment there is no support for proof
+ games, but you could still provide the final diagram to let people search.
+ Start by looking at the existing problems, and try to solve them :-)
+
+.question.
+ I'm in Hall but cannot see my games!
+.answer.
+ Your games are gathered in "My games" menu on top.
+ If a game is highlighted in orange, then it's your turn: click on it and
+ play! You can have as many running games as you like in either live or
+ correspondance.
+
+.question.
+ Clocks in live games sometimes freeze.
+.answer
+ | The clocks in live games follow a non-standard logic - but sounded, I
+ | believe :-)
+ ul
+ li.
+ If you play a move and then quit the game, your clock will be
+ frozen at its current state until you come back in the game. After his move
+ your opponent will see your clock stopped; he could decide to abort or
+ resign, or
+ li.
+ If your opponent also quits the game after playing, then the time is
+ just frozen - and you can decide to continue it later.
+ | The rational behind this is that you don't know what the opponent played,
+ | so your clock shouldn't be running. Ans it also allows to take a break in
+ | long live games, like maybe 1h30 + 30s.
+
+.question.
+ I bookmarked a fascinating observed game, but the URL no longer works.
+.answer
+ | Live games are stored locally, on browsers only.
+ | If you are only an observer, your browser doesn't even store it, so later
+ | the game won't be reachable if the players and all observers leave the game.
+ | Consequently, the right way to go is
+ ol
+ li Download the game (see the icon on the right),
+ li Import it using the button in "Imported games" tab in "My Games" menu.
+
+.question.
+ I cleaned the website data, and all my live games are gone!
+.answer.
+ They are stored in your browser's database.
+ You just erased it, so the games are gone :-)
+ More flexible cleaning can be achieved: removing cookies is harmless (you'll
+ just need to re-login), as well as removing local storage data (your
+ preferences about board color and sounds will be reset). But touching
+ 'IndexedDB' will remove all local games.
+
+.question.
+ But I would like to remove this specific game, and this one too!
+.answer.
+ Click on the game result area from "My Games" listings, and confirm deletion.
+ If the game is running this will abort it first.
+ Note that correspondance games deleted by only one player are still
+ reachable: they are just hidden for you.
+
+.question.
+ I've a question not answered here!
+.answer.
+ If the answer isn't 42 (are you really sure?), then use the contact form,
+ or ask on Discord :-)
+ See the links in the website footer.
--- /dev/null
+.question.
+ ¿Por donde empiezo?
+.answer.
+ El menú "Variantes" en la parte superior contiene la lista de todos los
+ juegos disponibles.
+ Si sabe cuál quiere, el filtro "prefijo" puede ser útil.
+ Luego lea las reglas y posiblemente vea una partida de ejemplo o
+ juega uno contra la computadora. Tenga en cuenta que este oponente es
+ en general bastante débil.
+ Se utiliza solo para ilustrar y aprender las reglas.
+
+.question.
+ ¡La computadora está jugando demasiado mal! ¿Dónde debo continuar?
+.answer
+ | Me gusta esta pregunta. Para mí un lugar es más agradable con
+ | gente comprensivo, así que el siguiente paso es jugar contra
+ | humanos. Vaya al "Salón" principal (menú superior izquierda) y
+ | primero averigua si estás interesado en un desafío en vivo o por
+ | correspondencia. En caso afirmativo, simplemente haga clic en él.
+ | Los desafíos resaltados en naranja son apuntado: alguien quiere jugar
+ | contra ti, específicamente, tal vez desde una posición inicial particular.
+ | Si ningún desafío es interesante, haga clic en "Nueva partida" en
+ | la esquina superior derecha. Elija una variante, luego
+ ul
+ li.
+ Ajuste la cadencia: el formato es 'tiempo principal + incremento', por
+ defecto en minutos y segundos. Si el tiempo principal se da en días,
+ la parte se considera por correspondencia.
+ li.
+ Seleccione el nivel de aleatoriedad: 'determinista' para tener siempre
+ el misma configuración inicial, probablemente en la que estás
+ acostumbrado a.
+ | También puedes hacer clic en "Quién está allí" y elegir un jugador para
+ | desafiar. El cuadro "memorizar" permite almacenar los parámetros del
+ | desafío para el relanzar más tarde.
+
+.question.
+ Estoy cansado de ser anónimo, ¡quiero un nombre!
+.answer.
+ Gran idea: haga clic en "Login" en la esquina superior derecha, luego cambie
+ en la vista de registro (a través del enlace en rojo oscuro que aparece en
+ arriba). Solo se requiere su nombre de usuario y un correo electrónico.
+ Una vez registrado, debe iniciar sesión en las próximas 24 horas de lo
+ contrario su 'cuenta' se elimina (puede comenzar de nuevo en cualquier
+ momento tarde por supuesto).
+ Nota: la autenticación se realiza sin contraseña, como debería
+ sea el caso en la mayoría de los sitios.
+
+.question.
+ ¿Cómo puedo hablar con el oponente? Solicitar venganza?
+.answer.
+ Simplemente haga clic en el icono de Chat en la parte superior.
+ Se vuelve púrpura cuando llega un nuevo mensaje. Cuando la partida termina,
+ el ícono de Espadas al lado permite reiniciar un juego:
+ se vuelve verde cuando el oponente quiere repetición.
+
+.question.
+ Hice un mal movimiento, ¡quiero volver!
+.answer
+ | No es posible por el momento. Sin embargo, aquí hay una manera de
+ | continuar el juego:
+ ol
+ li.
+ Haga clic en el botón Análisis y regrese justo antes del movimiento
+ incorrecto.
+ li
+ Copie el FEN que se muestra debajo del tablero de ajedrez (la cadena
+ larga y extraña).
+ li.
+ Vaya al Salón, abra la ventana "Nueva partida", seleccione
+ su oponente y luego pegue el FEN en el campo apropiado.
+
+.question.
+ Estoy transmitiendo un juego en vivo, y me gustaría usar flechas y
+ círculos.
+.answer.
+ Haga clic derecho en un cuadro dibuja un círculo morado en el interior, y un
+ segundo clic derecho lo borra.
+ 'Arrastra y suelta' con el botón derecho de un cuadro a otro dibujo
+ una flecha morada. Haga clic izquierdo en cualquier lugar para
+ eliminar dibujos.
+
+.question.
+ ¡Quiero comenzar desde una posición específica!
+.answer.
+ Si la posición deseada es en un tablero en algún lugar del sitio,
+ simplemente haga clic en el botón Análisis (el icono del microscopio) y
+ copie el cadena que aparece debajo del tablero. Si la posición está en tu
+ cabeza o en un tablero de ajedrez físico, entonces puedes buscar entender el
+ formato FEN por prueba y error en modo Análisis, o pregúntame a través del
+ formulario de contacto o en Discord. El pasaje,
+ estas cadenas FEN también son necesarias para publicar un problema.
+
+.question.
+ ¡Quiero un ranking! ¡Quiero torneos! ¡Quiero un nuevo pony!
+.answer.
+ En mi experiencia, preocuparse por un ranking solo te hace
+ complicar la vida, por lo que no habrá ninguno en este sitio.
+ Nada esta planeado ya no se trata de torneos, pero puedes organizarlos de
+ todos modos. Haga los emparejamientos en otro lugar y pídale a la gente que
+ desafío.
+
+.question.
+ ¿Mencionaste el menú "Problemas"? Que es eso ?
+.answer.
+ Un espacio donde puedes compartir posiciones interesantes, que podrían
+ ser estudios, mat (ayudado) en 3 etc. Actualmente no hay
+ soporte para análisis retrógrado, pero aún podría enviar
+ el diagrama final para permitir que las personas busquen.
+ Comience mirando los problemas existentes e intente resolverlos.
+ :-)
+
+.question.
+ ¡Estoy en el Salón pero no veo mis partidas!
+.answer.
+ Sus partidas se agrupan en el menú "Mis partidas" en la parte superior.
+ Si un juego está resaltado en naranja, entonces es tu turno: haga clic en
+ arriba y juega! El número de partidas en progreso en vivo o por
+ correspondencia no es limitada.
+
+.question.
+ En un juego en vivo, el péndulo a veces se detiene.
+.answer
+ | Los péndulos en las partidas en vivo siguen una lógica no estándar
+ | - pero consistente, creo :-)
+ ul
+ li.
+ Si haces un movimiento y luego sales del juego, tu péndulo se congelará
+ en su estado actual hasta que vuelvas al juego.
+ Despues su movimiento, tu oponente verá tu tiempo detenido;
+ él podría decidir para detener el juego o rendirse, o
+ li.
+ Si tu oponente también abandona el juego después de su movimiento,
+ entonces el tiempo está congelado y puede decidir reanudarlo más tarde.
+ | De hecho, ya que no sabes lo que jugó el oponente, es
+ | normal para que su péndulo se detenga. También te permite tomar un
+ | descanso durante una larga partida en vivo, como 1h30 + 30s, por ejemplo.
+
+.question.
+ Anoté la dirección de una partida fascinante, pero la URL ya no funciona.
+.answer
+ | Los juegos en vivo se almacenan localmente en el navegador
+ | solamente. Si eres un simple espectador, tu navegador no registra
+ | ni siquiera el juego, por lo que será inaccesible cuando los jugadores
+ | así como todos los observadores se habrán ido.
+ | La forma correcta de hacer esto es
+ ol
+ li Descargue la partida (vea el icono a la derecha),
+ li.
+ Importarlo usando el botón en la pestaña "Partidas importadas"
+ desde el menú "Mis partidas".
+
+.question.
+ ¡Eliminé los datos del sitio y mis partidas en vivo han desaparecido!
+.answer.
+ Se almacenan en la base de datos del navegador.
+ Simplemente lo eliminó, por lo que ya no están allí :-)
+ Se requiere una limpieza más fina: eliminar las cookies es inofensivo
+ (solo tendrá que iniciar sesión de nuevo), así como la eliminación de los
+ datos local (guardando sus preferencias como el color del tablero).
+ Sin embargo, tocar la base de datos 'IndexedDB' puede eliminar partidas.
+
+.question.
+ Pero me gustaría eliminar esta parte allí, ¡y esta también!
+.answer.
+ Haz clic en el área de resultados del juego en la lista "Mis partidas",
+ y confirme la eliminación. Si el juego está en progreso, será primero
+ detuvo. Tenga en cuenta que las partidas de correspondencia borradas por
+ solo uno de los dos jugadores siempre están accesibles: simplemente están
+ ocultos para ti.
+
+.question.
+ Tengo una pregunta sin respuesta aquí!
+.answer.
+ Si la respuesta no es 42 (¿estás seguro?), usa el formulario
+ de Contacta o pregunta en Discord :-)
+ Vea los enlaces al final de la página.
--- /dev/null
+.question.
+ Par où dois-je commencer ?
+.answer.
+ Le menu "Variantes" en haut contient la liste de touts les jeux disponibles.
+ Si vous savez lequel vous voulez, le filtre "préfixe" peut être utile.
+ Ensuite, lisez les règles, et éventuellement regardez une partie exemple ou
+ jouez-en une contre l'ordinateur. Gardez à l'esprit que cet adversaire est
+ en général plutôt faible.
+ Il sert à illustrer et à apprendre les règles seulement.
+
+.question.
+ L'ordinateur joue trop mal ! Où dois-je continuer ?
+.answer
+ | Cette question me plaît. Pour moi un endroit est plus agréable avec des
+ | gens sympas autour, donc la prochaine étape est de jouer contre des
+ | humains. Allez dans le "Salon" principal (menu en haut à gauche), et
+ | regardez d'abord si un défi en direct ou par correspondance vous intéresse.
+ | Si oui cliquez simplement dessus. Les défis surlignés en orange sont
+ | ciblés : quelqu'un veut jouer contre vous, spécifiquement, peut-être
+ | depuis une position initiale particulière.
+ | Si aucun défi n'est intéressant, alors cliquez sur "Nouvelle partie" dans
+ | le coin en haut à droite. Choisissez une variante, puis
+ ul
+ li.
+ Ajustez la cadence : le format est 'temps principal + incrément', par
+ défaut en minutes et secondes. Si le temps principal est donnée en jours,
+ la partie est considérée par correspondance.
+ li.
+ Sélectionnez le niveau d'alea : 'déterministe' pour avoir toujours la
+ même configuration initiale, sans doute celle à laquelle vous êtes
+ habitués.
+ | Vous pouvez aussi cliquer sur "Qui est là" et choisir un joueur à défier.
+ | La case "mémoriser" permet de stocker les paramètres du défi pour le
+ | re-lancer plus tard.
+
+.question.
+ J'en ai marre d'être anonyme, je veux un nom !
+.answer.
+ Excellente idée : cliquez sur "Login" dans le coin haut droit, puis basculez
+ sur la vue d'enregistrement (via le lien en rouge foncé apparaissant en
+ haut). Seuls votre nom d'utilisateur ainsi qu'une adresse email sont requis.
+ Une fois inscrit, vous devez vous logger dans les prochaines 24 heures sinon
+ votre 'compte' est supprimé (vous pouvez recommencer n'importe quand plus
+ tard bien sûr).
+ Note : l'authentification s'effectue sans mot de passe, comme cela devrait
+ être le cas sur la plupart des sites.
+
+.question.
+ Comment puis-je parler à l'adversaire ? Demander une revanche ?
+.answer.
+ Cliquez simplement sur l'icône Chat en haut. Il devient violet quand un
+ nouveau message arrive. Une fois la partie terminée, l'icône Épées à côté
+ permet de relancer une partie : il devient vert lorsque l'adversaire veut
+ rejouer.
+
+.question.
+ J'ai joué un mauvais coup, je veux revenir en arrière !
+.answer
+ | Ce n'est pas possible pour le moment. Cependant, voici une façon de
+ | continuer la partie :
+ ol
+ li Cliquez sur le bouton Analyse, et revenez juste avant le mauvais coup.
+ li Copiez la FEN indiquée sous l'échiquier (la longue chaîne bizarre).
+ li.
+ Allez dans le Salon, ouvrez la fenêtre "Nouvelle partie", sélectionnez
+ votre adversaire et collez ensuite la FEN dans le champ approprié.
+
+.question.
+ Je diffuse une partie en direct, et aimerais utiliser des flèches et des
+ cercles.
+.answer.
+ Un clic droit sur une case dessine un cercle violet à l'intérieur, et un
+ second clic droit l'efface.
+ 'Glisser déposer' avec le bouton droit depuis une case vers une autre dessine
+ une flèche violette. Cliquez n'importe où avec le bouton gauche pour
+ effacer les dessins.
+
+.question.
+ Je veux démarrer depuis une position spécifique !
+.answer.
+ SI la position souhaitée est sur un échiquier quelque part sur le site,
+ cliquez simplement sur le bouton Analyse (l'icône microscope), et copiez la
+ chaîne apparaissant sous l'échiquier. Si la position est dans votre tête ou
+ sur un échiquier physique, alors vous pouvez soit chercher à comprendre le
+ format FEN par essais et erreurs dans le mode Analyse, ou bien
+ me demander - via le formulaire de contact ou sur Discord. Au passage,
+ ces chaînes FEN sont nécessaires également pour poster un problème.
+
+.question.
+ Je veux un classement ! Je veux des tournois ! Je veux un nouveau poney !
+.answer.
+ D'après mon expérience, s'inquiéter pour un classement ne fait que vous
+ compliquer la vie, donc il n'y en aura pas sur ce site. Rien n'est prévu
+ non plus concernant les tournois, mais vous pouvez en organiser quand-même.
+ Effectuez les appariements quelque part ailleurs et demandez aux gens de se
+ défier.
+
+.question.
+ T'as mentionné le menu "Problèmes" ? C'est quoi ça ?
+.answer.
+ Un espace où vous pouvez partager des positions intéressantes, qui pourraient
+ être des études, des mat (aidés) en 3 etc. Actuellement il n'y a pas de
+ support pour l'analyse rétrograde, mais vous pourriez tout de même envoyer
+ le diagramme final pour permettre aux gens de chercher.
+ Commencez par regarder les problèmes existants, et essayez de les résoudre
+ :-)
+
+.question.
+ Je suis dans le Salon mais ne vois pas mes parties !
+.answer.
+ Vos parties sont rassemblées dans le menu "Mes parties" en haut.
+ Si une partie est surlignée en orange, alors c'est à vous de jouer : cliquez
+ dessus et jouez ! Le nombre de parties en cours en direct ou par
+ correspondance n'est pas limité.
+
+.question.
+ Dans une partie en direct, la pendule s'arrête parfois.
+.answer
+ | Les pendules dans les parties en direct suivent une logique non standard
+ | - mais cohérente, je crois :-)
+ ul
+ li.
+ Si vous jouez un coup puis quittez la partie, votre pendule sera figée
+ dans son état courant jusqu'à ce que vous reveniez dans le jeu. Après
+ son coup, votre adversaire verra votre temps arrêté ; il pourrait décider
+ d'arrêter la partie ou d'abandonner, ou
+ li.
+ Si votre adversaire quitte lui aussi la partie après son coup, alors le
+ temps est juste figé - et vous pouvez décider de reprendre plus tard.
+ | En effet puisque vous ne savez pas ce qu'a joué l'adversaire, il est
+ | normal que votre pendule s'arrête. Cela permet aussi de faire une pause
+ | pendant une longue partie en direct, comme 1h30 + 30s par exemple.
+
+.question.
+ J'ai noté l'adresse d'une partie fascinante, mais l'URL ne fonctionne plus.
+.answer
+ | Les parties en direct sont stockées localement, dans le navigateur
+ | seulement. Si vous êtes un simple spectateur, votre navigateur n'enregistre
+ | même pas la partie, donc celle-ci sera inaccessible lorsque les joueurs
+ | ainsi que tous les observateurs seront partis.
+ | La bonne manière de procéder consiste alors à
+ ol
+ li Télécharger la partie (cf. l'icône sur la droite),
+ li.
+ L'importer en utilisant le bouton dans l'onglet "Parties importées"
+ depuis le menu "Mes parties".
+
+.question.
+ J'ai effacé les données du site, et mes parties en direct ont disparu !
+.answer.
+ Elles sont stockées dans la base de données du navigateur.
+ Vous venez de l'effacer, donc elles ne sont plus là :-)
+ Un nettoyage plus fin est requis : supprimer les cookies est sans danger
+ (vous devrez juste vous re-logger), de même que la suppression des données
+ locales (enregistrant vos préférences comme la couleur de l'échiquier).
+ Cependant, toucher à la base 'IndexedDB' risque de supprimer des parties.
+
+.question.
+ Mais j'aimerais supprimer cette partie là, et celle-là aussi !
+.answer.
+ Cliquez sur la zone du résultat d'une partie depuis les listes "Mes parties",
+ et confirmez la suppression. Si la partie est en cours elle sera d'abord
+ arrêtée. Notez que les parties par correspondance supprimées par un seul des
+ deux joueurs sont toujours accessibles : elles vous sont juste cachées.
+
+.question.
+ J'ai une question sans réponse ici !
+.answer.
+ Si la réponse n'est pas 42 (êtes vous bien sûr ?), utilisez le formulaire de
+ Contact ou demandez sur Discord :-)
+ Cf. les liens en bas de la page.
"New correspondance game:": "Nouvelle partie par corespondance :",
"New game": "Nouvelle partie",
"New problem": "Nouveau problème",
- News: "Nouvelles",
"No challenges found :( Click on 'New game'!": "Aucun défi trouvé :( Cliquez sur 'Nouvelle partie' !",
"No games found :( Send a challenge!": "Aucune partie trouvée :( Envoyez un défi !",
"No more problems": "Plus de problèmes",
moves2.forEach(m2 => {
this.play(m2);
const score = this.getCurrentScore();
- const mvEval =
- ["1-0", "0-1"].includes(score)
- ? (score == "1-0" ? 1 : -1) * maxeval
- : (score == "1/2" ? 0 : initEval);
+ let mvEval = 0;
+ if (["1-0", "0-1"].includes(score))
+ mvEval = (score == "1-0" ? 1 : -1) * maxeval;
+ else if (score == "*")
+ // Add small fluctuations to avoid dropping pieces always on the
+ // first square available.
+ mvEval = initEval + 0.05 - Math.random() / 10;
if (
(color == 'w' && mvEval > m.eval) ||
(color == 'b' && mvEval < m.eval)
--- /dev/null
+<template lang="pug">
+main
+ .row
+ .col-sm-12.col-md-8.col-md-offset-2.col-lg-6.col-lg-offset-3
+ div#faqDiv(v-html="content")
+</template>
+
+<script>
+import { store } from "@/store";
+export default {
+ name: "my-faq",
+ data: function() {
+ return { st: store.state };
+ },
+ computed: {
+ content: function() {
+ // (AJAX) Request to get FAQ content (plain text, HTML)
+ return (
+ require("raw-loader!@/translations/faq/" + this.st.lang + ".pug")
+ // Next two lines fix a weird issue after last update (2019-11)
+ .replace(/\\n/g, " ")
+ .replace(/\\"/g, '"')
+ .replace('module.exports = "', "")
+ .replace(/"$/, "")
+ );
+ }
+ },
+ mounted: function() {
+ this.re_setListeners();
+ },
+ updated: function() {
+ this.re_setListeners();
+ },
+ methods: {
+ re_setListeners: function() {
+ document.querySelectorAll(".answer").forEach(a => {
+ a.style.display = "none";
+ });
+ document.querySelectorAll(".question").forEach(q => {
+ q.addEventListener("click", (e) => {
+ let answerDiv = e.target.nextSibling;
+ const answerVisible = (answerDiv.style.display == "block");
+ answerDiv.style.display = (answerVisible ? "none" : "block");
+ });
+ });
+ }
+ }
+};
+</script>
+
+<style lang="sass">
+#faqDiv
+ @media screen and (max-width: 767px)
+ margin-left: var(--universal-margin)
+ margin-right: var(--universal-margin)
+
+.question
+ color: darkblue
+ font-size: 1.1em
+ margin-top: 15px
+ cursor: pointer
+
+.answer
+ ol, ul
+ margin-top: 0
+ margin-bottom: 0
+</style>
+++ /dev/null
-<template lang="pug">
-main
- input#modalNews.modal(type="checkbox")
- div#newnewsDiv(
- role="dialog"
- data-checkbox="modalNews"
- )
- .card#writeNews
- label.modal-close(for="modalNews")
- textarea#newsContent(
- v-model="curnews.content"
- :placeholder="st.tr['News go here']"
- @input="adjustHeight"
- )
- button(@click="sendNews()") {{ st.tr["Send"] }}
- #dialog.text-center {{ st.tr[infoMsg] }}
- .row
- .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
- button#writeNewsBtn(
- v-if="devTeam"
- @click="showModalNews"
- )
- | {{ st.tr["Write news"] }}
- .news(
- v-for="n,idx in newsList"
- :id="'n' + n.id"
- :class="{margintop:idx>0}"
- )
- span.ndt {{ formatDatetime(n.added) }}
- .dev-buttons(v-if="devTeam")
- button(@click="editNews(n)") {{ st.tr["Edit"] }}
- button(@click="deleteNews(n)") {{ st.tr["Delete"] }}
- button(@click="gotoPrevNext(n, 1)") {{ st.tr["Previous_n"] }}
- button(@click="gotoPrevNext(n, -1)") {{ st.tr["Next_n"] }}
- .news-content(v-html="parseHtml(n.content)")
- button#loadMoreBtn(
- v-if="hasMore"
- @click="loadMore()"
- )
- | {{ st.tr["Load more"] }}
-</template>
-
-<script>
-import { store } from "@/store";
-import { ajax } from "@/utils/ajax";
-import params from "@/parameters";
-import { getDate, getTime } from "@/utils/datetime";
-import { processModalClick } from "@/utils/modalClick";
-export default {
- name: "my-news",
- data: function() {
- return {
- st: store.state,
- // timestamp of oldest showed news:
- cursor: Number.MAX_SAFE_INTEGER,
- // hasMore == TRUE: a priori there could be more news to load
- hasMore: true,
- curnews: { id: 0, content: "" },
- newsList: [],
- infoMsg: ""
- };
- },
- computed: {
- devTeam: function() {
- return params.devs.includes(this.st.user.id);
- }
- },
- created: function() {
- ajax(
- "/news",
- "GET",
- {
- data: { cursor: this.cursor },
- success: (res) => {
- // The returned list is sorted from most recent to oldest
- this.newsList = res.newsList;
- const L = res.newsList.length;
- if (L > 0) this.cursor = res.newsList[L - 1].added;
- else this.hasMore = false;
- }
- }
- );
- },
- mounted: function() {
- // Mark that I've read the news:
- localStorage.setItem("newsRead", Date.now());
- if (this.st.user.id > 0) ajax("/newsread", "PUT");
- document.getElementById("newsMenu").classList.remove("somenews");
- document
- .getElementById("newnewsDiv")
- .addEventListener("click", processModalClick);
- },
- methods: {
- formatDatetime: function(dt) {
- const dtObj = new Date(dt);
- const timePart = getTime(dtObj);
- // Show minutes but not seconds:
- return (
- getDate(dtObj) + " " + timePart.substr(0, timePart.lastIndexOf(":"))
- );
- },
- parseHtml: function(txt) {
- return !txt.match(/<[/a-zA-Z]+>/)
- ? txt.replace(/\n/g, "<br/>") //no HTML tag
- : txt;
- },
- adjustHeight: function() {
- const newsContent = document.getElementById("newsContent");
- // https://stackoverflow.com/a/995374
- newsContent.style.height = "1px";
- newsContent.style.height = 10 + newsContent.scrollHeight + "px";
- },
- resetCurnews: function() {
- this.curnews.id = 0;
- this.curnews.content = "";
- // No need for added and uid fields: never updated
- },
- gotoPrevNext: function(n, dir) {
- document.getElementById("n" + n.id)[
- (dir < 0 ? "previous" : "next") + "ElementSibling"].scrollIntoView();
- },
- showModalNews: function() {
- this.resetCurnews();
- window.doClick("modalNews");
- },
- sendNews: function() {
- const edit = this.curnews.id > 0;
- this.infoMsg = "Processing... Please wait";
- ajax(
- "/news",
- edit ? "PUT" : "POST",
- {
- data: { news: this.curnews },
- success: (res) => {
- if (edit) {
- let n = this.newsList.find(n => n.id == this.curnews.id);
- if (!!n) n.content = this.curnews.content;
- } else {
- const newNews = {
- content: this.curnews.content,
- added: Date.now(),
- uid: this.st.user.id,
- id: res.id
- };
- this.newsList = [newNews].concat(this.newsList);
- }
- document.getElementById("modalNews").checked = false;
- this.infoMsg = "";
- this.resetCurnews();
- }
- }
- );
- },
- editNews: function(n) {
- this.curnews.content = n.content;
- this.curnews.id = n.id;
- // No need for added and uid fields: never updated
- window.doClick("modalNews");
- },
- deleteNews: function(n) {
- if (confirm(this.st.tr["Are you sure?"])) {
- this.infoMsg = "Processing... Please wait";
- ajax(
- "/news",
- "DELETE",
- {
- data: { id: n.id },
- success: () => {
- const nIdx = this.newsList.findIndex(nw => nw.id == n.id);
- this.newsList.splice(nIdx, 1);
- this.infoMsg = "";
- document.getElementById("modalNews").checked = false;
- }
- }
- );
- }
- },
- loadMore: function() {
- ajax(
- "/news",
- "GET",
- {
- data: { cursor: this.cursor },
- success: (res) => {
- const L = res.newsList.length;
- if (L > 0) {
- this.newsList = this.newsList.concat(res.newsList);
- this.cursor = res.newsList[L - 1].added;
- } else this.hasMore = false;
- }
- }
- );
- }
- }
-};
-</script>
-
-<style lang="sass" scoped>
-[type="checkbox"].modal+div .card
- max-width: 767px
- max-height: 100%
-
-textarea#newsContent
- margin: 0
- width: 100%
- min-height: 200px
- max-height: 100%
-
-#dialog
- padding: 5px
- color: blue
-
-#writeNews
- padding-top: 50px
-
-button#writeNewsBtn, button#loadMoreBtn
- margin-top: 0
- margin-bottom: 0
-
-span.ndt
- color: darkblue
- padding: 0 5px 0 var(--universal-margin)
-
-.margintop
- margin-top: 25px
- border-top: 1px solid grey
-@media screen and (max-width: 767px)
- .margintop
- margin-top: 10px
-</style>
-
-<style lang="sass">
-.news
- padding-top: 10px
- & > .dev-buttons
- display: inline-block
- & > .news-content
- margin: var(--universal-margin)
- & > p
- margin: 10px 0
- & > br
- display: block
- margin-top: 10px
- content: " "
-</style>
foreign key (vid) references Variants(id)
);
-create table News (
- id integer primary key,
- uid integer,
- added datetime,
- content text,
- foreign key (uid) references Users(id)
-);
-
create table Challenges (
id integer primary key,
added datetime,
+++ /dev/null
-const db = require("../utils/database");
-
-/*
- * Structure:
- * id: integer
- * added: datetime
- * uid: user id (int)
- * content: text
- */
-
-const NewsModel =
-{
- create: function(content, uid, cb)
- {
- db.serialize(function() {
- const query =
- "INSERT INTO News " +
- "(added, uid, content) " +
- "VALUES " +
- "(" + Date.now() + "," + uid + ",?)";
- db.run(query, content, function(err) {
- cb(err, { id: this.lastID });
- });
- });
- },
-
- getNext: function(cursor, cb)
- {
- db.serialize(function() {
- const query =
- "SELECT * " +
- "FROM News " +
- "WHERE added < " + cursor + " " +
- "ORDER BY added DESC " +
- "LIMIT 10"; //TODO: 10 currently hard-coded
- db.all(query, (err, newsList) => {
- cb(err, newsList);
- });
- });
- },
-
- getTimestamp: function(cb)
- {
- db.serialize(function() {
- const query =
- "SELECT added " +
- "FROM News " +
- "ORDER BY added DESC " +
- "LIMIT 1";
- db.get(query, (err, ts) => {
- cb(err, ts);
- });
- });
- },
-
- update: function(news)
- {
- db.serialize(function() {
- let query =
- "UPDATE News " +
- "SET content = ? " +
- "WHERE id = " + news.id;
- db.run(query, news.content);
- });
- },
-
- remove: function(id)
- {
- db.serialize(function() {
- const query =
- "DELETE FROM News " +
- "WHERE id = " + id;
- db.run(query);
- });
- },
-}
-
-module.exports = NewsModel;
router.use("/", require("./users"));
router.use("/", require("./variants"));
router.use("/", require("./problems"));
-router.use("/", require("./news"));
module.exports = router;
+++ /dev/null
-let router = require("express").Router();
-const access = require("../utils/access");
-const params = require("../config/parameters");
-const NewsModel = require("../models/News");
-const sanitizeHtml = require('sanitize-html');
-
-router.post("/news", access.logged, access.ajax, (req,res) => {
- if (params.devs.includes(req.userId)) {
- const content = sanitizeHtml(req.body.news.content);
- NewsModel.create(content, req.userId, (err, ret) => {
- res.json(err || ret);
- });
- }
-});
-
-router.get("/news", access.ajax, (req,res) => {
- const cursor = req.query["cursor"];
- if (!!cursor && !!cursor.match(/^[0-9]+$/)) {
- NewsModel.getNext(cursor, (err, newsList) => {
- res.json(err || { newsList: newsList });
- });
- }
-});
-
-router.get("/newsts", access.ajax, (req,res) => {
- // Special query for footer: just return timestamp of last news
- NewsModel.getTimestamp((err, ts) => {
- res.json(err || { timestamp: !!ts ? ts.added : 0 });
- });
-});
-
-router.put("/news", access.logged, access.ajax, (req,res) => {
- let news = req.body.news;
- if (
- params.devs.includes(req.userId) &&
- news.id.toString().match(/^[0-9]+$/)
- ) {
- news.content = sanitizeHtml(news.content);
- NewsModel.update(news);
- res.json({});
- }
-});
-
-router.delete("/news", access.logged, access.ajax, (req,res) => {
- const nid = req.query.id;
- if (
- params.devs.includes(req.userId) &&
- nid.toString().match(/^[0-9]+$/)
- ) {
- NewsModel.remove(nid);
- res.json({});
- }
-});
-
-module.exports = router;