Added card styles

This commit is contained in:
Mysaa Java
2026-08-25 05:22:18 +02:00
parent 639a5565ad
commit 142d08cc28
7 changed files with 1006 additions and 72 deletions
@@ -9,8 +9,13 @@ import org.springframework.web.servlet.view.RedirectView;
import com.bernard.nodecames.game.GameManager;
import lombok.AllArgsConstructor;
@AllArgsConstructor
@Controller
public class HttpController {
GameManager gm;
@GetMapping("/")
public String index() {
@@ -24,7 +29,7 @@ public class HttpController {
@GetMapping("/create-room")
public RedirectView createRoom() {
UUID uuid = GameManager.newGrid();
UUID uuid = gm.newGrid();
return new RedirectView("/room/"+uuid.toString()+"/grid");
}
}
@@ -1,30 +1,56 @@
package com.bernard.nodecames.frontend;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import com.bernard.nodecames.game.GameManager;
import com.bernard.nodecames.model.Card;
import com.bernard.nodecames.model.Grid;
import com.bernard.nodecames.model.Card.Color;
import com.bernard.nodecames.model.Grid.Phase;
import lombok.AllArgsConstructor;
import tools.jackson.databind.JsonNode;
import tools.jackson.databind.node.JsonNodeFactory;
import tools.jackson.databind.node.ObjectNode;
@Controller
@AllArgsConstructor
public class WebSocketController {
private static final JsonNodeFactory jsn = JsonNodeFactory.instance;
@Autowired
GameManager gm;
private GameManager gm;
private SimpMessagingTemplate template;
public void publishNewPhase(Grid g) {
this.template.convertAndSend(
"/topic/new-phase",
g.getPhase().name().toLowerCase()
);
}
public void publishCardUpdateToPlayer(Grid g, int cardIndex, char player) {
Card c = g.getCards()[cardIndex];
this.template.convertAndSend(
"/topic/update-card/" + Character.toLowerCase(player),
gm.cardData(c, player),
Map.of("cardIndex", cardIndex)
);
}
public void publishCardUpdate(Grid g, int cardIndex) {
publishCardUpdateToPlayer(g, cardIndex, 'A');
publishCardUpdateToPlayer(g, cardIndex, 'B');
}
@GetMapping("/room/{id}/game/{player}")
public Object grid(@PathVariable("id") String gridId, @PathVariable("player") String playerStr) {
@@ -36,9 +62,9 @@ public class WebSocketController {
else
throw new IllegalArgumentException("Unknown player type");
Grid g = GameManager.findGrid(gridId);
Grid g = gm.findGrid(gridId);
return new ResponseEntity<>(GameManager.gridData(g, player), HttpStatus.OK);
return new ResponseEntity<>(gm.gridData(g, player), HttpStatus.OK);
}
@MessageMapping("submit-hint")
@@ -47,10 +73,11 @@ public class WebSocketController {
String hint = content.asObject().get("hint").stringValue();
int wordCount = content.asObject().get("hintWordCount").intValue();
Grid g = GameManager.findGrid(roomId);
Grid g = gm.findGrid(roomId);
gm.proposeHint(g, player.charAt(0), hint, wordCount);
content.asObject().set("player", jsn.stringNode(player));
this.publishNewPhase(g);
return content;
}
@@ -59,17 +86,24 @@ public class WebSocketController {
public JsonNode pointCard(@Header("room") String roomId, @Header("player") String player, @Payload JsonNode content) {
int cardIndex = content.asObject().get("cardIndex").intValue();
Grid g = GameManager.findGrid(roomId);
gm.pointCard(g, player.charAt(0), cardIndex);
Grid g = gm.findGrid(roomId);
Color c = gm.pointCard(g, player.charAt(0), cardIndex);
content.asObject().set("color", jsn.stringNode(c.name().toLowerCase()));
content.asObject().set("player", jsn.stringNode(player));
if(g.getPhase() != Phase.GUESSING_A && g.getPhase() != Phase.GUESSING_B)
publishNewPhase(g);
publishCardUpdate(g, cardIndex);
return content;
}
@MessageMapping("end-guessing")
@SendTo("/topic/end-guessing")
public String endGuessing(@Header("room") String roomId, @Header("player") String player) {
Grid g = GameManager.findGrid(roomId);
public JsonNode endGuessing(@Header("room") String roomId, @Header("player") String player) {
Grid g = gm.findGrid(roomId);
gm.endGuessing(g, player.charAt(0));
return "";
ObjectNode out = jsn.objectNode();
out.set("player", jsn.stringNode(player));
return out;
}
}
@@ -1,14 +1,20 @@
package com.bernard.nodecames.game;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
import java.util.UUID;
import java.util.stream.IntStream;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import com.bernard.nodecames.model.Card;
@@ -27,48 +33,90 @@ public class GameManager {
private static final JsonNodeFactory jsn = JsonNodeFactory.instance;
//TODO Remove static, make something more Spring Boot-y
private static Map<UUID, Grid> games = new HashMap<>();
public static JsonNode gridData(Grid g, char player) {
@Value("classpath:dictionaries/fr.txt")
Resource dictFr;
//TODO do Spring boot magic to only generate this once
public List<String> allWords() {
try (Scanner wordsScanner = new Scanner(dictFr.getInputStream())) {
List<String> out = new ArrayList<>();
while (wordsScanner.hasNextLine())
out.add(wordsScanner.nextLine());
return Collections.unmodifiableList(out);
} catch (IOException e) {
throw new IllegalStateException("Could not read internal dictionnary", e);
}
}
public String[] randomWords(int count) {
List<String> allWords = allWords();
//TODO seed the games
Random r = new Random();
if(count > allWords.size())
throw new IllegalArgumentException("Not enough words in the dictionary");
String[] out = new String[count];
Set<Integer> already = new HashSet<>();
int k;
for(int i = 0; i<count; i++) {
do {
k = r.nextInt(allWords.size());
} while (already.contains(k));
out[i] = allWords.get(k);
already.add(k);
}
return out;
}
public JsonNode cardData(Card c, char player) {
ObjectNode cardNode = jsn.objectNode();
cardNode.set("word", jsn.stringNode(c.getWord()));
cardNode.set("color", jsn.stringNode((player=='A'?c.getColorA():c.getColorB()).name().toLowerCase()));
if((player=='A' && c.isRevealedA()) || (player=='B' && c.isRevealedB()))
cardNode.set("otherColor", jsn.stringNode((player=='A'?c.getColorB():c.getColorA()).name().toLowerCase()));
cardNode.set("revealed-a", jsn.booleanNode(c.isRevealedA()));
cardNode.set("revealed-b", jsn.booleanNode(c.isRevealedB()));
return cardNode;
}
public JsonNode eventData(Grid g, GameEvent ge) {
ObjectNode geNode = jsn.objectNode();
geNode.set("type", jsn.stringNode(ge.getType().name().toLowerCase()));
geNode.set("issuer", jsn.stringNode(Character.toString(ge.getIssuer())));
switch (ge.getType()) {
case GameEvent.Type.HINT:
Hint hint = (Hint)ge.getData();
geNode.set("word", jsn.stringNode(hint.getWord()));
geNode.set("wordCount", jsn.numberNode(hint.getWordCount()));
break;
case GameEvent.Type.GUESS:
Card c = (Card)ge.getData();
Integer pos = IntStream.range(0, g.getCardCount())
.filter(i -> c == g.getCards()[i])
.findFirst()
.getAsInt();
geNode.set("card-index", jsn.numberNode(pos));
break;
case GameEvent.Type.END_GUESSING:
geNode.set("manual", jsn.booleanNode((Boolean)ge.getData()));
break;
case GameEvent.Type.START_GAME:
break;
}
return geNode;
}
public JsonNode gridData(Grid g, char player) {
ArrayNode cardsNode = jsn.arrayNode(g.getCardCount());
for (int i = 0; i < g.getCardCount(); i++) {
ObjectNode cardNode = jsn.objectNode();
Card c = g.getCards()[i];
cardNode.set("word", jsn.stringNode(c.getWord()));
cardNode.set("color", jsn.stringNode((player=='A'?c.getColorA():c.getColorB()).name().toLowerCase()));
if((player=='A' && c.isRevealedA()) || (player=='B' && c.isRevealedB()))
cardNode.set("otherColor", jsn.stringNode((player=='A'?c.getColorB():c.getColorA()).name().toLowerCase()));
cardsNode.add(cardNode);
}
for (int i = 0; i < g.getCardCount(); i++)
cardsNode.add(cardData(g.getCards()[i], player));
ArrayNode eventsNode = jsn.arrayNode(g.getGameEvents().size());
for(GameEvent ge : g.getGameEvents()) {
ObjectNode geNode = jsn.objectNode();
geNode.set("type", jsn.stringNode(ge.getType().name().toLowerCase()));
geNode.set("issuer", jsn.stringNode(Character.toString(ge.getIssuer())));
switch (ge.getType()) {
case GameEvent.Type.HINT:
Hint hint = (Hint)ge.getData();
geNode.set("word", jsn.stringNode(hint.getWord()));
geNode.set("wordCount", jsn.numberNode(hint.getWordCount()));
break;
case GameEvent.Type.GUESS:
Card c = (Card)ge.getData();
Integer pos = IntStream.range(0, g.getCardCount())
.filter(i -> c == g.getCards()[i])
.findFirst()
.getAsInt();
geNode.set("card-index", jsn.numberNode(pos));
break;
case GameEvent.Type.END_GUESSING:
geNode.set("manual", jsn.booleanNode((Boolean)ge.getData()));
break;
case GameEvent.Type.START_GAME:
break;
}
eventsNode.add(geNode);
}
for(GameEvent ge : g.getGameEvents())
eventsNode.add(eventData(g, ge));
ObjectNode currentHintNode = jsn.objectNode();
if(g.getCurrentHint() != null) {
@@ -89,15 +137,13 @@ public class GameManager {
return out;
}
public static Grid findGrid(String gridId) {
public Grid findGrid(String gridId) {
return games.get(UUID.fromString(gridId));
}
public static UUID newGrid() {
public UUID newGrid() {
UUID uuid = UUID.randomUUID();
String[] words = new String[25];
for (int i = 0; i < words.length; i++)
words[i] = "MotNumero"+Integer.toString(i);
String[] words = randomWords(25);
List<Card> cards = new ArrayList<>(25);
int i = 0;
cards.add(new Card(words[i++], Color.BLACK, Color.BLACK));
@@ -141,7 +187,7 @@ public class GameManager {
g.setCurrentGuessCount(0);
}
public void pointCard(Grid g, char player, int cardIndex) {
public Card.Color pointCard(Grid g, char player, int cardIndex) {
if (!(((player == 'A') && (g.getPhase() == Grid.Phase.GUESSING_A)) ||
((player == 'B') && (g.getPhase() == Grid.Phase.GUESSING_B)))) {
throw new RuntimeException("This action is not allowed now");
@@ -199,7 +245,7 @@ public class GameManager {
g.setPhase(Grid.Phase.HINTING_B);
g.newGameEvent(GameEvent.newEndGuessingEvent(false, player));
}
return (player == 'A')?c.getColorB():c.getColorA();
}
public void endGuessing(Grid g, char player) {
+697
View File
@@ -0,0 +1,697 @@
Accident
Achat
Acné
Action
Adolescent
Afrique
Aiguille
Allumer
Alpes
Alphabet
Altitude
Amérique
Ami
Amour
Ampoule
Anniversaire
Appétit
Araignée
Arbre
Arc
Arc-en-ciel
Argent
Arme
Armée
Ascenseur
Asie
Assis
Astronaute
Atchoum
Athlète
Atlantide
Aube
Australie
Avec
Aventure
Avion
Avocat
Bac
Baguette
Bain
Baiser
Balai
Balle
Ballon
Bambou
Banane
Bannir
Barbe
Barrière
Bas
Basket
Bateau
Bâton
Batterie
Bébé
Beethoven
Bête
Biberon
Bière
Blanc
Blé
Bleu
Bob
Boisson
Boîte
Bombe
Bonbon
Bonnet
Bord
Bordeaux
Botte
Boue
Bougie
Boule
Bouteille
Bouton
Branche
Bras
Bravo
Bretagne
Brise
Brosse
Bruit
Brume
Brun
Bûche
Bulle
Bureau
But
Cabane
Cabine
Cacher
Cadeau
Cafard
Café
Caisse
Calculer
Calme
Caméra
Camion
Camping
Canada
Canard
Canette
Canine
Cap
Capitalisme
Car
Carotte
Carré
Carte
Carton
Casque
Casser
Cassette
Cauchemar
Cause
Ceinture
Cellule
Cercle
Chaîne
Chair
Chaise
Champ
Champion
Chant
Chapeau
Charbon
Charge
Chasse
Chat
Château
Chaud
Chaussure
Chauve
Chef
Chemise
Chêne
Cher
Cheval
Chevalier
Cheveu
Chien
Chiffre
Chine
Chocolat
Chômage
Ciel
Cil
Cinéma
Cire
Cirque
Citron
Clé
Clou
Clown
Coach
Coccinelle
Code
Cœur
Col
Colle
Colline
Colonne
Cône
Confort
Continu
Contre
Conversation
Copain
Coq
Coquillage
Corbeau
Corde
Corps
Côte
Coude
Couloir
Coup
Cour
Courant
Courrier
Cours
Course
Court
Couteau
Couvert
Couverture
Cowboy
Crac
Crayon
Crème
Critique
Crochet
Croix
Croûte
Cuillère
Cuir
Cuisine
Culotte
Cycle
Dard
Debout
Défaut
Dehors
Démocratie
Dent
Dentiste
Dessin
Devoir
Diamant
Dictionnaire
Dieu
Dinosaure
Discours
Disque
Dix
Docteur
Doigt
Domino
Dormir
Droit
Eau
Échec
Échelle
Éclair
École
Écran
Écraser
Écrit
Église
Égout
Électricité
Éléphant
Élève
Elfe
Empreinte
Enceinte
Épice
Épine
Erreur
Espace
Espion
Essence
État
Été
Étoile
Étranger
Éventail
Évolution
Explosion
Extension
Face
Fan
Farce
Fatigue
Fauteuil
Femme
Fenêtre
Fer
Fête
Feu
Feuille
Fidèle
Fil
Fille
Flamme
Flèche
Fleur
Fleuve
Fond
Football
Forêt
Forger
Foudre
Fouet
Four
Fourmi
Froid
Fromage
Front
Fruit
Fuir
Futur
Garçon
Gâteau
Gauche
Gaz
Gazon
Gel
Genou
Glace
Gomme
Gorge
Goutte
Grand
Grèce
Grenouille
Grippe
Gris
Gros
Groupe
Guitare
Hasard
Haut
Hélicoptère
Herbe
Heureux
Histoire
Hiver
Hôtel
Hugo
Huile
Humide
Humour
Indice
Internet
Inviter
Italie
Jacques
Jambe
Jambon
Jardin
Jaune
Jean
Jeanne
Jet
Jeu
Jogging
Jour
Journal
Jupiter
Kilo
Kiwi
Laine
Lait
Langue
Lapin
Latin
Laver
Lecteur
Léger
Lent
Lettre
Lien
Ligne
Linge
Lion
Lit
Livre
Loi
Long
Louis
Loup
Lumière
Lundi
Lune
Lunette
Machine
Macho
Main
Maison
Maîtresse
Mal
Maladie
Maman
Mammouth
Manger
Marais
Marc
Marche
Mariage
Marie
Mariée
Marque
Marseille
Masse
Mer
Messe
Mètre
Métro
Miaou
Micro
Mieux
Mille
Mine
Miroir
Moderne
Moitié
Monde
Monstre
Montagne
Montre
Mort
Moteur
Moto
Mou
Mouche
Moulin
Moustache
Mouton
Mur
Muscle
Musique
Mystère
Nage
Nature
Neige
Neutre
New York
Nez
Nid
Ninja
Niveau
Noël
Nœud
Noir
Nous
Nuage
Nuit
Numéro
Œil
Œuf
Oiseau
Olympique
Ombre
Ongle
Or
Oral
Orange
Ordinateur
Ordre
Ordure
Oreille
Organe
Orgueil
Ours
Outil
Ouvert
Ovale
Pain
Palais
Panneau
Pantalon
Pantin
Papa
Papier
Papillon
Paradis
Parc
Paris
Parole
Partie
Passe
Pâte
Patin
Patte
Payer
Pêche
Peinture
Pendule
Penser
Personne
Petit
Peur
Philosophe
Photo
Phrase
Piano
Pièce
Pied
Pierre
Pile
Pilote
Pince
Pioche
Pion
Pirate
Pire
Piscine
Place
Plafond
Plage
Plaie
Plan
Planche
Planète
Plante
Plastique
Plat
Plat
Plomb
Plonger
Pluie
Poche
Poète
Poids
Poing
Point
Poivre
Police
Politique
Pollen
Polo
Pomme
Pompe
Pont
Population
Port
Porte
Portefeuille
Positif
Poste
Poubelle
Poule
Poupée
Pousser
Poussière
Pouvoir
Préhistoire
Premier
Présent
Presse
Prier
Princesse
Prise
Privé
Professeur
Psychologie
Public
Pull
Punk
Puzzle
Pyjama
Quatre
Quinze
Race
Radio
Raisin
Rap
Rayé
Rayon
Réfléchir
Reine
Repas
Reptile
Requin
Rêve
Riche
Rideau
Rien
Rire
Robinet
Roche
Roi
Rond
Rose
Roue
Rouge
Rouille
Roux
Russie
Sable
Sabre
Sac
Sain
Saison
Sale
Salle
Salut
Samu
Sandwich
Sang
Sapin
Satellite
Saumon
Saut
Savoir
Schtroumpf
Science
Scout
Sec
Seine
Sel
Sept
Serpent
Serrer
Sexe
Shampooing
Siècle
Siège
Sieste
Silhouette
Sirène
Ski
Soleil
Sommeil
Son
Sonner
Sorcière
Sourd
Souris
Sport
Star
Station
Stylo
Sur
Surface
Sushi
Swing
Tableau
Tache
Taille
Tante
Tapis
Tard
Taxi
Téléphone
Télévision
Temple
Temps
Tennis
Tête
Thé
Tigre
Tintin
Tissu
Titre
Titre
Toast
Toilette
Tokyo
Tombe
Ton
Top
Touche
Toujours
Tour
Tournoi
Tout
Trace
Train
Traîner
Transport
Travail
Trésor
Triangle
Triste
Trône
Troupeau
Tsar
Tube
Tuer
Tuer
Tupperware
Tuyau
Twitter
Type
Université
Vache
Vache
Vague
Vaisselle
Valeur
Ver
Verdict
Verre
Vers
Vert
Veste
Viande
Vide
Vie
Vieux
Ville
Vin
Vingt
Violon
Vipère
Vision
Vite
Vive
Vœu
Voile
Voisin
Voiture
Vol
Volume
Vote
Vouloir
Voyage
Zen
Zéro
Zodiaque
Zone
Zoo
+63 -1
View File
@@ -2,7 +2,11 @@ li.card {
border: purple solid 2pt;
list-style-type: none;
padding: 1ex;
margin: 1ex;
margin: .2ex;
width: 30ex;
height: 12ex;
line-break: anywhere;
text-align: center;
font-size: 16px;
}
ul#cards-list {
@@ -13,4 +17,62 @@ ul#cards-list {
span.card-word {
font-weight: bold;
font-size: 30px;
}
.green {
color: #111111;
background:
linear-gradient(63deg, #40DD62 23%, transparent 23%) 7px 0,
linear-gradient(63deg, transparent 74%, #40DD62 78%),
linear-gradient(63deg, transparent 34%, #40DD62 38%, #40DD62 58%, transparent 62%),
#5CE279;
background-size: 16px 48px;
}
.black {
color: #EEEEEE;
background:
linear-gradient(27deg, #151515 5px, transparent 5px) 0 5px,
linear-gradient(207deg, #151515 5px, transparent 5px) 10px 0px,
linear-gradient(27deg, #222 5px, transparent 5px) 0px 10px,
linear-gradient(207deg, #222 5px, transparent 5px) 10px 5px,
linear-gradient(90deg, #1b1b1b 10px, transparent 10px),
linear-gradient(#1d1d1d 25%, #1a1a1a 25%, #1a1a1a 50%, transparent 50%, transparent 75%, #242424 75%, #242424);
background-color: #131313;
background-size: 20px 20px;
}
.white {
color: #222222;
background-color:#EEEEEE;
background-image:
radial-gradient(circle at 100% 150%, #EEEEEE 24%, white 24%, white 28%, #EEEEEE 28%, #EEEEEE 36%, white 36%, white 40%, transparent 40%, transparent),
radial-gradient(circle at 0 150%, #EEEEEE 24%, white 24%, white 28%, #EEEEEE 28%, #EEEEEE 36%, white 36%, white 40%, transparent 40%, transparent),
radial-gradient(circle at 50% 100%, white 10%, #EEEEEE 10%, #EEEEEE 23%, white 23%, white 30%, #EEEEEE 30%, #EEEEEE 43%, white 43%, white 50%, #EEEEEE 50%, #EEEEEE 63%, white 63%, white 71%, transparent 71%, transparent),
radial-gradient(circle at 100% 50%, white 5%, #EEEEEE 5%, #EEEEEE 15%, white 15%, white 20%, #EEEEEE 20%, #EEEEEE 29%, white 29%, white 34%, #EEEEEE 34%, #EEEEEE 44%, white 44%, white 49%, transparent 49%, transparent),
radial-gradient(circle at 0 50%, white 5%, #EEEEEE 5%, #EEEEEE 15%, white 15%, white 20%, #EEEEEE 20%, #EEEEEE 29%, white 29%, white 34%, #EEEEEE 34%, #EEEEEE 44%, white 44%, white 49%, transparent 49%, transparent);
background-size: 100px 50px;
}
.card-bottom-bar {
display: grid;
grid-template-columns: 5ex 17ex 5ex;
justify-content: center;
}
.card-bottom-bar div {
width: 3ex;
height: 3ex;
font-size: 20pt;
border: black solid 2pt;
font-weight: bold;
}
.card-bottom-bar button {
margin-left: 1ex;
margin-right: 1ex;
}
.card.card-done {
opacity: 70%;
}
+93 -12
View File
@@ -2,6 +2,7 @@ var socket = null
var player = '_'
var roomId = '_'
var wsHeaders = {}
var cards = []
function getRoomId() {
const urlRegex = /\/room\/([a-f0-9-]{36})\/grid$/
@@ -11,27 +12,93 @@ function getRoomId() {
return res[1]
}
function makeCards(data) {
var cards = data['cards']
function updatePhase(phase) {
if(phase == "hinting_any" || (phase == "hinting_a" && player == 'A') || (phase == "hinting_b" && player == 'B')) {
// Hinting
$('.card-button').css('visibility', 'hidden')
$('#hint-text').hide()
$('#submit-hint').show()
$('#other-playing').hide()
$('#end-guessing').hide()
} else if ((phase == "hinting_b" && player == 'A') || (phase == "hinting_a" && player == 'B')) {
// Wait for the other one
$('.card-button').css('visibility', 'hidden')
$('#hint-text').hide()
$('#submit-hint').hide()
$('#other-playing').show()
$('#end-guessing').hide()
} else if ((phase == "guessing_a" && player == 'B') || (phase == "guessing_b" && player == 'A')) {
// Wait for the other one
$('.card-button').css('visibility', 'hidden')
$('#hint-text').show()
$('#submit-hint').hide()
$('#other-playing').show()
$('#end-guessing').hide()
} else if ((phase == "guessing_a" && player == 'A') || (phase == "guessing_b" && player == 'B')) {
// Guessing
$('.card-button').css('visibility', 'visible')
$('.card-button.untouchable').css('visibility', 'hidden')
$('#hint-text').show()
$('#submit-hint').hide()
$('#other-playing').hide()
$('#end-guessing').show()
}
}
function setHint(hint, wordCount) {
$('#hint-text').text(hint+" in "+wordCount)
}
function updateCard(i) {
card = cards[i]
if(card['revealed-a']) {
$(`#card-${i}-b-public`).addClass((player=='A')?card.otherColor:card.color)
$(`#card-${i}-b-public`).css('visibility', 'visible')
} else {
$(`#card-${i}-b-public`).css('visibility', 'hidden')
}
if(card['revealed-b']) {
$(`#card-${i}-a-public`).addClass((player=='B')?card.otherColor:card.color)
$(`#card-${i}-a-public`).css('visibility', 'visible')
} else {
$(`#card-${i}-a-public`).css('visibility', 'hidden')
}
cardDone = (card['revealed-a'] && ((player=='A')?card.otherColor:card.color == "green")) ||
(card['revealed-b'] && ((player=='B')?card.otherColor:card.color == "green")) ||
(card['revealed-a'] && card['revealed-b']);
if(cardDone) $(`#card-${i}`).addClass('card-done')
cantTouch = cardDone ||
(player=='A' && card['revealed-a']) ||
(player=='B' && card['revealed-b']);
if(cantTouch) {
$(`#card-${i}-button`).addClass('untouchable')
$(`#card-${i}-button`).css('visibility', 'hidden')
}
}
function initGame(data) {
cards = data['cards']
$('#cards-list').empty()
for(var i = 0; i<cards.length; i++) {
html = `
<li class="card" id="card-${i}">
<li class="card ${cards[i].color}" id="card-${i}">
<span class="card-word">${cards[i].word}</span><br/>
Color: <span class="card-color-text" id="card-${i}-color">${cards[i].color}</span><br/>
<button id="card-${i}-button">Toucher</button>
<div class="card-bottom-bar">
<div id="card-${i}-a-public">A</div>
<button class="card-button" id="card-${i}-button">Toucher</button>
<div id="card-${i}-b-public">B</div>
</div>
</li>
`
$('#cards-list').append($(html))
$(`#card-${i}-button`).on('click', pointCard)
updateCard(i)
}
updatePhase(data['phase'])
}
function selectPlayer(e) {
console.log(e)
console.log(e.target)
console.log(e.target.id)
console.log(e.target.id == "select-player-a")
player = (e.target.id == "select-player-a") ? 'A' : 'B'
wsHeaders = {
"room": roomId,
@@ -44,7 +111,7 @@ function selectPlayer(e) {
contentType: 'application/json',
type: "GET",
url: "/room/"+roomId+"/game/player-"+player.toLowerCase(),
success: makeCards
success: initGame
})
socket = Stomp.over(new SockJS('/socket'));
@@ -52,6 +119,8 @@ function selectPlayer(e) {
socket.subscribe('/topic/submit-hint', onSubmitHint);
socket.subscribe('/topic/point-card', onPointCard);
socket.subscribe('/topic/end-guessing', onEndGuessing);
socket.subscribe('/topic/new-phase', onNewPhase);
socket.subscribe('/topic/update-card/' + player.toLowerCase(), onUpdateCard);
});
}
@@ -75,17 +144,19 @@ function endGuessing(e) {
function onSubmitHint(m) {
data = JSON.parse(m.body)
setHint(data['hint'], data['hintWordCount'])
$("#event-log").append($(`
<li>
${data['hint']} en ${data['hintWordCount']}
${data.player} proposed "${data['hint']}" in ${data['hintWordCount']} word(s)
</li>
`))
}
function onPointCard(m) {
data = JSON.parse(m.body)
i = data['cardIndex']
$("#event-log").append($(`
<li>
Pointed card ${data['cardIndex']}
${data.player} pointed card ${cards[i].word} (${data.color})
</li>
`))
}
@@ -96,6 +167,16 @@ function onEndGuessing(m) {
</li>
`))
}
function onNewPhase(m) {
updatePhase(m.body)
}
function onUpdateCard(m) {
data = JSON.parse(m.body)
i = Number(m.headers['cardIndex'])
cards[i] = data
updateCard(i)
}
function initialize() {
$('#select-player-a').on('click', selectPlayer)
+10 -1
View File
@@ -21,6 +21,10 @@
</ul>
<div id="hint-text">
</div>
<div id="submit-hint">
<input type="text" id="submit-hint-text"/>
<select id="submit-hint-wordcount">
@@ -33,7 +37,12 @@
</select>
<button>Submit Hint</button>
</div>
<button id="end-guessing-button">End Guessing</button>
<div id="other-playing">
Waiting for the other side to play
</div>
<div id="end-guessing">
<button id="end-guessing-button">End Guessing</button>
</div>
<br/>
<ol id="event-log">