Compare commits
10 Commits
5d769c3989
...
0fcd12d885
Author | SHA1 | Date | |
---|---|---|---|
0fcd12d885 | |||
b2a4fc85ea | |||
9cbc95e131 | |||
320766a0b1 | |||
249ce77323 | |||
9b669ce181 | |||
2a21a8a0d0 | |||
5a9b20dd0e | |||
745baf798f | |||
2adf0a44a1 |
@ -1,11 +1,11 @@
|
||||
image: ubuntu/lts
|
||||
image: debian/unstable
|
||||
packages:
|
||||
- openjdk-11-jre-headless
|
||||
- openjdk-19-jdk
|
||||
- maven
|
||||
sources:
|
||||
- https://git.sr.ht/~crg/lingo
|
||||
artifacts:
|
||||
- lingo/server/target/lingo-server.jar
|
||||
- lingo/server/target/lingo.jar
|
||||
tasks:
|
||||
- build: |
|
||||
cd lingo
|
||||
|
2
Procfile
2
Procfile
@ -1 +1 @@
|
||||
web: java -jar server/target/lingo-server.jar
|
||||
web: java -jar server/target/lingo.jar
|
||||
|
12
README.md
12
README.md
@ -1,17 +1,19 @@
|
||||
## Lingo
|
||||
|
||||
[](https://builds.sr.ht/~crg?)
|
||||
|
||||
A word guessing game based on the [game show](https://en.wikipedia.org/wiki/Lingo_(American_game_show)).
|
||||
|
||||
[Screenshots](screenshots/)
|
||||
|
||||
#### Browser client
|
||||
|
||||
- Practice: https://lingo.charego.com/practice.html
|
||||
- Competitive: https://lingo.charego.com
|
||||
- Practice: https://lingo.gould.dev/practice.html
|
||||
- Competitive: https://lingo.gould.dev
|
||||
|
||||
#### JavaFX client
|
||||
|
||||
- Requirements: Java 11, Maven 3
|
||||
- Requirements: Java 19, Maven 3
|
||||
- Build: `mvn clean install`
|
||||
- Start client: `mvn -f client javafx:run`
|
||||
|
||||
@ -19,8 +21,8 @@ A word guessing game based on the [game show](https://en.wikipedia.org/wiki/Ling
|
||||
|
||||
- Build: `mvn clean install`
|
||||
- Start server
|
||||
* Default port (8080): `java -jar server/target/lingo-server.jar`
|
||||
* Custom port: `java -jar server/target/lingo-server.jar --server.port=<port>`
|
||||
* Default port (8080): `java -jar server/target/lingo.jar`
|
||||
* Custom port: `java -jar server/target/lingo.jar --server.port=<port>`
|
||||
- Start client
|
||||
* Browser: `open http://localhost:<port>`
|
||||
* JavaFX: `mvn -f client javafx:run -Dlingo-url=http://localhost:<port>`
|
||||
|
@ -3,8 +3,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.charego</groupId>
|
||||
<artifactId>lingo-parent</artifactId>
|
||||
<groupId>dev.gould</groupId>
|
||||
<artifactId>lingo</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.api;
|
||||
package dev.gould.lingo.api;
|
||||
|
||||
public class Destinations {
|
||||
|
@ -1,3 +1,3 @@
|
||||
module com.charego.lingo.api {
|
||||
exports com.charego.lingo.api;
|
||||
module dev.gould.lingo.api {
|
||||
exports dev.gould.lingo.api;
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.charego</groupId>
|
||||
<artifactId>lingo-parent</artifactId>
|
||||
<groupId>dev.gould</groupId>
|
||||
<artifactId>lingo</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
<name>Lingo :: Client</name>
|
||||
|
||||
<properties>
|
||||
<javafx.version>11.0.2</javafx.version>
|
||||
<lingo.url>https://lingo.charego.com</lingo.url>
|
||||
<javafx.version>19</javafx.version>
|
||||
<lingo.url>https://lingo.gould.dev</lingo.url>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -52,22 +52,14 @@
|
||||
<plugin>
|
||||
<groupId>org.openjfx</groupId>
|
||||
<artifactId>javafx-maven-plugin</artifactId>
|
||||
<version>0.0.4</version>
|
||||
<version>0.0.8</version>
|
||||
<configuration>
|
||||
<mainClass>com.charego.lingo.client.bootstrap.LingoClient</mainClass>
|
||||
<mainClass>dev.gould.lingo.client/dev.gould.lingo.client.bootstrap.LingoClient</mainClass>
|
||||
<options>
|
||||
<option>-Dlingo.url=${lingo.url}</option>
|
||||
</options>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.charego.lingo.client.bootstrap.LingoClient</mainClass>
|
||||
<addResourcesToClasspath>true</addResourcesToClasspath>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.bootstrap;
|
||||
package dev.gould.lingo.client.bootstrap;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
@ -1,12 +1,12 @@
|
||||
package com.charego.lingo.client.bootstrap;
|
||||
package dev.gould.lingo.client.bootstrap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.charego.lingo.client.multiplayer.MultiplayerConfig;
|
||||
import com.charego.lingo.client.multiplayer.MultiplayerPresenter;
|
||||
import com.charego.lingo.client.singleplayer.SinglePlayerPresenter;
|
||||
import com.charego.lingo.client.util.FxmlController;
|
||||
import dev.gould.lingo.client.multiplayer.MultiplayerConfig;
|
||||
import dev.gould.lingo.client.multiplayer.MultiplayerPresenter;
|
||||
import dev.gould.lingo.client.singleplayer.SinglePlayerPresenter;
|
||||
import dev.gould.lingo.client.util.FxmlController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.bootstrap;
|
||||
package dev.gould.lingo.client.bootstrap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -10,9 +10,9 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.charego.lingo.common.WordReader;
|
||||
import dev.gould.lingo.common.WordReader;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class WordRepository {
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.multiplayer;
|
||||
package dev.gould.lingo.client.multiplayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.multiplayer;
|
||||
package dev.gould.lingo.client.multiplayer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
@ -6,9 +6,9 @@ import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.charego.lingo.common.LobbyData;
|
||||
import dev.gould.lingo.common.LobbyData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -34,14 +34,14 @@ import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import javafx.scene.web.WebView;
|
||||
import com.charego.lingo.api.Destinations;
|
||||
import com.charego.lingo.client.util.FxmlController;
|
||||
import com.charego.lingo.client.view.Board;
|
||||
import com.charego.lingo.client.view.OpponentBoard;
|
||||
import com.charego.lingo.client.view.PlayerBoard;
|
||||
import com.charego.lingo.common.Game;
|
||||
import com.charego.lingo.common.GameLeftMessage;
|
||||
import com.charego.lingo.common.Report;
|
||||
import dev.gould.lingo.api.Destinations;
|
||||
import dev.gould.lingo.client.util.FxmlController;
|
||||
import dev.gould.lingo.client.view.Board;
|
||||
import dev.gould.lingo.client.view.OpponentBoard;
|
||||
import dev.gould.lingo.client.view.PlayerBoard;
|
||||
import dev.gould.lingo.common.Game;
|
||||
import dev.gould.lingo.common.GameLeftMessage;
|
||||
import dev.gould.lingo.common.Report;
|
||||
|
||||
@Component
|
||||
public class MultiplayerPresenter implements FxmlController {
|
@ -1,11 +1,11 @@
|
||||
package com.charego.lingo.client.multiplayer;
|
||||
package dev.gould.lingo.client.multiplayer;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.PreDestroy;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.PreDestroy;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
@ -1,8 +1,8 @@
|
||||
package com.charego.lingo.client.singleplayer;
|
||||
package dev.gould.lingo.client.singleplayer;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.charego.lingo.client.bootstrap.WordRepository;
|
||||
import dev.gould.lingo.client.bootstrap.WordRepository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -21,10 +21,10 @@ import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.scene.text.TextAlignment;
|
||||
import com.charego.lingo.client.view.PlayerBoard;
|
||||
import com.charego.lingo.common.Game;
|
||||
import com.charego.lingo.common.Player;
|
||||
import com.charego.lingo.common.Report;
|
||||
import dev.gould.lingo.client.view.PlayerBoard;
|
||||
import dev.gould.lingo.common.Game;
|
||||
import dev.gould.lingo.common.Player;
|
||||
import dev.gould.lingo.common.Report;
|
||||
|
||||
public class SinglePlayerPresenter {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.util;
|
||||
package dev.gould.lingo.client.util;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.view;
|
||||
package dev.gould.lingo.client.view;
|
||||
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.view;
|
||||
package dev.gould.lingo.client.view;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.view;
|
||||
package dev.gould.lingo.client.view;
|
||||
|
||||
import javafx.scene.canvas.Canvas;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.client.view;
|
||||
package dev.gould.lingo.client.view;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
@ -1,7 +1,7 @@
|
||||
module com.charego.lingo.client {
|
||||
requires com.charego.lingo.common;
|
||||
requires com.charego.lingo.api;
|
||||
requires java.annotation;
|
||||
module dev.gould.lingo.client {
|
||||
requires dev.gould.lingo.common;
|
||||
requires dev.gould.lingo.api;
|
||||
requires jakarta.annotation;
|
||||
requires javafx.controls;
|
||||
requires javafx.fxml;
|
||||
requires javafx.graphics;
|
||||
@ -15,8 +15,8 @@ module com.charego.lingo.client {
|
||||
requires spring.messaging;
|
||||
requires spring.web;
|
||||
requires spring.websocket;
|
||||
exports com.charego.lingo.client.bootstrap;
|
||||
exports com.charego.lingo.client.multiplayer;
|
||||
opens com.charego.lingo.client.bootstrap to javafx.fxml, spring.core;
|
||||
opens com.charego.lingo.client.multiplayer to javafx.fxml, spring.core;
|
||||
exports dev.gould.lingo.client.bootstrap;
|
||||
exports dev.gould.lingo.client.multiplayer;
|
||||
opens dev.gould.lingo.client.bootstrap to javafx.fxml, spring.core;
|
||||
opens dev.gould.lingo.client.multiplayer to javafx.fxml, spring.core;
|
||||
}
|
||||
|
@ -1,2 +1,2 @@
|
||||
# https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
|
||||
logging.level.com.charego.lingo = DEBUG
|
||||
logging.level.dev.gould.lingo = DEBUG
|
||||
|
@ -8,7 +8,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<BorderPane xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="com.charego.lingo.client.bootstrap.LingoPresenter"
|
||||
fx:controller="dev.gould.lingo.client.bootstrap.LingoPresenter"
|
||||
fx:id="content"
|
||||
prefWidth="650"
|
||||
prefHeight="420">
|
||||
|
@ -8,7 +8,7 @@
|
||||
<?import javafx.scene.web.WebView?>
|
||||
|
||||
<StackPane xmlns:fx="http://javafx.com/fxml"
|
||||
fx:controller="com.charego.lingo.client.multiplayer.MultiplayerPresenter"
|
||||
fx:controller="dev.gould.lingo.client.multiplayer.MultiplayerPresenter"
|
||||
fx:id="contentPane">
|
||||
|
||||
<children>
|
||||
|
@ -3,8 +3,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.charego</groupId>
|
||||
<artifactId>lingo-parent</artifactId>
|
||||
<groupId>dev.gould</groupId>
|
||||
<artifactId>lingo</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
public class ChatMessage {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
public class GameLeftMessage {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
public class Report {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
public class SetUsernameMessage {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.common;
|
||||
package dev.gould.lingo.common;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
@ -1,4 +1,4 @@
|
||||
module com.charego.lingo.common {
|
||||
module dev.gould.lingo.common {
|
||||
requires com.fasterxml.jackson.annotation;
|
||||
exports com.charego.lingo.common;
|
||||
exports dev.gould.lingo.common;
|
||||
}
|
||||
|
8
pom.xml
8
pom.xml
@ -5,11 +5,11 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.0.RELEASE</version>
|
||||
<version>3.0.0</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.charego</groupId>
|
||||
<artifactId>lingo-parent</artifactId>
|
||||
<groupId>dev.gould</groupId>
|
||||
<artifactId>lingo</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>11</java.version>
|
||||
<java.version>19</java.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
|
@ -3,8 +3,8 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.charego</groupId>
|
||||
<artifactId>lingo-parent</artifactId>
|
||||
<groupId>dev.gould</groupId>
|
||||
<artifactId>lingo</artifactId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
|
||||
@ -17,56 +17,46 @@
|
||||
<version>${project.version}</version>
|
||||
<artifactId>lingo-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Web -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Development Tools -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<!-- Prevent transitive application to other modules -->
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>lingo</finalName>
|
||||
<plugins>
|
||||
<!-- Repackage as executable JAR (java -jar) -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<!-- Enable hot refreshing of resources -->
|
||||
<!-- Add src/main/resources to the classpath -->
|
||||
<!-- Remove duplicate resources from target/classes -->
|
||||
<addResources>true</addResources>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<image>
|
||||
<name>docker.io/charego/lingo</name>
|
||||
</image>
|
||||
</configuration>
|
||||
<executions>
|
||||
<!-- Repackage as executable JAR (java -jar) -->
|
||||
<execution>
|
||||
<id>repackage</id>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- How to build image directly to Docker daemon: -->
|
||||
<!-- $ mvn jib:dockerBuild -->
|
||||
<!-- How to build image and publish to Docker registry: -->
|
||||
<!-- $ mvn jib:build -Djib.to.image=<myregistry>/<myimage>:latest -->
|
||||
<!-- $ mvn jib:build -->
|
||||
<plugin>
|
||||
<groupId>com.google.cloud.tools</groupId>
|
||||
<artifactId>jib-maven-plugin</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<version>3.3.1</version>
|
||||
<configuration>
|
||||
<!-- Enable this setting to allow pushes to local Docker registry -->
|
||||
<!--<allowInsecureRegistries>true</allowInsecureRegistries>-->
|
||||
<from>
|
||||
<image>adoptopenjdk:11-jre-openj9</image>
|
||||
<image>eclipse-temurin:19-jre</image>
|
||||
</from>
|
||||
<to>
|
||||
<image>docker.io/charego/lingo</image>
|
||||
</to>
|
||||
<container>
|
||||
<mainClass>dev.gould.lingo.server.LingoServer</mainClass>
|
||||
<ports>
|
||||
<port>8080</port>
|
||||
</ports>
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import static org.springframework.messaging.simp.SimpMessageHeaderAccessor.SESSION_ID_HEADER;
|
||||
|
||||
@ -8,10 +8,10 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
import com.charego.lingo.api.Destinations;
|
||||
import com.charego.lingo.common.*;
|
||||
import dev.gould.lingo.api.Destinations;
|
||||
import dev.gould.lingo.common.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -30,21 +30,21 @@ public class LingoController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(LingoController.class);
|
||||
|
||||
@Autowired
|
||||
private SimpMessagingTemplate messagingTemplate;
|
||||
|
||||
@Autowired
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Autowired
|
||||
private WordRepository wordRepo;
|
||||
private final SimpMessagingTemplate messagingTemplate;
|
||||
private final SessionManager sessionManager;
|
||||
private final WordRepository wordRepo;
|
||||
|
||||
private final Map<Integer, Game> gameById = new TreeMap<>();
|
||||
|
||||
private final Map<Player, Game> gameByPlayer = new HashMap<>();
|
||||
|
||||
private final Set<String> usernames = new HashSet<>();
|
||||
|
||||
@Autowired
|
||||
public LingoController(SimpMessagingTemplate messagingTemplate, SessionManager sessionManager, WordRepository wordRepo) {
|
||||
this.messagingTemplate = messagingTemplate;
|
||||
this.sessionManager = sessionManager;
|
||||
this.wordRepo = wordRepo;
|
||||
}
|
||||
|
||||
@MessageMapping("/chat")
|
||||
public ChatMessage chat(String message, @Header(SESSION_ID_HEADER) String sessionId) {
|
||||
final Player player = sessionManager.getPlayer(sessionId);
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import static org.springframework.messaging.simp.SimpMessageHeaderAccessor.SESSION_ID_HEADER;
|
||||
|
||||
@ -16,27 +16,29 @@ import org.springframework.messaging.simp.SimpMessageType;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.charego.lingo.api.Destinations;
|
||||
import com.charego.lingo.common.Game;
|
||||
import com.charego.lingo.common.Player;
|
||||
import com.charego.lingo.common.Report;
|
||||
import dev.gould.lingo.api.Destinations;
|
||||
import dev.gould.lingo.common.Game;
|
||||
import dev.gould.lingo.common.Player;
|
||||
import dev.gould.lingo.common.Report;
|
||||
|
||||
@RestController
|
||||
public class PracticeController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PracticeController.class);
|
||||
|
||||
@Autowired
|
||||
private SimpMessagingTemplate messagingTemplate;
|
||||
|
||||
@Autowired
|
||||
private SessionManager sessionManager;
|
||||
|
||||
@Autowired
|
||||
private WordRepository wordRepo;
|
||||
private final SimpMessagingTemplate messagingTemplate;
|
||||
private final SessionManager sessionManager;
|
||||
private final WordRepository wordRepo;
|
||||
|
||||
private final Map<Player, Game> practiceByPlayer = new HashMap<>();
|
||||
|
||||
@Autowired
|
||||
public PracticeController(SimpMessagingTemplate messagingTemplate, SessionManager sessionManager, WordRepository wordRepo) {
|
||||
this.messagingTemplate = messagingTemplate;
|
||||
this.sessionManager = sessionManager;
|
||||
this.wordRepo = wordRepo;
|
||||
}
|
||||
|
||||
@MessageMapping("/practiceGame")
|
||||
public void practiceGame(@Header(SESSION_ID_HEADER) String sessionId) {
|
||||
final Player player = sessionManager.getPlayer(sessionId);
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -15,7 +15,7 @@ import org.springframework.web.socket.messaging.AbstractSubProtocolEvent;
|
||||
import org.springframework.web.socket.messaging.SessionConnectedEvent;
|
||||
import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
||||
|
||||
import com.charego.lingo.common.Player;
|
||||
import dev.gould.lingo.common.Player;
|
||||
|
||||
@Component
|
||||
public class SessionManager implements ApplicationListener<AbstractSubProtocolEvent> {
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.simp.config.ChannelRegistration;
|
@ -1,4 +1,4 @@
|
||||
package com.charego.lingo.server;
|
||||
package dev.gould.lingo.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@ -10,9 +10,9 @@ import java.util.Set;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.charego.lingo.common.WordReader;
|
||||
import dev.gould.lingo.common.WordReader;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@Component
|
||||
public class WordRepository {
|
@ -1,7 +1,7 @@
|
||||
module com.charego.lingo.server {
|
||||
requires com.charego.lingo.common;
|
||||
requires com.charego.lingo.api;
|
||||
requires java.annotation;
|
||||
module dev.gould.lingo.server {
|
||||
requires dev.gould.lingo.common;
|
||||
requires dev.gould.lingo.api;
|
||||
requires jakarta.annotation;
|
||||
requires org.slf4j;
|
||||
requires spring.beans;
|
||||
requires spring.boot;
|
||||
|
@ -1,2 +1,2 @@
|
||||
# https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html
|
||||
logging.level.com.charego.lingo = DEBUG
|
||||
logging.level.dev.gould.lingo = DEBUG
|
||||
|
@ -7,24 +7,25 @@ const MARGIN_BOTTOM = 75;
|
||||
let client = null;
|
||||
let sessionId = null;
|
||||
|
||||
const vm = new Vue({
|
||||
el: '#vue-app',
|
||||
data: {
|
||||
players: [],
|
||||
games: [],
|
||||
messages: [],
|
||||
username: null,
|
||||
usernameError: '',
|
||||
myGame: null,
|
||||
myScore: 0,
|
||||
myGuess: '',
|
||||
myGuesses: [],
|
||||
myProgress: [],
|
||||
myResults: [],
|
||||
opponentScore: 0,
|
||||
opponentResults: [],
|
||||
opponentUsername: null,
|
||||
lastWord: null
|
||||
const app = Vue.createApp({
|
||||
data() {
|
||||
return {
|
||||
players: [],
|
||||
games: [],
|
||||
messages: [],
|
||||
username: null,
|
||||
usernameError: '',
|
||||
myGame: null,
|
||||
myScore: 0,
|
||||
myGuess: '',
|
||||
myGuesses: [],
|
||||
myProgress: [],
|
||||
myResults: [],
|
||||
opponentScore: 0,
|
||||
opponentResults: [],
|
||||
opponentUsername: null,
|
||||
lastWord: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inGame: function() {
|
||||
@ -275,11 +276,8 @@ const vm = new Vue({
|
||||
this.opponentScore = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
document.getElementById('nicknameInput').focus();
|
||||
}
|
||||
});
|
||||
}).mount('#app');
|
||||
|
||||
function afterConnected(stompConnectedFrame) {
|
||||
console.log('Connected to STOMP endpoint')
|
||||
@ -316,7 +314,7 @@ function main() {
|
||||
|
||||
// Will be invoked in case of error encountered at broker.
|
||||
// Bad login/passcode typically will cause an error.
|
||||
// Complaint brokers will set `message` header with a brief message. Body may contain details.
|
||||
// Compliant brokers will set `message` header with a brief message. Body may contain details.
|
||||
// Compliant brokers will terminate the connection after any error.
|
||||
client.onStompError = function(frame) {
|
||||
console.log('Broker reported error: ' + frame.headers['message']);
|
||||
@ -347,10 +345,10 @@ function main() {
|
||||
const response = JSON.parse(message.body);
|
||||
if (response.success === true) {
|
||||
console.log('Username: ' + response.username);
|
||||
vm.username = response.username;
|
||||
app.username = response.username;
|
||||
start();
|
||||
} else {
|
||||
vm.usernameError = response.errorMessage;
|
||||
app.usernameError = response.errorMessage;
|
||||
}
|
||||
};
|
||||
|
||||
@ -358,12 +356,12 @@ function main() {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if (sessionId === null) {
|
||||
vm.usernameError = 'Not connected to server';
|
||||
app.usernameError = 'Not connected to server';
|
||||
return;
|
||||
}
|
||||
const usernameValue = usernameInput.value.trim();
|
||||
if (usernameValue.length === 0) {
|
||||
vm.usernameError = 'Name cannot be empty';
|
||||
app.usernameError = 'Name cannot be empty';
|
||||
return;
|
||||
}
|
||||
if (usernameSubscription === null) {
|
||||
@ -379,7 +377,7 @@ function main() {
|
||||
}
|
||||
const usernameValue = usernameInput.value.trim();
|
||||
if (usernameValue.length !== 0) {
|
||||
vm.usernameError = '';
|
||||
app.usernameError = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -409,7 +407,7 @@ function start() {
|
||||
const games = data.games;
|
||||
for (let i = 0; i < games.length; i++) {
|
||||
const game = games[i];
|
||||
vm.games.push({
|
||||
app.games.push({
|
||||
id: game.id,
|
||||
playerOne: game.playerOne.username,
|
||||
playerTwo: game.playerTwo ? game.playerTwo.username : null,
|
||||
@ -419,7 +417,7 @@ function start() {
|
||||
}
|
||||
for (let i = 0; i < players.length; i++) {
|
||||
const player = players[i];
|
||||
vm.players.push({
|
||||
app.players.push({
|
||||
username: player.username
|
||||
});
|
||||
}
|
||||
@ -438,14 +436,14 @@ function start() {
|
||||
}
|
||||
|
||||
function addChatAnnouncement(body) {
|
||||
vm.messages.push({
|
||||
app.messages.push({
|
||||
body: body
|
||||
});
|
||||
showNotification('Announcement', body);
|
||||
}
|
||||
|
||||
function addChatMessage(sender, body) {
|
||||
vm.messages.push({
|
||||
app.messages.push({
|
||||
sender: sender,
|
||||
body: body
|
||||
});
|
||||
@ -474,7 +472,7 @@ function onChat(message) {
|
||||
const messageBody = chatMessage.message;
|
||||
if (messageSender === null) {
|
||||
addChatAnnouncement(messageBody);
|
||||
} else if (messageSender === vm.username) {
|
||||
} else if (messageSender === app.username) {
|
||||
// Ignore messages sent by yourself
|
||||
} else {
|
||||
console.log('Message from ' + messageSender + ': ' + messageBody);
|
||||
@ -487,10 +485,10 @@ function onGameClosed(message) {
|
||||
const gameId = game.id;
|
||||
const playerOne = game.playerOne.username;
|
||||
console.log(playerOne + ' closed Game ' + gameId);
|
||||
if (playerOne === vm.username) {
|
||||
vm.myGame = null;
|
||||
if (playerOne === app.username) {
|
||||
app.myGame = null;
|
||||
}
|
||||
vm.removeGame(gameId);
|
||||
app.removeGame(gameId);
|
||||
}
|
||||
|
||||
function onGameHosted(message) {
|
||||
@ -505,9 +503,9 @@ function onGameHosted(message) {
|
||||
wordLength: wordLength,
|
||||
started: false
|
||||
};
|
||||
vm.games.push(vueGame);
|
||||
if (playerOne === vm.username) {
|
||||
vm.myGame = vueGame;
|
||||
app.games.push(vueGame);
|
||||
if (playerOne === app.username) {
|
||||
app.myGame = vueGame;
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,18 +519,18 @@ function onGameJoined(message) {
|
||||
console.log(playerTwo + ' joined ' + playerOne + "'s game");
|
||||
|
||||
let vueGame = null;
|
||||
for (let i = 0; i < vm.games.length; i++) {
|
||||
if (vm.games[i].id === gameId) {
|
||||
vm.games[i].playerTwo = playerTwo;
|
||||
vm.games[i].wordLength = wordLength;
|
||||
vm.games[i].started = true;
|
||||
vueGame = vm.games[i];
|
||||
for (let i = 0; i < app.games.length; i++) {
|
||||
if (app.games[i].id === gameId) {
|
||||
app.games[i].playerTwo = playerTwo;
|
||||
app.games[i].wordLength = wordLength;
|
||||
app.games[i].started = true;
|
||||
vueGame = app.games[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (playerTwo === vm.username) {
|
||||
vm.myGame = vueGame;
|
||||
if (playerTwo === app.username) {
|
||||
app.myGame = vueGame;
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,33 +542,33 @@ function onGameLeft(message) {
|
||||
const gameLeaver = report.gameLeaver.username;
|
||||
console.log(gameLeaver + ' left ' + playerOne + "'s game");
|
||||
const previousPlayers = [];
|
||||
for (let i = 0; i < vm.games.length; i++) {
|
||||
if (vm.games[i].id === gameId) {
|
||||
previousPlayers.push(vm.games[i].playerOne);
|
||||
previousPlayers.push(vm.games[i].playerTwo);
|
||||
vm.games[i].playerOne = playerOne;
|
||||
vm.games[i].playerTwo = game.playerTwo ? game.playerTwo.username : null;
|
||||
vm.games[i].started = false;
|
||||
for (let i = 0; i < app.games.length; i++) {
|
||||
if (app.games[i].id === gameId) {
|
||||
previousPlayers.push(app.games[i].playerOne);
|
||||
previousPlayers.push(app.games[i].playerTwo);
|
||||
app.games[i].playerOne = playerOne;
|
||||
app.games[i].playerTwo = game.playerTwo ? game.playerTwo.username : null;
|
||||
app.games[i].started = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gameLeaver === vm.username) {
|
||||
vm.myGame = null;
|
||||
if (gameLeaver === app.username) {
|
||||
app.myGame = null;
|
||||
}
|
||||
if (previousPlayers.indexOf(vm.username) !== -1) {
|
||||
vm.opponentUsername = null;
|
||||
vm.lastWord = null;
|
||||
vm.repaint();
|
||||
if (previousPlayers.indexOf(app.username) !== -1) {
|
||||
app.opponentUsername = null;
|
||||
app.lastWord = null;
|
||||
app.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
function onOpponentJoined(message) {
|
||||
const report = JSON.parse(message.body);
|
||||
const firstLetter = report[0];
|
||||
vm.opponentUsername = report[1];
|
||||
console.log('Opponent username: ' + vm.opponentUsername);
|
||||
vm.reset(firstLetter, true);
|
||||
vm.repaint();
|
||||
app.opponentUsername = report[1];
|
||||
console.log('Opponent username: ' + app.opponentUsername);
|
||||
app.reset(firstLetter, true);
|
||||
app.repaint();
|
||||
}
|
||||
|
||||
function onOpponentReport(message) {
|
||||
@ -579,14 +577,14 @@ function onOpponentReport(message) {
|
||||
if (report.correct === true) {
|
||||
const guess = report.guess;
|
||||
const firstLetter = report.firstLetter;
|
||||
vm.opponentScore = vm.opponentScore + 100;
|
||||
vm.lastWord = guess;
|
||||
vm.reset(firstLetter, false);
|
||||
vm.repaint();
|
||||
app.opponentScore = app.opponentScore + 100;
|
||||
app.lastWord = guess;
|
||||
app.reset(firstLetter, false);
|
||||
app.repaint();
|
||||
} else {
|
||||
const result = report.result;
|
||||
vm.opponentResults.push(result);
|
||||
vm.repaint();
|
||||
app.opponentResults.push(result);
|
||||
app.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,26 +594,26 @@ function onPlayerReport(message) {
|
||||
if (report.correct === true) {
|
||||
const guess = report.guess;
|
||||
const firstLetter = report.firstLetter;
|
||||
vm.myScore = vm.myScore + 100;
|
||||
vm.lastWord = guess;
|
||||
vm.reset(firstLetter, false);
|
||||
vm.repaint();
|
||||
app.myScore = app.myScore + 100;
|
||||
app.lastWord = guess;
|
||||
app.reset(firstLetter, false);
|
||||
app.repaint();
|
||||
} else {
|
||||
const guess = report.guess;
|
||||
const result = report.result;
|
||||
if (result[0] === 9) {
|
||||
const invalidGuess = '-'.repeat(vm.wordLength);
|
||||
vm.myGuesses.push(invalidGuess);
|
||||
const invalidGuess = '-'.repeat(app.wordLength);
|
||||
app.myGuesses.push(invalidGuess);
|
||||
} else {
|
||||
for (let i = 0; i < vm.wordLength; i++) {
|
||||
for (let i = 0; i < app.wordLength; i++) {
|
||||
if (result[i] === 2) {
|
||||
vm.myProgress[i] = guess[i];
|
||||
app.myProgress[i] = guess[i];
|
||||
}
|
||||
}
|
||||
vm.myGuesses.push(guess);
|
||||
app.myGuesses.push(guess);
|
||||
}
|
||||
vm.myResults.push(result);
|
||||
vm.repaint();
|
||||
app.myResults.push(result);
|
||||
app.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,7 +621,7 @@ function onPlayerJoined(message) {
|
||||
const report = JSON.parse(message.body);
|
||||
const username = report[0];
|
||||
const numUsers = report[1];
|
||||
if (username === vm.username) {
|
||||
if (username === app.username) {
|
||||
addChatAnnouncement('Welcome to Lingo!');
|
||||
if (numUsers === 1) {
|
||||
addChatAnnouncement('You are the only player online');
|
||||
@ -632,7 +630,7 @@ function onPlayerJoined(message) {
|
||||
}
|
||||
} else {
|
||||
addChatAnnouncement(username + ' joined');
|
||||
vm.players.push({
|
||||
app.players.push({
|
||||
username: username
|
||||
});
|
||||
}
|
||||
@ -641,7 +639,7 @@ function onPlayerJoined(message) {
|
||||
function onPlayerLeft(message) {
|
||||
const username = message.body;
|
||||
addChatAnnouncement(username + ' left');
|
||||
vm.removePlayer(username);
|
||||
app.removePlayer(username);
|
||||
}
|
||||
|
||||
function canShowNotification() {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 318 B |
76
server/src/main/resources/static/favicon.svg
Normal file
76
server/src/main/resources/static/favicon.svg
Normal file
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:version="1.0 (4035a4f, 2020-05-01)"
|
||||
sodipodi:docname="logo.svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 64 64"
|
||||
height="64mm"
|
||||
width="64mm">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="23"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-height="791"
|
||||
inkscape:window-width="1252"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:cy="291.42857"
|
||||
inkscape:cx="297.14282"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-13.607147,-35.529762)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<circle
|
||||
r="32"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:export-xdpi="96"
|
||||
cy="67.529762"
|
||||
cx="45.607147"
|
||||
id="path16"
|
||||
style="fill:#000000;stroke-width:0.260465" />
|
||||
<text
|
||||
transform="scale(1.0355499,0.96567047)"
|
||||
id="text30"
|
||||
y="87.83168"
|
||||
x="22.764704"
|
||||
style="font-style:normal;font-weight:normal;font-size:52.1622px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.271678"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:52.1622px;fill:#ffffff;stroke-width:0.271678"
|
||||
y="87.83168"
|
||||
x="22.764704"
|
||||
id="tspan28"
|
||||
sodipodi:role="line">G</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -3,19 +3,20 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Lingo</title>
|
||||
<link rel="icon" href="favicon.svg" sizes="any" type="image/svg+xml">
|
||||
<link rel="stylesheet" href="layout.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="//cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/@stomp/stompjs@5.4.4/bundles/stomp.umd.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/vue@3.0.7/dist/vue.global.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/@stomp/stompjs@6.1.0/bundles/stomp.umd.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="vue-app" v-cloak>
|
||||
<div id="app" v-cloak>
|
||||
<div class="main column">
|
||||
<div class="header row">Lingo</div>
|
||||
<div class="body row nofooter">
|
||||
<div v-show="!username" class="form">
|
||||
<h2>What is your name?</h2>
|
||||
<input id="nicknameInput" type="text" class="form-control" maxlength="16">
|
||||
<input id="nicknameInput" type="text" class="form-control" maxlength="16" v-bind:autofocus="'autofocus'">
|
||||
<p class="error-message">{{ usernameError }}</p>
|
||||
</div>
|
||||
<div v-show="username">
|
||||
|
@ -11,7 +11,7 @@
|
||||
<button id="skipButton" type="button">Skip Word</button>
|
||||
</div>
|
||||
|
||||
<script src="//cdn.jsdelivr.net/npm/@stomp/stompjs@5.2.0/bundles/stomp.umd.min.js"></script>
|
||||
<script src="//cdn.jsdelivr.net/npm/@stomp/stompjs@6.0.0/bundles/stomp.umd.min.js"></script>
|
||||
<script src="practice.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,6 +1,6 @@
|
||||
const HEIGHT = 300;
|
||||
const WIDTH = 250;
|
||||
const SIDE = 50;
|
||||
const CHARACTER_HEIGHT = 50;
|
||||
const MARGIN_TOP = 50;
|
||||
const MARGIN_BOTTOM = 25;
|
||||
|
||||
@ -122,11 +122,11 @@ function drawScore(x, y, score) {
|
||||
|
||||
function drawGrid(xOrigin, yOrigin) {
|
||||
ctx.beginPath();
|
||||
for (let x = 0; x <= WIDTH; x += SIDE) {
|
||||
for (let x = 0; x <= WIDTH; x += CHARACTER_HEIGHT) {
|
||||
ctx.moveTo(xOrigin + x, yOrigin);
|
||||
ctx.lineTo(xOrigin + x, yOrigin + HEIGHT);
|
||||
}
|
||||
for (let y = 0; y <= HEIGHT; y += SIDE) {
|
||||
for (let y = 0; y <= HEIGHT; y += CHARACTER_HEIGHT) {
|
||||
ctx.moveTo(xOrigin, yOrigin + y);
|
||||
ctx.lineTo(xOrigin + WIDTH, yOrigin + y);
|
||||
}
|
||||
@ -136,43 +136,43 @@ function drawGrid(xOrigin, yOrigin) {
|
||||
|
||||
function drawInput(xOrigin, yOrigin, input) {
|
||||
ctx.fillStyle = 'green';
|
||||
let x = xOrigin + SIDE * 0.5;
|
||||
const y = yOrigin + SIDE * 0.5;
|
||||
let x = xOrigin + CHARACTER_HEIGHT * 0.5;
|
||||
const y = yOrigin + CHARACTER_HEIGHT * 0.5;
|
||||
for (let i = 0; i < myGuess.length; i++) {
|
||||
ctx.fillText(myGuess[i], x, y);
|
||||
x += SIDE;
|
||||
x += CHARACTER_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
function drawGuesses(xOrigin, yOrigin, guesses, results) {
|
||||
let y = yOrigin + SIDE * 1.5;
|
||||
let y = yOrigin + CHARACTER_HEIGHT * 1.5;
|
||||
const numGuesses = Math.min(4, guesses.length);
|
||||
for (let i = 0; i < numGuesses; i++) {
|
||||
let x = xOrigin + SIDE * 0.5;
|
||||
let x = xOrigin + CHARACTER_HEIGHT * 0.5;
|
||||
const guess = guesses[guesses.length - numGuesses + i];
|
||||
const result = results[results.length - numGuesses + i];
|
||||
for (let j = 0; j < 5; j++) {
|
||||
if (result[j] === 1) {
|
||||
ctx.fillStyle = 'yellow';
|
||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||
ctx.fillRect(x - CHARACTER_HEIGHT * 0.5, y - CHARACTER_HEIGHT * 0.5, CHARACTER_HEIGHT, CHARACTER_HEIGHT);
|
||||
} else if (result[j] === 2) {
|
||||
ctx.fillStyle = 'orange';
|
||||
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
|
||||
ctx.fillRect(x - CHARACTER_HEIGHT * 0.5, y - CHARACTER_HEIGHT * 0.5, CHARACTER_HEIGHT, CHARACTER_HEIGHT);
|
||||
}
|
||||
ctx.fillStyle = 'green';
|
||||
ctx.fillText(guess[j], x, y);
|
||||
x += SIDE;
|
||||
x += CHARACTER_HEIGHT;
|
||||
}
|
||||
y += SIDE;
|
||||
y += CHARACTER_HEIGHT;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
function drawHint(xOrigin, yOrigin, progress) {
|
||||
let x = xOrigin + SIDE * 0.5;
|
||||
let x = xOrigin + CHARACTER_HEIGHT * 0.5;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
ctx.fillText(progress[i], x, yOrigin);
|
||||
x += SIDE;
|
||||
x += CHARACTER_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
java.runtime.version=11
|
||||
java.runtime.version=17
|
||||
|
Loading…
x
Reference in New Issue
Block a user