From 0d504ef2c80143b69097a83292774e6dcd71c620 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Tue, 7 Nov 2023 20:59:03 +0000 Subject: [PATCH 01/20] [minor] Bump version to 0.3.0-SNAPSHOT --- CHANGELOG.md | 7 ++++++- src/version/version.py | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7079c73..df22bce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `0.0.x` : End-to-end Flask PoC - `0.1.x` : GitHub Actions - `0.2.x` : Simple Tic Tac Toe (3 x 3) +- `0.3.x` : Implement ultimate edition (9 x 9)
# Releases +## [0.3.0] - ??? +- UMA-17: Give the user the option of standard or ultimate tic tac toe + ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns - UMA-12: Display results to each player when the game is over @@ -47,4 +51,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [0.1.1]: https://github.com/jrsmth/ultima/compare/0.1.0...0.1.1 [0.1.2]: https://github.com/jrsmth/ultima/compare/0.1.1...0.1.2 [0.2.0]: https://github.com/jrsmth/ultima/compare/0.1.2...0.2.0 -[0.2.1]: https://github.com/jrsmth/ultima/compare/0.2.0...0.2.1 \ No newline at end of file +[0.2.1]: https://github.com/jrsmth/ultima/compare/0.2.0...0.2.1 +[0.3.0]: https://github.com/jrsmth/ultima/compare/0.2.1...0.3.0 \ No newline at end of file diff --git a/src/version/version.py b/src/version/version.py index 44401cd..f178641 100644 --- a/src/version/version.py +++ b/src/version/version.py @@ -1 +1 @@ -__version__ = "0.2.2-SNAPSHOT" \ No newline at end of file +__version__ = "0.3.0-SNAPSHOT" \ No newline at end of file From 353d4c9b6a1275ba6e7e2d762c9addc540dc23a7 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Tue, 7 Nov 2023 22:08:49 +0000 Subject: [PATCH 02/20] [patch] UMA-17: template structural changes --- CHANGELOG.md | 2 +- src/app/game/game.py | 12 +++++----- src/resources/messages.properties | 14 ++++-------- src/resources/static/styles/css/game.css | 20 ++++++++++++++--- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/scss/game.scss | 19 +++++++++++++--- src/resources/static/styles/scss/spacing.scss | 4 +++- src/resources/templates/game.html | 22 ++++++++++++------- 8 files changed, 63 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df22bce..f590fa6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.0] - ??? -- UMA-17: Give the user the option of standard or ultimate tic tac toe +- UMA-17: Give the user the option of standard or ultimate tic-tac-toe ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns diff --git a/src/app/game/game.py b/src/app/game/game.py index a3cd2e8..2880f97 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -38,30 +38,30 @@ def game(game_id, user_id): if game_state == Status.DRAW: notification_header = messages.load("game.end.draw.header") notification_message = messages.load("game.end.draw.1.message") - notification_icon = messages.load("game.end.draw.1.icon") + notification_icon = messages.load("game.end.draw.icon") elif game_state == Status.PLAYER_ONE_WINS: if redis.get("player1") == user_id: notification_header = messages.load_with_params("game.end.win.header", [redis.get("player1")]) + notification_icon = messages.load("game.end.win.icon") notification_message = messages.load("game.end.win.1.message") - notification_icon = messages.load("game.end.win.1.icon") notification_mood = Mood.HAPPY.value else: notification_header = messages.load_with_params("game.end.lose.header", [redis.get("player2")]) + notification_icon = messages.load("game.end.lose.icon") notification_message = messages.load("game.end.lose.3.message") - notification_icon = messages.load("game.end.lose.3.icon") notification_mood = Mood.SAD.value elif game_state == Status.PLAYER_TWO_WINS: if redis.get("player2") == user_id: notification_header = messages.load_with_params("game.end.win.header", [redis.get("player2")]) + notification_icon = messages.load("game.end.win.icon") notification_message = messages.load("game.end.win.3.message") - notification_icon = messages.load("game.end.win.3.icon") notification_mood = Mood.HAPPY.value else: notification_header = messages.load_with_params("game.end.lose.header", [redis.get("player1")]) + notification_icon = messages.load("game.end.lose.icon") notification_message = messages.load("game.end.lose.1.message") - notification_icon = messages.load("game.end.lose.1.icon") notification_mood = Mood.SAD.value return render_template( @@ -131,6 +131,8 @@ def get_game_state(redis): if list(board.values()).count("0") == 0: return Status.DRAW + # FixMe :: this check needs to happen after test each player has won... + # Note :: There is probs a clean way to split this up so that you don't iterate when not nec... print("count: " + str(list(board.values()).count("1"))) if (list(board.values()).count("1")) >= 3: diff --git a/src/resources/messages.properties b/src/resources/messages.properties index c36c8d4..eebc901 100644 --- a/src/resources/messages.properties +++ b/src/resources/messages.properties @@ -5,25 +5,19 @@ login.error.invalid-game-id=Invalid Game ID: Please try again or leave blank to ## Game game.end.draw.header=Draw -game.end.draw.1.icon=fa-solid fa-face-relieved +game.end.draw.icon=fa-solid fa-face-surprise game.end.draw.1.message=Phew, what a battle! -game.end.draw.2.icon=fa-solid fa-face-rolling-eyes -game.end.draw.2.message=Well that was waste of time... -game.end.draw.3.icon= fa-solid fa-face-meh-blank +game.end.draw.2.message=Well that was good use of time... game.end.draw.3.message=When you win, say nothing. When you lose, say less game.end.win.header=Congratulations, {0}! -game.end.win.1.icon=fa-solid fa-face-smile-wink +game.end.win.icon=fa-solid fa-face-smile game.end.win.1.message=Winning isn't everything, it's the only thing -game.end.win.2.icon=fa-solid fa-face-smile game.end.win.2.message=Life shrinks or expands in proportion to one's courage -game.end.win.3.icon=fa-solid fa-face-smile-beam game.end.win.3.message=Winning isn't everything, but wanting it is game.end.lose.header=Commiserations, {0} -game.end.lose.1.icon=fa-solid fa-face-dizzy +game.end.lose.icon=fa-solid fa-face-dizzy game.end.lose.1.message=Doubt kills more dreams than failure ever will -game.end.lose.2.icon=fa-solid fa-face-grimace game.end.lose.2.message=Fight to avoid defeat, a surefire losing strategy -game.end.lose.3.icon=fa-solid fa-face-sad-cry game.end.lose.3.message=Accept finite disappointment, never lose infinite hope \ No newline at end of file diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 5d23497..86a8294 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -16,6 +16,7 @@ body { /** Header */ header { display: flex; + margin: 0.75rem 0.5rem; } header #badge { height: 2.25rem; @@ -56,6 +57,12 @@ header h1 { width: 70%; text-align: center; } +#content .main-bar #whose-turn { + height: 5.125rem; +} +#content .main-bar #whose-turn.inactive-True { + display: none; +} #content .main-bar #whose-turn .symbol-active-True { display: block; } @@ -91,13 +98,13 @@ header h1 { /** Side Bar */ .side-bar { - margin-top: 6rem; + margin-top: 6.5rem; width: 15%; } .side-bar .player { margin: 1rem; padding: 1rem; - width: 10rem; + width: 12rem; } .side-bar .player.active { border: 1px solid rgba(231, 4, 83, 0.2509803922); @@ -207,7 +214,7 @@ header h1 { /** Notification */ .notification { - margin: 2rem auto 0 auto; + margin: 0 auto; border: 1px solid rgba(231, 4, 83, 0.2509803922); border-radius: 0.5rem; background-color: #2b0710; @@ -217,6 +224,13 @@ header h1 { align-items: center; text-align: left; } +.notification.error { + margin: 2rem 1rem 0 1rem; + width: 14rem; +} +.notification.error .notification-content { + margin: 1rem; +} .notification.active-True { display: flex; } diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index f3059d3..31dbf6b 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCTO;EDUP,OCKW;EDJX;;;AEbF;AACA;EACE;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD9BS;;ACiCX;EACE;EACA;;AAGE;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODpDd;;ACqDL;EAAmB,OD3DpB;;AC6DC;EACE;;AAMF;EAAkB,ODpEnB;;ACqEC;EAAkB,OD/Db;;ACiEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDhGM;;ACmGR;EACE;EACA;EACA,kBDtGM;;ACyGR;EACE;EACA,ODtGC;;ACyGH;EACE,OD1GC;EC2GD;EACA;EACA;;AAGF;EAA6B,OD1GpB;;AC2GT;EAA6B,ODjH1B;;ACkHH;EAA6B,ODlH1B;;ACmHH;EAA6B,OD7GpB;;;ACiHb;AACA;EACE;EACA,QChImB;EDiInB;EACA,YCpIe;EDqIf,YCpIe;EDqIf;EACA;;AAEA;EACE;EACA;EACA,kBDzIQ;EC0IR;;AAEA;EACE;EACA;EACA;EACA,kBDhJM;ECiJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDhKK;ECiKL;;AAEA;EACE,OD/KE;;ACoLR;EACE;;AAEA;EACE;EACA,kBDpLD;ECqLC;;AAEA;EACE,OD7LE;;ACmMqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBD7MU;EC8MV;EACA,OCjNe;EDkNf;EACA;EACA;;AAEA;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD7NS;EC8NT;EACA,kBD9NW;;ACgOX;EACE,OD7NO;;ACiOT;EACE,OD7OC;EC8OD;EACA,kBDpPM;;ACsPN;EACE,ODnPI;;ACsPN;EACE,OD3OK","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCTO;EDUP,OCKW;EDJX;;;AEbF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD/BS;;ACkCX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODxDd;;ACyDL;EAAmB,OD/DpB;;ACiEC;EACE;;AAMF;EAAkB,ODxEnB;;ACyEC;EAAkB,ODnEb;;ACqEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,OD1GC;;AC6GH;EACE,OD9GC;EC+GD;EACA;EACA;;AAGF;EAA6B,OD9GpB;;AC+GT;EAA6B,ODrH1B;;ACsHH;EAA6B,ODtH1B;;ACuHH;EAA6B,ODjHpB;;;ACqHb;AACA;EACE;EACA,QCpImB;EDqInB;EACA,YCxIe;EDyIf,YCxIe;EDyIf;EACA;;AAEA;EACE;EACA;EACA,kBD7IQ;EC8IR;;AAEA;EACE;EACA;EACA;EACA,kBDpJM;ECqJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpKK;ECqKL;;AAEA;EACE,ODnLE;;ACwLR;EACE;;AAEA;EACE;EACA,kBDxLD;ECyLC;;AAEA;EACE,ODjME;;ACuMqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDjNU;ECkNV;EACA,OCrNe;EDsNf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD1OS;EC2OT;EACA,kBD3OW;;AC6OX;EACE,OD1OO;;AC8OT;EACE,OD1PC;EC2PD;EACA,kBDjQM;;ACmQN;EACE,ODhQI;;ACmQN;EACE,ODxPK","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 28c229a..10cc1de 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -3,6 +3,7 @@ /** Header */ header { display: flex; + margin: .75rem .5rem; #badge { height: 2.25rem; @@ -50,6 +51,9 @@ header { text-align: center; #whose-turn { + height: 5.125rem; + &.inactive-True { display: none; } + .symbol-active-True { display: block; } .symbol-active-False { display: none; } @@ -87,13 +91,13 @@ header { /** Side Bar */ .side-bar { - margin-top: 6rem; + margin-top: 6.5rem; width: 15%; .player { margin: 1rem; padding: 1rem; - width: 10rem; + width: 12rem; &.active { border: 1px solid $pink25; @@ -203,7 +207,7 @@ header { /** Notification */ .notification { - margin: 2rem auto 0 auto; + margin: 0 auto; border: 1px solid $pink25; border-radius: .5rem; background-color: $aubergine; @@ -213,6 +217,15 @@ header { align-items: center; text-align: left; + &.error { + margin: 2rem 1rem 0 1rem; + width: 14rem; + + .notification-content { + margin: 1rem; + } + } + &.active-True { display: flex } &.active-False { display: none } diff --git a/src/resources/static/styles/scss/spacing.scss b/src/resources/static/styles/scss/spacing.scss index 571da3e..5ea4804 100644 --- a/src/resources/static/styles/scss/spacing.scss +++ b/src/resources/static/styles/scss/spacing.scss @@ -1,3 +1,5 @@ $boardLengthMax: 600px; $boardLengthMin: 400px; -$boardLengthDefault: 50%; // of main #content height \ No newline at end of file +$boardLengthDefault: 50%; // of main #content height + +$lhs_menu_item_width: 14rem; \ No newline at end of file diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index a0fe9e8..7f33a3b 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -33,9 +33,22 @@

Ultima

{{ player2 }} +
+
+

Invalid Move

+

Play in the highlighted square

+
+
-
+
+ +
+

{{ notificationHeader }}

+

{{ notificationMessage }}

+
+
+
@@ -56,13 +69,6 @@

Ultima

{{ seven }}
{{ eight }}
-
- -
-

{{ notificationHeader }}

-

{{ notificationMessage }}

-
-
From 058994cde23684f99d7b03a31021b4d43d1fa2ef Mon Sep 17 00:00:00 2001 From: jrsmth Date: Tue, 7 Nov 2023 22:14:48 +0000 Subject: [PATCH 03/20] [patch] UMA-17: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 327c95f..d1f3bfb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![python](https://img.shields.io/badge/Python-3.9-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) [![test-and-release](https://github.com/jrsmth/ultima/actions/workflows/main.yaml/badge.svg)](https://github.com/jrsmth/ultima/actions/workflows/main.yaml) -# Logo Ultima +# Logo ULTIMA [ultima.jrsmth.io](https://ultima.jrsmth.io) From 8829e50b8faa0d76b22ba302c0def89367c96c84 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Tue, 7 Nov 2023 22:15:24 +0000 Subject: [PATCH 04/20] [patch] UMA-17: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d1f3bfb..41e648f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![python](https://img.shields.io/badge/Python-3.9-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) [![test-and-release](https://github.com/jrsmth/ultima/actions/workflows/main.yaml/badge.svg)](https://github.com/jrsmth/ultima/actions/workflows/main.yaml) -# Logo ULTIMA +# Ultima [ultima.jrsmth.io](https://ultima.jrsmth.io) From 2bf6ed0b9422f88e0a4951e4a0b5b7f9da3983f1 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Tue, 7 Nov 2023 22:16:11 +0000 Subject: [PATCH 05/20] [patch] UMA-17: revert README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41e648f..327c95f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![python](https://img.shields.io/badge/Python-3.9-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) [![test-and-release](https://github.com/jrsmth/ultima/actions/workflows/main.yaml/badge.svg)](https://github.com/jrsmth/ultima/actions/workflows/main.yaml) -# Ultima +# Logo Ultima [ultima.jrsmth.io](https://ultima.jrsmth.io) From ff02e5e78df3cddd1c6a9eb6f7c4937c9acd7374 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 17:31:57 +0000 Subject: [PATCH 06/20] [patch] UMA-17: login styling update --- src/app/login/login.py | 2 + .../static/scripts/{index.js => game.js} | 0 src/resources/static/scripts/login.js | 9 ++ src/resources/static/styles/css/base.css.map | 2 +- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/css/login.css | 121 +++++++++++----- src/resources/static/styles/css/login.css.map | 2 +- src/resources/static/styles/scss/base.scss | 5 +- src/resources/static/styles/scss/colours.scss | 13 +- src/resources/static/styles/scss/game.scss | 42 +++--- src/resources/static/styles/scss/login.scss | 136 ++++++++++++------ src/resources/static/styles/scss/spacing.scss | 8 +- .../static/styles/scss/variables.scss | 4 + src/resources/templates/game.html | 2 +- src/resources/templates/login.html | 51 +++++-- 15 files changed, 277 insertions(+), 122 deletions(-) rename src/resources/static/scripts/{index.js => game.js} (100%) create mode 100644 src/resources/static/scripts/login.js create mode 100644 src/resources/static/styles/scss/variables.scss diff --git a/src/app/login/login.py b/src/app/login/login.py index be3e1fd..989e0c1 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -27,6 +27,8 @@ def login(): redis.set("7", board_list[7]) redis.set("8", board_list[8]) + redis.set("gameMode", request.form["gameMode"]) + # TODO :: set redis obj as dict { $game_id: [player1: "", player2: ""] } if request.form["gameId"] == "": redis.set("player1", request.form["name"]) diff --git a/src/resources/static/scripts/index.js b/src/resources/static/scripts/game.js similarity index 100% rename from src/resources/static/scripts/index.js rename to src/resources/static/scripts/game.js diff --git a/src/resources/static/scripts/login.js b/src/resources/static/scripts/login.js new file mode 100644 index 0000000..f46c02e --- /dev/null +++ b/src/resources/static/scripts/login.js @@ -0,0 +1,9 @@ +$(document).ready(function() { + $('.field > .selection').click(function() { + $(this).siblings().removeClass('selected'); + $(this).addClass('selected'); + + const gameMode = document.getElementById('game-mode'); + gameMode.value = document.getElementsByClassName('selected')[0].innerHTML.toUpperCase(); + }); +}); \ No newline at end of file diff --git a/src/resources/static/styles/css/base.css.map b/src/resources/static/styles/css/base.css.map index ac28d0d..2427080 100644 --- a/src/resources/static/styles/css/base.css.map +++ b/src/resources/static/styles/css/base.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCTO;EDUP,OCKW;EDJX","file":"base.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd","file":"base.css"} \ No newline at end of file diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index 31dbf6b..515a404 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCTO;EDUP,OCKW;EDJX;;;AEbF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD/BS;;ACkCX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODxDd;;ACyDL;EAAmB,OD/DpB;;ACiEC;EACE;;AAMF;EAAkB,ODxEnB;;ACyEC;EAAkB,ODnEb;;ACqEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,OD1GC;;AC6GH;EACE,OD9GC;EC+GD;EACA;EACA;;AAGF;EAA6B,OD9GpB;;AC+GT;EAA6B,ODrH1B;;ACsHH;EAA6B,ODtH1B;;ACuHH;EAA6B,ODjHpB;;;ACqHb;AACA;EACE;EACA,QCpImB;EDqInB;EACA,YCxIe;EDyIf,YCxIe;EDyIf;EACA;;AAEA;EACE;EACA;EACA,kBD7IQ;EC8IR;;AAEA;EACE;EACA;EACA;EACA,kBDpJM;ECqJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpKK;ECqKL;;AAEA;EACE,ODnLE;;ACwLR;EACE;;AAEA;EACE;EACA,kBDxLD;ECyLC;;AAEA;EACE,ODjME;;ACuMqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDjNU;ECkNV;EACA,OCrNe;EDsNf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD1OS;EC2OT;EACA,kBD3OW;;AC6OX;EACE,OD1OO;;AC8OT;EACE,OD1PC;EC2PD;EACA,kBDjQM;;ACmQN;EACE,ODhQI;;ACmQN;EACE,ODxPK","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EACE;EACA,QCpImB;EDqInB;EACA,YCxIe;EDyIf,YCxIe;EDyIf;EACA;;AAEA;EACE;EACA;EACA,kBD7IQ;EC8IR;;AAEA;EACE;EACA;EACA;EACA,kBDpJM;ECqJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDjKK;ECkKL;;AAEA;EACE,ODnLE;;ACwLR;EACE;;AAEA;EACE;EACA,kBDrLD;ECsLC;;AAEA;EACE,ODjME;;ACuMqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDjNU;ECkNV;EACA,OCrNe;EDsNf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODvOS;ECwOT;EACA,kBDxOW;;AC0OX;EACE,ODvOU;;AC2OZ;EACE,ODvPC;ECwPD;EACA,kBDjQM;;ACmQN;EACE,ODhQI;;ACmQN;EACE,ODrPQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/css/login.css b/src/resources/static/styles/css/login.css index cb57f34..85df58e 100644 --- a/src/resources/static/styles/css/login.css +++ b/src/resources/static/styles/css/login.css @@ -13,66 +13,115 @@ body { height: 100%; } -#logo { - width: 10rem; - position: absolute; - left: calc(50% - 5rem); - top: 15%; -} - section { position: absolute; - top: 45%; - width: 20rem; - left: calc(50% - 10rem); - background-color: #2b0710; - border: 1px solid rgba(231, 4, 83, 0.7490196078); + width: 40rem; + height: 20rem; + left: calc(50% - 20rem); + top: calc(50% - 20rem); + text-align: center; +} +section #logo { + width: 10rem; + margin-bottom: 2rem; +} +section form { + background: rgba(155, 14, 64, 0.2509803922); + color: #ccc; + box-shadow: 0px 13px 50px -13px rgba(0, 0, 0, 0.0980392157); + border: 1px solid rgba(155, 14, 64, 0.7490196078); border-radius: 0.5rem; + letter-spacing: 0.5px; + display: flex; + flex-direction: column; + text-align: left; +} +section form div { + box-sizing: border-box; +} +section form h3 { + font-size: 1rem; + font-weight: normal; + margin: 2px 0; + color: #eee; +} +section form p { + font-size: 0.75rem; + margin: 2px 0; + color: #ccc; +} +section form .form-control { display: flex; + height: 5rem; + padding: 2rem; + width: 100%; + align-items: center; +} +section form .form-control .field { + margin-left: auto; + display: flex; + height: 2rem; + align-items: center; justify-content: center; +} +section form .form-control .field .selection { + display: flex; align-items: center; + justify-content: center; + cursor: pointer; + height: 2.25rem; + width: 8.5rem; + margin-left: -1px; + background-clip: border-box; + transform: scale3d(1, 1, 1); + background-color: rgba(231, 4, 83, 0.2509803922); + color: #ccc; + transition: 0.15s ease-in-out background-color; } -section form { - padding: 1rem; - width: 80%; +section form .form-control .field .selection.selected { + background-color: rgba(231, 4, 83, 0.7490196078) !important; + color: whitesmoke !important; + z-index: 2; + cursor: text; +} +section form .form-control .field .selection:hover { + color: whitesmoke !important; + background-color: rgba(231, 4, 83, 0.7490196078); +} +section form .form-control.button { + display: flex; + justify-content: end; } section form input { - margin-bottom: 1.5rem; border: none; border-bottom: 1px solid rgba(231, 4, 83, 0.2509803922); background: none; line-height: 2rem; - color: white; + color: whitesmoke; outline: none; - width: 100%; + width: 16.875rem; + margin: auto; } -section form input ::placeholder { - color: white; +section form input::placeholder { + color: #ccc; } section form input:focus { border-bottom: 1px solid rgba(231, 4, 83, 0.7490196078); } section form button { - margin-bottom: 0.5rem; - width: 100%; + width: 8.5rem; + background-color: rgba(231, 4, 83, 0.2509803922); + border: none; + color: whitesmoke; + transition: 0.15s ease-in-out background-color; padding: 0.5rem; - border-radius: 0.5rem; cursor: pointer; - background-color: #e70453; - border: none; - -webkit-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.25); - -moz-box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.25); - box-shadow: 0 3px 6px 0 rgba(0, 0, 0, 0.25); - color: white; letter-spacing: 1px; + box-shadow: 0px 13px 50px -13px rgba(0, 0, 0, 0.0980392157); + height: 2.25rem; } - -#shadow-section { - top: 3px; - left: 3px; - z-index: -1; - width: 100%; - height: 100%; +section form button:hover { + background: rgba(231, 4, 83, 0.7490196078); } /*# sourceMappingURL=login.css.map */ diff --git a/src/resources/static/styles/css/login.css.map b/src/resources/static/styles/css/login.css.map index 8876e93..8b5f64a 100644 --- a/src/resources/static/styles/css/login.css.map +++ b/src/resources/static/styles/css/login.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss"],"names":[],"mappings":"AAGA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCTO;EDUP,OCKW;EDJX;;;AEbF;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA,kBDXU;ECYV;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA;EACA,kBD1CC;EC2CD;EACA;EACA;EACA;EACA;EACA;;;AAKN;EACE;EACA;EACA;EACA;EACA","file":"login.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDPO;ECQP,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAmB;EAAe,ODJ/B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD9DU;EC+DV;EACA;EACA;;AAEA;EACE,ODlEK;;ACqEP;EACE;;AAIJ;EACE;EACA,kBDxFG;ECyFH;EACA,ODhFU;ECiFV;EACA;EACA;EACA;EACA,YCxGQ;EDyGR;;AAEA;EACE,YDlGC","file":"login.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/base.scss b/src/resources/static/styles/scss/base.scss index 2947cb2..b3f9361 100644 --- a/src/resources/static/styles/scss/base.scss +++ b/src/resources/static/styles/scss/base.scss @@ -1,5 +1,4 @@ -@import "colours"; -@import "spacing"; +@import "variables"; * { font-family: Montserrat, sans-serif; @@ -12,6 +11,6 @@ html { body { background-color: $creole; - color: $text-light; + color: $text-lightest; height: 100%; } diff --git a/src/resources/static/styles/scss/colours.scss b/src/resources/static/styles/scss/colours.scss index 7c5fed2..582803e 100644 --- a/src/resources/static/styles/scss/colours.scss +++ b/src/resources/static/styles/scss/colours.scss @@ -6,9 +6,12 @@ $creole: #180405; // Pink $carnation: #ff2c63; -$pink: #e70453; -$pink25: #e7045340; // 25% alpha -$pink75: #e70453bf; // 75% alpha +$cherry: #9b0e40; +$cherry25: #9b0e4040; // 25% alpha +$cherry75: #9b0e40bf; // 25% alpha +$rose: #e70453; +$rose25: #e7045340; // 25% alpha +$rose75: #e70453bf; // 75% alpha // Green $verdun: #566505; @@ -17,4 +20,6 @@ $chartreuse05: #d8ff000d; // 5% alpha $chartreuse25: #d8ff0040; // 25% alpha // Text -$text-light: whitesmoke; \ No newline at end of file +$text-lightest: whitesmoke; +$text-lighter: #eee; +$text-light: #ccc \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 10cc1de..636a048 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -69,7 +69,7 @@ header { #whose-turn-cross { &.this-symbol-1 { color: $chartreuse; } - &.this-symbol-2 { color: $pink; } + &.this-symbol-2 { color: $rose; } .whose-turn-shadow { transform: translateX(-3.75rem); @@ -78,7 +78,7 @@ header { } #whose-turn-circle { - &.this-symbol-1 { color: $pink; } + &.this-symbol-1 { color: $rose; } &.this-symbol-2 { color: $chartreuse; } .whose-turn-shadow { @@ -100,31 +100,31 @@ header { width: 12rem; &.active { - border: 1px solid $pink25; + border: 1px solid $rose25; background-color: $aubergine; } &.active-True { - border: 1px solid $pink25; + border: 1px solid $rose25; border-radius: .25rem; background-color: $aubergine; } .fa-user { margin-right: .5rem; - color: $pink; + color: $rose; } .symbol { - color: $pink; + color: $rose; margin-left: .5rem; float: right; transform: translateY(1px); } &#player1 > .this-symbol-1 { color: $chartreuse } - &#player1 > .this-symbol-2 { color: $pink } - &#player2 > .this-symbol-1 { color: $pink } + &#player1 > .this-symbol-2 { color: $rose } + &#player2 > .this-symbol-1 { color: $rose } &#player2 > .this-symbol-2 { color: $chartreuse } } } @@ -141,14 +141,14 @@ header { .shadow-square { margin: .5rem; - border: 1px solid $pink25; + border: 1px solid $rose25; background-color: $aubergine; border-radius: .5rem; .square { border-radius: inherit; transform: translate(-0.25rem, -0.25rem); - border: 1px solid $pink25; + border: 1px solid $rose25; background-color: $aubergine; transition: .5s; cursor: pointer; @@ -186,11 +186,11 @@ header { } &.opponent-user { - border: 1px solid $pink; + border: 1px solid $rose; .square { - border: 1px solid $pink; - background-color: $pink; + border: 1px solid $rose; + background-color: $rose; cursor: default; .symbol { @@ -200,15 +200,15 @@ header { } } - &.this-user-1.player-1-False { .square { border: 1px solid $pink25; cursor: default; } } - &.this-user-2.player-2-False { .square { border: 1px solid $pink25; cursor: default; } } - &.game-complete-True { .square { border: 1px solid $pink25 !important; cursor: default !important; } } + &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } + &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } + &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Notification */ .notification { margin: 0 auto; - border: 1px solid $pink25; + border: 1px solid $rose25; border-radius: .5rem; background-color: $aubergine; height: 5rem; @@ -251,13 +251,13 @@ header { background-color: $chartreuse05; p { - color: $text-light; + color: $text-lightest; } } &.sad { - color: $pink; - border: 1px solid $pink25; + color: $rose; + border: 1px solid $rose25; background-color: $aubergine; h3 { @@ -265,7 +265,7 @@ header { } p { - color: $text-light; + color: $text-lightest; } } diff --git a/src/resources/static/styles/scss/login.scss b/src/resources/static/styles/scss/login.scss index fd6d674..591289b 100644 --- a/src/resources/static/styles/scss/login.scss +++ b/src/resources/static/styles/scss/login.scss @@ -1,68 +1,118 @@ @import "base"; -#logo { - width: 10rem; - position: absolute; - left: calc(50% - 5rem); - top: 15%; -} - section { position: absolute; - top: 45%; - width: 20rem; - left: calc(50% - 10rem); - background-color: $aubergine; - border: 1px solid $pink75; - border-radius: .5rem; - display: flex; - justify-content: center; - align-items: center; + width: $loginWidth; + height: $loginHeight; + left: calc(50% - ($loginWidth * .5)); + top: calc(50% - $loginHeight); + text-align: center; + + #logo { + width: 10rem; + margin-bottom: 2rem; + } form { - padding: 1rem; - width: 80%; + background: $cherry25; + color: $text-light; + box-shadow: $drop-shadow; + border: 1px solid $cherry75; + border-radius: .5rem; + letter-spacing: .5px; + display: flex; + flex-direction: column; + text-align: left; + + div { box-sizing: border-box; } + h3 { font-size: 1rem; font-weight: normal; margin: 2px 0; color: $text-lighter} + p { font-size: .75rem; margin: 2px 0; color: $text-light } + + .form-control { + display: flex; + height: $form-control-height + ($gutter * 1.5); + padding: $gutter; + width: 100%; + align-items: center; + + .field { + margin-left: auto; + display: flex; + height: $form-control-height; + align-items: center; + justify-content: center; + + .selection { + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + height: 2.25rem; + width: calc($field-width * .5); + margin-left: -1px; + background-clip: border-box; + transform: scale3d(1, 1, 1); + + background-color: $rose25; + color: $text-light; + transition: .15s ease-in-out background-color; + + &.selected { + background-color: $rose75 !important; + color: $text-lightest !important; + z-index: 2; + cursor: text; + } + + &:hover { + color: $text-lightest !important; + background-color: $rose75; + } + } + } + + &.button { + display: flex; + justify-content: end; + } + } input { - margin-bottom: 1.5rem; border: none; - border-bottom: 1px solid $pink25; + border-bottom: 1px solid $rose25; background: none; line-height: 2rem; - color: white; + color: $text-lightest; outline: none; - width: 100%; + width: 16.875rem; + margin: auto; - ::placeholder { - color: white; + &::placeholder { + color: $text-light; } &:focus { - border-bottom: 1px solid $pink75; + border-bottom: 1px solid $rose75; } } button { - margin-bottom: 0.5rem; - width: 100%; - padding: 0.5rem; - border-radius: 0.5rem; - cursor: pointer; - background-color: $pink; + width: calc($field-width * .5); + background-color: $rose25; border: none; - -webkit-box-shadow: 0 3px 6px 0 rgba(0,0,0,.25); - -moz-box-shadow: 0 3px 6px 0 rgba(0,0,0,.25); - box-shadow: 0 3px 6px 0 rgba(0,0,0,.25); - color: white; + color: $text-lightest; + transition: .15s ease-in-out background-color; + padding: .5rem; + cursor: pointer; letter-spacing: 1px; + box-shadow: $drop-shadow; + height: 2.25rem; + + &:hover { + background: $rose75; + } } + } -} - -#shadow-section { - top: 3px; - left: 3px; - z-index: -1; - width: 100%; - height: 100%; + } \ No newline at end of file diff --git a/src/resources/static/styles/scss/spacing.scss b/src/resources/static/styles/scss/spacing.scss index 5ea4804..c47d7a1 100644 --- a/src/resources/static/styles/scss/spacing.scss +++ b/src/resources/static/styles/scss/spacing.scss @@ -2,4 +2,10 @@ $boardLengthMax: 600px; $boardLengthMin: 400px; $boardLengthDefault: 50%; // of main #content height -$lhs_menu_item_width: 14rem; \ No newline at end of file +$loginWidth: 40rem; +$loginHeight: 20rem; +$lhs_menu_item_width: 14rem; + +$gutter: 2rem; +$form-control-height: 2rem; +$field-width: 17rem; \ No newline at end of file diff --git a/src/resources/static/styles/scss/variables.scss b/src/resources/static/styles/scss/variables.scss new file mode 100644 index 0000000..7a141dd --- /dev/null +++ b/src/resources/static/styles/scss/variables.scss @@ -0,0 +1,4 @@ +@import "colours"; +@import "spacing"; + +$drop-shadow: 0px 13px 50px -13px #00000019; \ No newline at end of file diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index 7f33a3b..b4661e9 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -73,6 +73,6 @@

{{ notificationHeader }}

- + diff --git a/src/resources/templates/login.html b/src/resources/templates/login.html index b244a9f..d22436f 100644 --- a/src/resources/templates/login.html +++ b/src/resources/templates/login.html @@ -7,19 +7,50 @@ -
+
- - -
- - {% if error %} -

Error: {{ error }}

- {% endif %} +
+
+

Player Name

+
+
+ +
+
+
+
+

Game ID

+

Leave blank to start a new game

+
+
+ +
+
+
+ +
+

Game Mode

+
+
+

Standard

+

Ultimate

+
+
+
+ +
- -
+ + From f1aef2b3d4cacf9c01645ceeac2d62b7edb462fb Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 17:39:52 +0000 Subject: [PATCH 07/20] [patch] UMA-17: Further login styling --- src/resources/static/styles/css/login.css | 11 ++++------- src/resources/static/styles/css/login.css.map | 2 +- src/resources/static/styles/scss/login.scss | 8 ++------ src/resources/static/styles/scss/spacing.scss | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/resources/static/styles/css/login.css b/src/resources/static/styles/css/login.css index 85df58e..7db472a 100644 --- a/src/resources/static/styles/css/login.css +++ b/src/resources/static/styles/css/login.css @@ -15,9 +15,9 @@ body { section { position: absolute; - width: 40rem; + width: 36rem; height: 20rem; - left: calc(50% - 20rem); + left: calc(50% - 18rem); top: calc(50% - 20rem); text-align: center; } @@ -26,7 +26,7 @@ section #logo { margin-bottom: 2rem; } section form { - background: rgba(155, 14, 64, 0.2509803922); + background: #2b0710; color: #ccc; box-shadow: 0px 13px 50px -13px rgba(0, 0, 0, 0.0980392157); border: 1px solid rgba(155, 14, 64, 0.7490196078); @@ -46,7 +46,7 @@ section form h3 { color: #eee; } section form p { - font-size: 0.75rem; + font-size: 0.7rem; margin: 2px 0; color: #ccc; } @@ -102,9 +102,6 @@ section form input { width: 16.875rem; margin: auto; } -section form input::placeholder { - color: #ccc; -} section form input:focus { border-bottom: 1px solid rgba(231, 4, 83, 0.7490196078); } diff --git a/src/resources/static/styles/css/login.css.map b/src/resources/static/styles/css/login.css.map index 8b5f64a..cce0789 100644 --- a/src/resources/static/styles/css/login.css.map +++ b/src/resources/static/styles/css/login.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDPO;ECQP,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAmB;EAAe,ODJ/B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD9DU;EC+DV;EACA;EACA;;AAEA;EACE,ODlEK;;ACqEP;EACE;;AAIJ;EACE;EACA,kBDxFG;ECyFH;EACA,ODhFU;ECiFV;EACA;EACA;EACA;EACA,YCxGQ;EDyGR;;AAEA;EACE,YDlGC","file":"login.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDbQ;ECcR,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAkB;EAAe,ODJ9B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD9DU;EC+DV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDpFG;ECqFH;EACA,OD5EU;EC6EV;EACA;EACA;EACA;EACA,YCpGQ;EDqGR;;AAEA;EACE,YD9FC","file":"login.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/login.scss b/src/resources/static/styles/scss/login.scss index 591289b..052d313 100644 --- a/src/resources/static/styles/scss/login.scss +++ b/src/resources/static/styles/scss/login.scss @@ -14,7 +14,7 @@ section { } form { - background: $cherry25; + background: $aubergine; color: $text-light; box-shadow: $drop-shadow; border: 1px solid $cherry75; @@ -26,7 +26,7 @@ section { div { box-sizing: border-box; } h3 { font-size: 1rem; font-weight: normal; margin: 2px 0; color: $text-lighter} - p { font-size: .75rem; margin: 2px 0; color: $text-light } + p { font-size: .7rem; margin: 2px 0; color: $text-light } .form-control { display: flex; @@ -87,10 +87,6 @@ section { width: 16.875rem; margin: auto; - &::placeholder { - color: $text-light; - } - &:focus { border-bottom: 1px solid $rose75; } diff --git a/src/resources/static/styles/scss/spacing.scss b/src/resources/static/styles/scss/spacing.scss index c47d7a1..75484be 100644 --- a/src/resources/static/styles/scss/spacing.scss +++ b/src/resources/static/styles/scss/spacing.scss @@ -2,7 +2,7 @@ $boardLengthMax: 600px; $boardLengthMin: 400px; $boardLengthDefault: 50%; // of main #content height -$loginWidth: 40rem; +$loginWidth: 36rem; $loginHeight: 20rem; $lhs_menu_item_width: 14rem; From 397311135dd3f5f0215485046027db23ce094e69 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 18:35:15 +0000 Subject: [PATCH 08/20] [patch] UMA-17: Prevent game mode choice if second player --- src/app/game/game.py | 1 + src/app/login/login.py | 7 ++++- src/resources/static/scripts/login.js | 26 ++++++++++++++-- src/resources/static/styles/css/game.css | 13 +++++++- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/css/login.css | 3 ++ src/resources/static/styles/css/login.css.map | 2 +- src/resources/static/styles/scss/game.scss | 6 +++- src/resources/static/styles/scss/login.scss | 4 +++ src/resources/templates/game.html | 30 +++++++++++-------- src/resources/templates/login.html | 8 +++-- 11 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index 2880f97..bec0b6c 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -77,6 +77,7 @@ def game(game_id, user_id): eight=redis.get("8"), gameComplete=game_complete, gameId=game_id, + gameMode=redis.get("gameMode"), notificationActive=notification_active, notificationHeader=notification_header, notificationMessage=notification_message, diff --git a/src/app/login/login.py b/src/app/login/login.py index 989e0c1..4579733 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -13,6 +13,7 @@ def login(): if request.method == "POST": print(request.form["name"]) # log me print(request.form["gameId"]) + print(request.form["gameMode"]) board = ThreeBoard() board_list = ThreeBoard.list(board) # first index is squareNo @@ -27,7 +28,11 @@ def login(): redis.set("7", board_list[7]) redis.set("8", board_list[8]) - redis.set("gameMode", request.form["gameMode"]) + game_mode = request.form["gameMode"] + if game_mode != "": + redis.set("gameMode", game_mode) + else: + print("Game Mode already set [" + redis.get("gameMode") + "]"); # TODO :: err handle # TODO :: set redis obj as dict { $game_id: [player1: "", player2: ""] } if request.form["gameId"] == "": diff --git a/src/resources/static/scripts/login.js b/src/resources/static/scripts/login.js index f46c02e..ca25e1d 100644 --- a/src/resources/static/scripts/login.js +++ b/src/resources/static/scripts/login.js @@ -1,9 +1,29 @@ $(document).ready(function() { + // Toggle radio selection $('.field > .selection').click(function() { $(this).siblings().removeClass('selected'); $(this).addClass('selected'); - const gameMode = document.getElementById('game-mode'); - gameMode.value = document.getElementsByClassName('selected')[0].innerHTML.toUpperCase(); + $('#game-mode')[0].value = $('.selected')[0].innerHTML.toUpperCase(); }); -}); \ No newline at end of file + + // Toggle game mode display + $('#game-id').on('input', function() { + const inputLength = $(this)[0].value.length; + + if (inputLength === 0) { + $('.form-control.radio').removeClass('hide'); + $('#game-mode')[0].value = "" + + console.log($('.field.radio > .selection')) + $('.field.radio > .selection').removeClass('selected'); + } + + if (inputLength > 0) { + $('.form-control.radio').addClass('hide'); + $('#game-mode')[0].value = "" + } + }); + +}); + diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 86a8294..c29308b 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -145,9 +145,20 @@ header h1 { aspect-ratio: 1/1; max-height: 600px; min-height: 400px; - display: grid; grid-template-columns: 33.3% 33.3% 33.3%; } +.board.threeboard.STANDARD { + display: grid; +} +.board.threeboard.ULTIMATE { + display: none; +} +.board.nineboard.STANDARD { + display: none; +} +.board.nineboard.ULTIMATE { + display: grid; +} .board .shadow-square { margin: 0.5rem; border: 1px solid rgba(231, 4, 83, 0.2509803922); diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index 515a404..b9fe1de 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EACE;EACA,QCpImB;EDqInB;EACA,YCxIe;EDyIf,YCxIe;EDyIf;EACA;;AAEA;EACE;EACA;EACA,kBD7IQ;EC8IR;;AAEA;EACE;EACA;EACA;EACA,kBDpJM;ECqJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDjKK;ECkKL;;AAEA;EACE,ODnLE;;ACwLR;EACE;;AAEA;EACE;EACA,kBDrLD;ECsLC;;AAEA;EACE,ODjME;;ACuMqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDjNU;ECkNV;EACA,OCrNe;EDsNf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODvOS;ECwOT;EACA,kBDxOW;;AC0OX;EACE,ODvOU;;AC2OZ;EACE,ODvPC;ECwPD;EACA,kBDjQM;;ACmQN;EACE,ODhQI;;ACmQN;EACE,ODrPQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASxB;EACE;EACA;EACA,kBDjJQ;ECkJR;;AAEA;EACE;EACA;EACA;EACA,kBDxJM;ECyJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDrKK;ECsKL;;AAEA;EACE,ODvLE;;AC4LR;EACE;;AAEA;EACE;EACA,kBDzLD;EC0LC;;AAEA;EACE,ODrME;;AC2MqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDrNU;ECsNV;EACA,OCzNe;ED0Nf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD3OS;EC4OT;EACA,kBD5OW;;AC8OX;EACE,OD3OU;;AC+OZ;EACE,OD3PC;EC4PD;EACA,kBDrQM;;ACuQN;EACE,ODpQI;;ACuQN;EACE,ODzPQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/css/login.css b/src/resources/static/styles/css/login.css index 7db472a..283ae5c 100644 --- a/src/resources/static/styles/css/login.css +++ b/src/resources/static/styles/css/login.css @@ -92,6 +92,9 @@ section form .form-control.button { display: flex; justify-content: end; } +section form .form-control.radio.hide { + display: none; +} section form input { border: none; border-bottom: 1px solid rgba(231, 4, 83, 0.2509803922); diff --git a/src/resources/static/styles/css/login.css.map b/src/resources/static/styles/css/login.css.map index cce0789..bc432dd 100644 --- a/src/resources/static/styles/css/login.css.map +++ b/src/resources/static/styles/css/login.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDbQ;ECcR,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAkB;EAAe,ODJ9B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD9DU;EC+DV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDpFG;ECqFH;EACA,OD5EU;EC6EV;EACA;EACA;EACA;EACA,YCpGQ;EDqGR;;AAEA;EACE,YD9FC","file":"login.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDbQ;ECcR,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAkB;EAAe,ODJ9B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,ODlEU;ECmEV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDxFG;ECyFH;EACA,ODhFU;ECiFV;EACA;EACA;EACA;EACA,YCxGQ;EDyGR;;AAEA;EACE,YDlGC","file":"login.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 636a048..7951c85 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -131,12 +131,16 @@ header { /** Board */ .board { + &.threeboard.STANDARD { display: grid; } + &.threeboard.ULTIMATE { display: none; } + &.nineboard.STANDARD { display: none; } + &.nineboard.ULTIMATE { display: grid; } + margin: 2rem auto 0 auto; height: $boardLengthDefault; aspect-ratio: 1 / 1; max-height: $boardLengthMax; min-height: $boardLengthMin; - display: grid; grid-template-columns: 33.3% 33.3% 33.3%; .shadow-square { diff --git a/src/resources/static/styles/scss/login.scss b/src/resources/static/styles/scss/login.scss index 052d313..0e0d300 100644 --- a/src/resources/static/styles/scss/login.scss +++ b/src/resources/static/styles/scss/login.scss @@ -75,6 +75,10 @@ section { display: flex; justify-content: end; } + + &.radio.hide { + display: none; + } } input { diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index b4661e9..66b2834 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -13,7 +13,8 @@ - + +
badge @@ -58,17 +59,22 @@

{{ notificationHeader }}

-
-
{{ zero }}
-
{{ one }}
-
{{ two }}
-
{{ three }}
-
{{ four }}
-
{{ five }}
-
{{ six }}
-
{{ seven }}
-
{{ eight }}
-
+
+
+
{{ zero }}
+
{{ one }}
+
{{ two }}
+
{{ three }}
+
{{ four }}
+
{{ five }}
+
{{ six }}
+
{{ seven }}
+
{{ eight }}
+
+
+

Nine Board (Ultimate)

+
+
diff --git a/src/resources/templates/login.html b/src/resources/templates/login.html index d22436f..6cbdfb9 100644 --- a/src/resources/templates/login.html +++ b/src/resources/templates/login.html @@ -29,14 +29,18 @@

Game ID

-
- +
+

Game Mode

From 17b83da3ea6590ce9e634bd704b3b1e825559473 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 18:39:01 +0000 Subject: [PATCH 09/20] [patch] UMA-18: prepare change log for ticket --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f590fa6..68136d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.0] - ??? - UMA-17: Give the user the option of standard or ultimate tic-tac-toe +- UMA-18: Create interactive 9x9 board and allow player to make a turn ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns From 356e0a37b198209a7d56512bd6416037d0d3dcbe Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 18:40:00 +0000 Subject: [PATCH 10/20] [patch] UMA-19: rename feature branch --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68136d1..379147c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.0] - ??? - UMA-17: Give the user the option of standard or ultimate tic-tac-toe -- UMA-18: Create interactive 9x9 board and allow player to make a turn +- UMA-19: Create interactive 9x9 board and allow player to make a turn ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns From 7310d43a1f325bfb5106df434a6d8784590ab5b4 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 21:17:52 +0000 Subject: [PATCH 11/20] [patch] UMA-19: initial nineboard setup --- src/resources/static/scripts/game.js | 8 +- src/resources/static/scripts/login.js | 1 - src/resources/static/styles/css/game.css | 4 + src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/scss/game.scss | 11 +- src/resources/templates/game.html | 119 +++++++++++++++++-- 6 files changed, 130 insertions(+), 15 deletions(-) diff --git a/src/resources/static/scripts/game.js b/src/resources/static/scripts/game.js index 1449064..5f6c574 100644 --- a/src/resources/static/scripts/game.js +++ b/src/resources/static/scripts/game.js @@ -6,7 +6,7 @@ function init() { thisSymbol = document.getElementById('this-user-symbol').value; for (let i = 0; i < 9; i++) { - const square = document.getElementById(`square-${i}`).getElementsByClassName("square")[0]; + const square = document.getElementById(`three-square-${i}`).getElementsByClassName("square")[0]; const state = square.innerHTML; if (state === thisSymbol) { square.parentElement.classList.add("this-user"); @@ -37,7 +37,7 @@ function placeMove(square) { if (userSymbol === '1' && playerTwoActive === 'True') return; if (userSymbol === '2' && playerOneActive === 'True') return; - if (document.getElementById(`square-${square}`).getElementsByClassName("square")[0].innerHTML !== '') { + if (document.getElementById(`three-square-${square}`).getElementsByClassName("square")[0].innerHTML !== '') { return; } @@ -45,4 +45,8 @@ function placeMove(square) { location.reload(); } +function placeMove(outerSquare, innerSquare) { + +} + init(); \ No newline at end of file diff --git a/src/resources/static/scripts/login.js b/src/resources/static/scripts/login.js index ca25e1d..d3175ca 100644 --- a/src/resources/static/scripts/login.js +++ b/src/resources/static/scripts/login.js @@ -15,7 +15,6 @@ $(document).ready(function() { $('.form-control.radio').removeClass('hide'); $('#game-mode')[0].value = "" - console.log($('.field.radio > .selection')) $('.field.radio > .selection').removeClass('selected'); } diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index c29308b..b741666 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -188,6 +188,10 @@ header h1 { position: absolute; margin-top: calc(47.5% - 2rem); } +.board .shadow-square .square.outer { + display: grid; + grid-template-columns: 33.3% 33.3% 33.3%; +} .board .shadow-square.this-user { border: 1px solid #d8ff00; } diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index b9fe1de..414cd04 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASxB;EACE;EACA;EACA,kBDjJQ;ECkJR;;AAEA;EACE;EACA;EACA;EACA,kBDxJM;ECyJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDrKK;ECsKL;;AAEA;EACE,ODvLE;;AC4LR;EACE;;AAEA;EACE;EACA,kBDzLD;EC0LC;;AAEA;EACE,ODrME;;AC2MqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDrNU;ECsNV;EACA,OCzNe;ED0Nf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD3OS;EC4OT;EACA,kBD5OW;;AC8OX;EACE,OD3OU;;AC+OZ;EACE,OD3PC;EC4PD;EACA,kBDrQM;;ACuQN;EACE,ODpQI;;ACuQN;EACE,ODzPQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASxB;EACE;EACA;EACA,kBDjJQ;ECkJR;;AAEA;EACE;EACA;EACA;EACA,kBDxJM;ECyJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD1KK;EC2KL;;AAEA;EACE,OD5LE;;ACiMR;EACE;;AAEA;EACE;EACA,kBD9LD;EC+LC;;AAEA;EACE,OD1ME;;ACiNqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBD3NU;EC4NV;EACA,OC/Ne;EDgOf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODjPS;ECkPT;EACA,kBDlPW;;ACoPX;EACE,ODjPU;;ACqPZ;EACE,ODjQC;ECkQD;EACA,kBD3QM;;AC6QN;EACE,OD1QI;;AC6QN;EACE,OD/PQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 7951c85..c726fa1 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -129,13 +129,16 @@ header { } } -/** Board */ +/** Board **/ .board { &.threeboard.STANDARD { display: grid; } &.threeboard.ULTIMATE { display: none; } &.nineboard.STANDARD { display: none; } &.nineboard.ULTIMATE { display: grid; } +} +/** Three Board */ +.threeboard { margin: 2rem auto 0 auto; height: $boardLengthDefault; aspect-ratio: 1 / 1; @@ -202,6 +205,7 @@ header { } } } + } &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } @@ -209,6 +213,11 @@ header { &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } +/** Nine Board */ +.nineboard { + +} + /** Notification */ .notification { margin: 0 auto; diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index 66b2834..674166b 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -61,18 +61,117 @@

{{ notificationHeader }}

-
{{ zero }}
-
{{ one }}
-
{{ two }}
-
{{ three }}
-
{{ four }}
-
{{ five }}
-
{{ six }}
-
{{ seven }}
-
{{ eight }}
+
{{ zero }}
+
{{ one }}
+
{{ two }}
+
{{ three }}
+
{{ four }}
+
{{ five }}
+
{{ six }}
+
{{ seven }}
+
{{ eight }}
+
-

Nine Board (Ultimate)

+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
+
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
0
+
From 7496cfd0306977a53f6a42e7b19566c4eed43c66 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Fri, 10 Nov 2023 22:39:35 +0000 Subject: [PATCH 12/20] [patch] UMA-19: nineboard place move progress --- src/app/game/game.py | 25 ++- src/app/login/login.py | 20 +- src/app/util/redis.py | 13 +- src/resources/static/scripts/game.js | 18 +- src/resources/static/styles/css/game.css | 101 +++++++-- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/css/login.css | 3 - src/resources/static/styles/css/login.css.map | 2 +- src/resources/static/styles/scss/game.scss | 85 +++++++- src/resources/static/styles/scss/login.scss | 3 - src/resources/templates/game.html | 192 +++++++++--------- 11 files changed, 316 insertions(+), 148 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index bec0b6c..c2e94dc 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -66,6 +66,7 @@ def game(game_id, user_id): return render_template( "game.html", + board=redis.get_complex("board"), zero=redis.get("0"), one=redis.get("1"), two=redis.get("2"), @@ -94,10 +95,12 @@ def game(game_id, user_id): ) @game_page.route("/game//place-move//") - def place_move(game_id, user_id, square): + def place_standard_move(game_id, user_id, square): # Set player's move symbol = redis.get(user_id) - redis.set(square, symbol) + board_list = redis.get_complex("board") + board_list[int(square)] = symbol + redis.set_complex("board", board_list) # Switch player turn if redis.get("whoseTurn") == 'player1': @@ -107,6 +110,24 @@ def place_move(game_id, user_id, square): return redirect(url_for("game_page.game", game_id=game_id, user_id=user_id)) + @game_page.route("/game//place-move///") + def place_ultimate_move(game_id, user_id, outer_square, inner_square): + # Set player's move + symbol = redis.get(user_id) + # redis.set(square, symbol) + + print(outer_square) + print(inner_square) + + # Switch player turn + if redis.get("whoseTurn") == 'player1': + redis.set("whoseTurn", "player2") + elif redis.get("whoseTurn") == 'player2': + redis.set("whoseTurn", "player1") + + return redirect(url_for("game_page.game", game_id=game_id, user_id=user_id)) + + # Closing return return game_page diff --git a/src/app/login/login.py b/src/app/login/login.py index 4579733..ae7434d 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -18,15 +18,16 @@ def login(): board_list = ThreeBoard.list(board) # first index is squareNo # second index is the state: 0 for empty, 1 for cross, 2 for circle - redis.set("0", board_list[0]) - redis.set("1", board_list[1]) - redis.set("2", board_list[2]) - redis.set("3", board_list[3]) - redis.set("4", board_list[4]) - redis.set("5", board_list[5]) - redis.set("6", board_list[6]) - redis.set("7", board_list[7]) - redis.set("8", board_list[8]) + # redis.set("0", board_list[0]) + # redis.set("1", board_list[1]) + # redis.set("2", board_list[2]) + # redis.set("3", board_list[3]) + # redis.set("4", board_list[4]) + # redis.set("5", board_list[5]) + # redis.set("6", board_list[6]) + # redis.set("7", board_list[7]) + # redis.set("8", board_list[8]) + redis.set_complex("board", board_list) game_mode = request.form["gameMode"] if game_mode != "": @@ -52,6 +53,7 @@ def login(): return render_template("login.html", error=error) + # Closing return return login_page diff --git a/src/app/util/redis.py b/src/app/util/redis.py index a166bac..8760620 100644 --- a/src/app/util/redis.py +++ b/src/app/util/redis.py @@ -1,4 +1,5 @@ from flask_redis import FlaskRedis +import json # Wrapper functionality for the Flask Redis Client @@ -13,4 +14,14 @@ def get(self, key): def set(self, key, value): return self.client.set(key, value) - # Sets a key-value element + # Set a key-value element + + def set_complex(self, key, complex_value): + json_value = json.dumps(complex_value) + return self.client.set(key, json_value) + # Set a complex key-value element by converting to json string + + def get_complex(self, key): + json_value = self.client.get(key).decode('utf-8') + return json.loads(json_value) + # Get a complex key-value element by converting from json string diff --git a/src/resources/static/scripts/game.js b/src/resources/static/scripts/game.js index 5f6c574..2eb0ff2 100644 --- a/src/resources/static/scripts/game.js +++ b/src/resources/static/scripts/game.js @@ -25,7 +25,7 @@ function init() { } -function placeMove(square) { +function placeStandardMove(square) { const gameId = "ab12-3cd4-e5f6-78gh"; const userSymbol = document.getElementById('this-user-symbol').value; @@ -46,7 +46,23 @@ function placeMove(square) { } function placeMove(outerSquare, innerSquare) { + const gameId = "ab12-3cd4-e5f6-78gh"; + + const userSymbol = document.getElementById('this-user-symbol').value; + const playerOneActive = document.getElementById('player-one-active').value; + const playerTwoActive = document.getElementById('player-two-active').value; + const gameComplete = document.getElementById('game-complete').value; + + if (gameComplete === 'True') return; + if (userSymbol === '1' && playerTwoActive === 'True') return; + if (userSymbol === '2' && playerOneActive === 'True') return; + if (document.getElementById(`nine-square-${outerSquare}-${innerSquare}`).getElementsByClassName("square")[0].innerHTML !== '') { + return; + } + + $.get(`/game/${gameId}/place-move/${thisUserId}/${outerSquare}/${innerSquare}`); + location.reload(); } init(); \ No newline at end of file diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index b741666..68b9669 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -138,7 +138,7 @@ header h1 { color: #d8ff00; } -/** Board */ +/** Board **/ .board { margin: 2rem auto 0 auto; height: 50%; @@ -159,13 +159,27 @@ header h1 { .board.nineboard.ULTIMATE { display: grid; } -.board .shadow-square { +.board.this-user-1.player-1-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.board.this-user-2.player-2-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.board.game-complete-True .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; + cursor: default !important; +} + +/** Three Board */ +.threeboard .shadow-square { margin: 0.5rem; border: 1px solid rgba(231, 4, 83, 0.2509803922); background-color: #2b0710; border-radius: 0.5rem; } -.board .shadow-square .square { +.threeboard .shadow-square .square { border-radius: inherit; transform: translate(-0.25rem, -0.25rem); border: 1px solid rgba(231, 4, 83, 0.2509803922); @@ -179,52 +193,97 @@ header h1 { height: 100%; width: 100%; } -.board .shadow-square .square:hover { +.threeboard .shadow-square .square:hover { opacity: 1; border: 1px solid #d8ff00; } -.board .shadow-square .square .symbol { +.threeboard .shadow-square .square .symbol { font-size: 4rem; position: absolute; margin-top: calc(47.5% - 2rem); } -.board .shadow-square .square.outer { - display: grid; - grid-template-columns: 33.3% 33.3% 33.3%; -} -.board .shadow-square.this-user { +.threeboard .shadow-square.this-user { border: 1px solid #d8ff00; } -.board .shadow-square.this-user .square { +.threeboard .shadow-square.this-user .square { border: 1px solid #d8ff00; background-color: #d8ff00; cursor: default; } -.board .shadow-square.this-user .square .symbol { +.threeboard .shadow-square.this-user .square .symbol { color: #2b0710; } -.board .shadow-square.opponent-user { +.threeboard .shadow-square.opponent-user { border: 1px solid #e70453; } -.board .shadow-square.opponent-user .square { +.threeboard .shadow-square.opponent-user .square { border: 1px solid #e70453; background-color: #e70453; cursor: default; } -.board .shadow-square.opponent-user .square .symbol { +.threeboard .shadow-square.opponent-user .square .symbol { color: #2b0710; } -.board.this-user-1.player-1-False .square { + +/** Nine Board */ +.nineboard .shadow-square.outer { + margin: 0.5rem; +} +.nineboard .shadow-square.outer .square { + display: grid; + grid-template-columns: 33.3% 33.33% 33.3%; + height: 100%; +} +.nineboard .shadow-square.inner { + margin: 0.375rem; border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; + background-color: #2b0710; + border-radius: 0.5rem; } -.board.this-user-2.player-2-False .square { +.nineboard .shadow-square.inner .square { + border-radius: inherit; + transform: translate(-0.25rem, -0.25rem); border: 1px solid rgba(231, 4, 83, 0.2509803922); + background-color: #2b0710; + transition: 0.5s; + cursor: pointer; + align-content: center; + justify-content: center; + display: flex; + flex-wrap: wrap; + height: 100%; + width: 100%; +} +.nineboard .shadow-square.inner .square:hover { + opacity: 1; + border: 1px solid #d8ff00; +} +.nineboard .shadow-square.inner .square .symbol { + font-size: 4rem; + position: absolute; + margin-top: calc(47.5% - 2rem); +} +.nineboard .shadow-square.inner.this-user { + border: 1px solid #d8ff00; +} +.nineboard .shadow-square.inner.this-user .square { + border: 1px solid #d8ff00; + background-color: #d8ff00; cursor: default; } -.board.game-complete-True .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; - cursor: default !important; +.nineboard .shadow-square.inner.this-user .square .symbol { + color: #2b0710; +} +.nineboard .shadow-square.inner.opponent-user { + border: 1px solid #e70453; +} +.nineboard .shadow-square.inner.opponent-user .square { + border: 1px solid #e70453; + background-color: #e70453; + cursor: default; +} +.nineboard .shadow-square.inner.opponent-user .square .symbol { + color: #2b0710; } /** Notification */ diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index 414cd04..a6ff189 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASxB;EACE;EACA;EACA,kBDjJQ;ECkJR;;AAEA;EACE;EACA;EACA;EACA,kBDxJM;ECyJN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD1KK;EC2KL;;AAEA;EACE,OD5LE;;ACiMR;EACE;;AAEA;EACE;EACA,kBD9LD;EC+LC;;AAEA;EACE,OD1ME;;ACiNqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBD3NU;EC4NV;EACA,OC/Ne;EDgOf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODjPS;ECkPT;EACA,kBDlPW;;ACoPX;EACE,ODjPU;;ACqPZ;EACE,ODjQC;ECkQD;EACA,kBD3QM;;AC6QN;EACE,OD1QI;;AC6QN;EACE,OD/PQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASO;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AAEE;EACE;EACA;EACA,kBDxJQ;ECyJR;;AAEA;EACE;EACA;EACA;EACA,kBD/JM;ECgKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD5KK;EC6KL;;AAEA;EACE,OD9LE;;ACmMR;EACE;;AAEA;EACE;EACA,kBDhMD;ECiMC;;AAEA;EACE,OD5ME;;;ACoNZ;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBDnOQ;ECoOR;;AAEA;EACE;EACA;EACA;EACA,kBD1OM;EC2ON;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDvPK;ECwPL;;AAEA;EACE,ODzQE;;AC8QR;EACE;;AAEA;EACE;EACA,kBD3QD;EC4QC;;AAEA;EACE,ODvRE;;;ACgSZ;AACA;EACE;EACA;EACA;EACA,kBDrSU;ECsSV;EACA,OCzSe;ED0Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD3TS;EC4TT;EACA,kBD5TW;;AC8TX;EACE,OD3TU;;AC+TZ;EACE,OD3UC;EC4UD;EACA,kBDrVM;;ACuVN;EACE,ODpVI;;ACuVN;EACE,ODzUQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/css/login.css b/src/resources/static/styles/css/login.css index 283ae5c..3834e2b 100644 --- a/src/resources/static/styles/css/login.css +++ b/src/resources/static/styles/css/login.css @@ -26,11 +26,8 @@ section #logo { margin-bottom: 2rem; } section form { - background: #2b0710; color: #ccc; box-shadow: 0px 13px 50px -13px rgba(0, 0, 0, 0.0980392157); - border: 1px solid rgba(155, 14, 64, 0.7490196078); - border-radius: 0.5rem; letter-spacing: 0.5px; display: flex; flex-direction: column; diff --git a/src/resources/static/styles/css/login.css.map b/src/resources/static/styles/css/login.css.map index bc432dd..d65a82c 100644 --- a/src/resources/static/styles/css/login.css.map +++ b/src/resources/static/styles/css/login.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,YDbQ;ECcR,ODOS;ECNT,YCfU;EDgBV;EACA;EACA;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODJhD;;ACKX;EAAM;EAAkB;EAAe,ODJ9B;;ACMT;EACE;EACA;EACA,SEzBG;EF0BH;EACA;;AAEA;EACE;EACA;EACA,QE/Bc;EFgCd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBD3CD;EC4CC,ODhCG;ECiCH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDvDH;;AC4DH;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,ODlEU;ECmEV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDxFG;ECyFH;EACA,ODhFU;ECiFV;EACA;EACA;EACA;EACA,YCxGQ;EDyGR;;AAEA;EACE,YDlGC","file":"login.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,ODQS;ECPT,YCdU;EDeV;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODDhD;;ACEX;EAAM;EAAkB;EAAe,ODD9B;;ACGT;EACE;EACA;EACA,SEtBG;EFuBH;EACA;;AAEA;EACE;EACA;EACA,QE5Bc;EF6Bd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBDxCD;ECyCC,OD7BG;EC8BH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDpDH;;ACyDH;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD/DU;ECgEV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDrFG;ECsFH;EACA,OD7EU;EC8EV;EACA;EACA;EACA;EACA,YCrGQ;EDsGR;;AAEA;EACE,YD/FC","file":"login.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index c726fa1..cf0d44f 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -135,10 +135,7 @@ header { &.threeboard.ULTIMATE { display: none; } &.nineboard.STANDARD { display: none; } &.nineboard.ULTIMATE { display: grid; } -} -/** Three Board */ -.threeboard { margin: 2rem auto 0 auto; height: $boardLengthDefault; aspect-ratio: 1 / 1; @@ -146,6 +143,13 @@ header { min-height: $boardLengthMin; grid-template-columns: 33.3% 33.3% 33.3%; + &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } + &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } + &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } +} + +/** Three Board */ +.threeboard { .shadow-square { margin: .5rem; border: 1px solid $rose25; @@ -207,14 +211,81 @@ header { } } - - &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } - &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } - &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Nine Board */ .nineboard { + .shadow-square.outer { + margin: .5rem; + + .square { + display: grid; + grid-template-columns: 33.3% 33.33% 33.3%; + height: 100%; + } + } + + .shadow-square.inner { + margin: .375rem; + border: 1px solid $rose25; + background-color: $aubergine; + border-radius: .5rem; + + .square { + border-radius: inherit; + transform: translate(-0.25rem, -0.25rem); + border: 1px solid $rose25; + background-color: $aubergine; + transition: .5s; + cursor: pointer; + align-content: center; + justify-content: center; + display: flex; + flex-wrap: wrap; + height: 100%; + width: 100%; + + &:hover { + opacity: 1; + border: 1px solid $chartreuse; + } + + .symbol { + font-size: 4rem; + position: absolute; + margin-top: calc(47.5% - 2rem); + } + } + + &.this-user { + border: 1px solid $chartreuse; + + .square { + border: 1px solid $chartreuse; + background-color: $chartreuse; + cursor: default; + + .symbol { + color: $aubergine; + } + } + } + + &.opponent-user { + border: 1px solid $rose; + + .square { + border: 1px solid $rose; + background-color: $rose; + cursor: default; + + .symbol { + color: $aubergine; + } + } + } + + } } diff --git a/src/resources/static/styles/scss/login.scss b/src/resources/static/styles/scss/login.scss index 0e0d300..b390d07 100644 --- a/src/resources/static/styles/scss/login.scss +++ b/src/resources/static/styles/scss/login.scss @@ -14,11 +14,8 @@ section { } form { - background: $aubergine; color: $text-light; box-shadow: $drop-shadow; - border: 1px solid $cherry75; - border-radius: .5rem; letter-spacing: .5px; display: flex; flex-direction: column; diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index 674166b..eb32389 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -61,116 +61,110 @@

{{ notificationHeader }}

-
{{ zero }}
-
{{ one }}
-
{{ two }}
-
{{ three }}
-
{{ four }}
-
{{ five }}
-
{{ six }}
-
{{ seven }}
-
{{ eight }}
+ {% for square in board %} +
{{ square }}
+ {% endfor %}
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
-
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
-
0
+
+
+
+
+
+
+
+
+
+
From b017ef2a95795f42b65a0a99267cc6fae1804d11 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 06:48:30 +0000 Subject: [PATCH 13/20] [patch] UMA-19: board refactoring --- src/app/game/game.py | 23 +++++++------ src/app/login/login.py | 31 ++++++++--------- src/app/model/board/nineboard.py | 4 ++- src/app/util/redis.py | 9 +++-- src/resources/static/styles/css/game.css | 36 +++++++++++++------- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/scss/game.scss | 13 +++---- 7 files changed, 70 insertions(+), 48 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index c2e94dc..f3ce788 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -99,7 +99,7 @@ def place_standard_move(game_id, user_id, square): # Set player's move symbol = redis.get(user_id) board_list = redis.get_complex("board") - board_list[int(square)] = symbol + board_list[int(square)] = int(symbol) redis.set_complex("board", board_list) # Switch player turn @@ -132,11 +132,13 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): def get_game_state(redis): - board = { - "0": redis.get("0"), "1": redis.get("1"), "2": redis.get("2"), - "3": redis.get("3"), "4": redis.get("4"), "5": redis.get("5"), - "6": redis.get("6"), "7": redis.get("7"), "8": redis.get("8"), - } + # board = { + # "0": redis.get("0"), "1": redis.get("1"), "2": redis.get("2"), + # "3": redis.get("3"), "4": redis.get("4"), "5": redis.get("5"), + # "6": redis.get("6"), "7": redis.get("7"), "8": redis.get("8"), + # } + + board = redis.get_complex("board") winning_combos = [ [0, 1, 2], @@ -151,13 +153,13 @@ def get_game_state(redis): print(board) - if list(board.values()).count("0") == 0: + if board.count(0) == 0: return Status.DRAW # FixMe :: this check needs to happen after test each player has won... # Note :: There is probs a clean way to split this up so that you don't iterate when not nec... - print("count: " + str(list(board.values()).count("1"))) - if (list(board.values()).count("1")) >= 3: + print("count: " + str(board.count(1))) + if (board.count(1)) >= 3: player_moves = get_player_moves("1", board) print(player_moves) for combo in winning_combos: @@ -165,7 +167,7 @@ def get_game_state(redis): if set(combo).issubset(set(player_moves)): return Status.PLAYER_ONE_WINS - if (list(board.values()).count("2")) >= 3: + if (board.count(2)) >= 3: player_moves = get_player_moves("2", board) for combo in winning_combos: if set(combo).issubset(set(player_moves)): @@ -175,4 +177,5 @@ def get_game_state(redis): def get_player_moves(player, board): + # FixMe :: check board structure and update below when a user has had 3 or more moves return [int(k) for k, v in board.items() if v == player] diff --git a/src/app/login/login.py b/src/app/login/login.py index ae7434d..6023ef8 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -1,5 +1,6 @@ from flask import redirect, url_for, render_template, Blueprint, request +from src.app.model.board.nineboard import NineBoard from src.app.model.board.threeboard import ThreeBoard @@ -14,26 +15,24 @@ def login(): print(request.form["name"]) # log me print(request.form["gameId"]) print(request.form["gameMode"]) - board = ThreeBoard() - board_list = ThreeBoard.list(board) - # first index is squareNo - # second index is the state: 0 for empty, 1 for cross, 2 for circle - # redis.set("0", board_list[0]) - # redis.set("1", board_list[1]) - # redis.set("2", board_list[2]) - # redis.set("3", board_list[3]) - # redis.set("4", board_list[4]) - # redis.set("5", board_list[5]) - # redis.set("6", board_list[6]) - # redis.set("7", board_list[7]) - # redis.set("8", board_list[8]) - redis.set_complex("board", board_list) game_mode = request.form["gameMode"] - if game_mode != "": + if game_mode == "STANDARD": redis.set("gameMode", game_mode) + board = ThreeBoard() + board_list = ThreeBoard.list(board) + # second index is the state: 0 for empty, 1 for cross, 2 for circle + redis.set_complex("board", board_list) + + elif game_mode == "ULTIMATE": + redis.set("gameMode", game_mode) + board = NineBoard() + board_list = NineBoard.list(board) + # second index is the state: 0 for empty, 1 for cross, 2 for circle + redis.set_complex("board", board_list) + else: - print("Game Mode already set [" + redis.get("gameMode") + "]"); # TODO :: err handle + print("Game Mode already set [" + redis.get("gameMode") + "]") # TODO :: err handle # TODO :: set redis obj as dict { $game_id: [player1: "", player2: ""] } if request.form["gameId"] == "": diff --git a/src/app/model/board/nineboard.py b/src/app/model/board/nineboard.py index 7c6412b..5070171 100644 --- a/src/app/model/board/nineboard.py +++ b/src/app/model/board/nineboard.py @@ -14,4 +14,6 @@ class NineBoard(Board): bot_rhs = ThreeBoard() def list(self): - return + return [self.top_lhs, self.top_mid, self.top_rhs, + self.mid_lhs, self.mid_mid, self.mid_rhs, + self.bot_lhs, self.bot_mid, self.bot_rhs] diff --git a/src/app/util/redis.py b/src/app/util/redis.py index 8760620..7f41dda 100644 --- a/src/app/util/redis.py +++ b/src/app/util/redis.py @@ -1,5 +1,5 @@ -from flask_redis import FlaskRedis import json +from flask_redis import FlaskRedis # Wrapper functionality for the Flask Redis Client @@ -17,7 +17,12 @@ def set(self, key, value): # Set a key-value element def set_complex(self, key, complex_value): - json_value = json.dumps(complex_value) + json_value = json.dumps( + complex_value, + default=lambda o: o.__dict__, + sort_keys=True, + indent=4 + ) return self.client.set(key, json_value) # Set a complex key-value element by converting to json string diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 68b9669..3182139 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -159,18 +159,6 @@ header h1 { .board.nineboard.ULTIMATE { display: grid; } -.board.this-user-1.player-1-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.board.this-user-2.player-2-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.board.game-complete-True .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; - cursor: default !important; -} /** Three Board */ .threeboard .shadow-square { @@ -224,6 +212,18 @@ header h1 { .threeboard .shadow-square.opponent-user .square .symbol { color: #2b0710; } +.threeboard.this-user-1.player-1-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.threeboard.this-user-2.player-2-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.threeboard.game-complete-True .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; + cursor: default !important; +} /** Nine Board */ .nineboard .shadow-square.outer { @@ -285,6 +285,18 @@ header h1 { .nineboard .shadow-square.inner.opponent-user .square .symbol { color: #2b0710; } +.nineboard.this-user-1.player-1-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.nineboard.this-user-2.player-2-False .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922); + cursor: default; +} +.nineboard.game-complete-True .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; + cursor: default !important; +} /** Notification */ .notification { diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index a6ff189..b616299 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AASO;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AAEE;EACE;EACA;EACA,kBDxJQ;ECyJR;;AAEA;EACE;EACA;EACA;EACA,kBD/JM;ECgKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD5KK;EC6KL;;AAEA;EACE,OD9LE;;ACmMR;EACE;;AAEA;EACE;EACA,kBDhMD;ECiMC;;AAEA;EACE,OD5ME;;;ACoNZ;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBDnOQ;ECoOR;;AAEA;EACE;EACA;EACA;EACA,kBD1OM;EC2ON;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDvPK;ECwPL;;AAEA;EACE,ODzQE;;AC8QR;EACE;;AAEA;EACE;EACA,kBD3QD;EC4QC;;AAEA;EACE,ODvRE;;;ACgSZ;AACA;EACE;EACA;EACA;EACA,kBDrSU;ECsSV;EACA,OCzSe;ED0Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD3TS;EC4TT;EACA,kBD5TW;;AC8TX;EACE,OD3TU;;AC+TZ;EACE,OD3UC;EC4UD;EACA,kBDrVM;;ACuVN;EACE,ODpVI;;ACuVN;EACE,ODzUQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;;AAU1B;AAEE;EACE;EACA;EACA,kBDpJQ;ECqJR;;AAEA;EACE;EACA;EACA;EACA,kBD3JM;EC4JN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDxKK;ECyKL;;AAEA;EACE,OD1LE;;AC+LR;EACE;;AAEA;EACE;EACA,kBD5LD;EC6LC;;AAEA;EACE,ODxME;;AC8MqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBDlOQ;ECmOR;;AAEA;EACE;EACA;EACA;EACA,kBDzOM;EC0ON;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDtPK;ECuPL;;AAEA;EACE,ODxQE;;AC6QR;EACE;;AAEA;EACE;EACA,kBD1QD;EC2QC;;AAEA;EACE,ODtRE;;AC4RqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDtSU;ECuSV;EACA,OC1Se;ED2Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD5TS;EC6TT;EACA,kBD7TW;;AC+TX;EACE,OD5TU;;ACgUZ;EACE,OD5UC;EC6UD;EACA,kBDtVM;;ACwVN;EACE,ODrVI;;ACwVN;EACE,OD1UQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index cf0d44f..960d547 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -142,10 +142,6 @@ header { max-height: $boardLengthMax; min-height: $boardLengthMin; grid-template-columns: 33.3% 33.3% 33.3%; - - &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } - &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } - &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Three Board */ @@ -209,8 +205,11 @@ header { } } } - } + + &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } + &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } + &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Nine Board */ @@ -284,9 +283,11 @@ header { } } } - } + &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } + &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } + &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Notification */ From 2f87bf43c3470dbd0d1480c09303de32590e3b35 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 06:50:09 +0000 Subject: [PATCH 14/20] [patch] UMA-19: comment formatting --- src/app/util/redis.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/util/redis.py b/src/app/util/redis.py index 7f41dda..ff8ba57 100644 --- a/src/app/util/redis.py +++ b/src/app/util/redis.py @@ -24,9 +24,9 @@ def set_complex(self, key, complex_value): indent=4 ) return self.client.set(key, json_value) - # Set a complex key-value element by converting to json string + # Set a complex key-value element by converting to json string def get_complex(self, key): json_value = self.client.get(key).decode('utf-8') return json.loads(json_value) - # Get a complex key-value element by converting from json string + # Get a complex key-value element by converting from json string From 7e2342e79f0763f5e589762a5a4de6432ae5eb72 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 06:51:42 +0000 Subject: [PATCH 15/20] [patch] UMA-19: comment formatting --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 426ae98..f61c77b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ make build: env = "dev" # local : make sure redis is running # dev : ensure IP is whitelisted on render redis -# prod : +# prod make start: export FLASK_ENV=$(env) && make build && gunicorn -b 0.0.0.0:8080 --chdir src/app app:app From 8fb7a6248987f4f9153ee839621be94743f966fd Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 14:36:39 +0000 Subject: [PATCH 16/20] [patch] UMA-19: Allow move placement --- src/app/game/game.py | 46 +++++--- src/app/login/login.py | 2 + src/app/model/board/nineboard.py | 6 +- src/resources/static/scripts/game.js | 33 +++++- src/resources/static/styles/css/game.css | 62 ++++------ src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/scss/game.scss | 36 +++--- src/resources/templates/game.html | 118 +++---------------- 8 files changed, 124 insertions(+), 181 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index f3ce788..233c1df 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -25,7 +25,10 @@ def game(game_id, user_id): else: player_two_active = True - game_state = get_game_state(redis) + game_mode = redis.get("gameMode") + board = redis.get_complex("board") + game_state = get_game_state(board) + print(game_state) print("user id") print(user_id) @@ -66,7 +69,7 @@ def game(game_id, user_id): return render_template( "game.html", - board=redis.get_complex("board"), + board=board, zero=redis.get("0"), one=redis.get("1"), two=redis.get("2"), @@ -78,7 +81,7 @@ def game(game_id, user_id): eight=redis.get("8"), gameComplete=game_complete, gameId=game_id, - gameMode=redis.get("gameMode"), + gameMode=game_mode, notificationActive=notification_active, notificationHeader=notification_header, notificationMessage=notification_message, @@ -114,10 +117,13 @@ def place_standard_move(game_id, user_id, square): def place_ultimate_move(game_id, user_id, outer_square, inner_square): # Set player's move symbol = redis.get(user_id) - # redis.set(square, symbol) + board = redis.get_complex("board") + board[int(outer_square)][int(inner_square)] = int(symbol) + redis.set_complex("board", board) - print(outer_square) - print(inner_square) + print("[place_ultimate_move] outer_square: " + outer_square) + print("[place_ultimate_move] inner_square: " + inner_square) + print(board) # Switch player turn if redis.get("whoseTurn") == 'player1': @@ -131,14 +137,14 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): return game_page -def get_game_state(redis): - # board = { - # "0": redis.get("0"), "1": redis.get("1"), "2": redis.get("2"), - # "3": redis.get("3"), "4": redis.get("4"), "5": redis.get("5"), - # "6": redis.get("6"), "7": redis.get("7"), "8": redis.get("8"), - # } +def get_game_state(board): - board = redis.get_complex("board") + if isinstance(board[0], list): + outer_state = Status.IN_PROGRESS + for outer_square in board: + inner_state = get_game_state(outer_square) + print(inner_state) + return Status.IN_PROGRESS winning_combos = [ [0, 1, 2], @@ -151,8 +157,6 @@ def get_game_state(redis): [2, 4, 6] ] - print(board) - if board.count(0) == 0: return Status.DRAW # FixMe :: this check needs to happen after test each player has won... @@ -160,7 +164,7 @@ def get_game_state(redis): print("count: " + str(board.count(1))) if (board.count(1)) >= 3: - player_moves = get_player_moves("1", board) + player_moves = get_player_moves(1, board) print(player_moves) for combo in winning_combos: print(combo) @@ -168,7 +172,7 @@ def get_game_state(redis): return Status.PLAYER_ONE_WINS if (board.count(2)) >= 3: - player_moves = get_player_moves("2", board) + player_moves = get_player_moves(2, board) for combo in winning_combos: if set(combo).issubset(set(player_moves)): return Status.PLAYER_TWO_WINS @@ -177,5 +181,9 @@ def get_game_state(redis): def get_player_moves(player, board): - # FixMe :: check board structure and update below when a user has had 3 or more moves - return [int(k) for k, v in board.items() if v == player] + player_moves = [] + for index in range(len(board)): + if board[index] == player: + player_moves.append(index) + + return player_moves diff --git a/src/app/login/login.py b/src/app/login/login.py index 6023ef8..5f35cf9 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -34,6 +34,8 @@ def login(): else: print("Game Mode already set [" + redis.get("gameMode") + "]") # TODO :: err handle + print(redis.get_complex("board")) + # TODO :: set redis obj as dict { $game_id: [player1: "", player2: ""] } if request.form["gameId"] == "": redis.set("player1", request.form["name"]) diff --git a/src/app/model/board/nineboard.py b/src/app/model/board/nineboard.py index 5070171..50cbb08 100644 --- a/src/app/model/board/nineboard.py +++ b/src/app/model/board/nineboard.py @@ -14,6 +14,6 @@ class NineBoard(Board): bot_rhs = ThreeBoard() def list(self): - return [self.top_lhs, self.top_mid, self.top_rhs, - self.mid_lhs, self.mid_mid, self.mid_rhs, - self.bot_lhs, self.bot_mid, self.bot_rhs] + return [self.top_lhs.list(), self.top_mid.list(), self.top_rhs.list(), + self.mid_lhs.list(), self.mid_mid.list(), self.mid_rhs.list(), + self.bot_lhs.list(), self.bot_mid.list(), self.bot_rhs.list()] diff --git a/src/resources/static/scripts/game.js b/src/resources/static/scripts/game.js index 2eb0ff2..a637a06 100644 --- a/src/resources/static/scripts/game.js +++ b/src/resources/static/scripts/game.js @@ -1,10 +1,17 @@ let thisUserId; let thisSymbol; -function init() { +function init() { // TODO :: convert to JQuery? thisUserId = document.getElementById('this-user-id').value; thisSymbol = document.getElementById('this-user-symbol').value; + const gameMode = document.getElementById('game-mode').value; + if (gameMode === "STANDARD") initStandard(thisUserId, thisSymbol); + if (gameMode === "ULTIMATE") initUltimate(thisUserId, thisSymbol); + +} + +function initStandard(thisUserId, thisSymbol) { for (let i = 0; i < 9; i++) { const square = document.getElementById(`three-square-${i}`).getElementsByClassName("square")[0]; const state = square.innerHTML; @@ -22,7 +29,31 @@ function init() { square.innerHTML = '' } } +} + +function initUltimate(thisUserId, thisSymbol) { + for (let i = 0; i < 9; i++) { + const outerSquare = document.getElementById(`nine-square-${i}`).getElementsByClassName("square")[0]; + + for (let j = 0; j < 9; j++) { + const innerSquare = document.getElementById(`nine-square-${i}-${j}`).getElementsByClassName("square")[0]; + + const innerState = innerSquare.innerHTML; + if (innerState === thisSymbol) { + innerSquare.parentElement.classList.add("this-user"); + } else if (innerState !== "0") { + innerSquare.parentElement.classList.add("opponent-user"); + } + if (innerState === "0") { + innerSquare.innerHTML = ''; + } else if (innerState === "1") { + innerSquare.innerHTML = '' + } else if (innerState === "2") { + innerSquare.innerHTML = '' + } + } + } } function placeStandardMove(square) { diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 3182139..776d470 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -138,27 +138,35 @@ header h1 { color: #d8ff00; } -/** Board **/ -.board { - margin: 2rem auto 0 auto; - height: 50%; - aspect-ratio: 1/1; - max-height: 600px; - min-height: 400px; - grid-template-columns: 33.3% 33.3% 33.3%; -} -.board.threeboard.STANDARD { +/** Boards **/ +.boards .threeboard.STANDARD { display: grid; } -.board.threeboard.ULTIMATE { +.boards .threeboard.ULTIMATE { display: none; } -.board.nineboard.STANDARD { +.boards .nineboard.STANDARD { display: none; } -.board.nineboard.ULTIMATE { +.boards .nineboard.ULTIMATE { display: grid; } +.boards.this-user-1.player-1-False .threeboard .shadow-square .square, +.boards.this-user-1.player-1-False .nineboard .shadow-square.inner .square, .boards.this-user-2.player-2-False .threeboard .shadow-square .square, +.boards.this-user-2.player-2-False .nineboard .shadow-square.inner .square, .boards.game-complete-True .threeboard .shadow-square .square, +.boards.game-complete-True .nineboard .shadow-square.inner .square { + border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; + cursor: default !important; +} + +.board { + margin: 2rem auto 0 auto; + height: 50%; + aspect-ratio: 1/1; + max-height: 600px; + min-height: 400px; + grid-template-columns: 33.3% 33.3% 33.3%; +} /** Three Board */ .threeboard .shadow-square { @@ -212,18 +220,6 @@ header h1 { .threeboard .shadow-square.opponent-user .square .symbol { color: #2b0710; } -.threeboard.this-user-1.player-1-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.threeboard.this-user-2.player-2-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.threeboard.game-complete-True .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; - cursor: default !important; -} /** Nine Board */ .nineboard .shadow-square.outer { @@ -259,9 +255,9 @@ header h1 { border: 1px solid #d8ff00; } .nineboard .shadow-square.inner .square .symbol { - font-size: 4rem; + font-size: 1.5rem; position: absolute; - margin-top: calc(47.5% - 2rem); + margin-top: calc(50% - 0.75rem); } .nineboard .shadow-square.inner.this-user { border: 1px solid #d8ff00; @@ -285,18 +281,6 @@ header h1 { .nineboard .shadow-square.inner.opponent-user .square .symbol { color: #2b0710; } -.nineboard.this-user-1.player-1-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.nineboard.this-user-2.player-2-False .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922); - cursor: default; -} -.nineboard.game-complete-True .square { - border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; - cursor: default !important; -} /** Notification */ .notification { diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index b616299..d5406b7 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AACA;EAME;EACA,QCzImB;ED0InB;EACA,YC7Ie;ED8If,YC7Ie;ED8If;;AAVA;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;AACxB;EAAwB;;;AAU1B;AAEE;EACE;EACA;EACA,kBDpJQ;ECqJR;;AAEA;EACE;EACA;EACA;EACA,kBD3JM;EC4JN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDxKK;ECyKL;;AAEA;EACE,OD1LE;;AC+LR;EACE;;AAEA;EACE;EACA,kBD5LD;EC6LC;;AAEA;EACE,ODxME;;AC8MqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBDlOQ;ECmOR;;AAEA;EACE;EACA;EACA;EACA,kBDzOM;EC0ON;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDtPK;ECuPL;;AAEA;EACE,ODxQE;;AC6QR;EACE;;AAEA;EACE;EACA,kBD1QD;EC2QC;;AAEA;EACE,ODtRE;;AC4RqB;EAAU;EAA2B;;AACrC;EAAU;EAA2B;;AAC7C;EAAU;EAAsC;;;AAGzE;AACA;EACE;EACA;EACA;EACA,kBDtSU;ECuSV;EACA,OC1Se;ED2Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD5TS;EC6TT;EACA,kBD7TW;;AC+TX;EACE,OD5TU;;ACgUZ;EACE,OD5UC;EC6UD;EACA,kBDtVM;;ACwVN;EACE,ODrVI;;ACwVN;EACE,OD1UQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AAEE;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AAKrB;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA,QCrJmB;EDsJnB;EACA,YCzJe;ED0Jf,YCzJe;ED0Jf;;;AAGF;AAEE;EACE;EACA;EACA,kBDhKQ;ECiKR;;AAEA;EACE;EACA;EACA;EACA,kBDvKM;ECwKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpLK;ECqLL;;AAEA;EACE,ODtME;;AC2MR;EACE;;AAEA;EACE;EACA,kBDxMD;ECyMC;;AAEA;EACE,ODpNE;;;AC2NZ;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBD1OQ;EC2OR;;AAEA;EACE;EACA;EACA;EACA,kBDjPM;ECkPN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD9PK;EC+PL;;AAEA;EACE,ODhRE;;ACqRR;EACE;;AAEA;EACE;EACA,kBDlRD;ECmRC;;AAEA;EACE,OD9RE;;;ACqSZ;AACA;EACE;EACA;EACA;EACA,kBD1SU;EC2SV;EACA,OC9Se;ED+Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODhUS;ECiUT;EACA,kBDjUW;;ACmUX;EACE,ODhUU;;ACoUZ;EACE,ODhVC;ECiVD;EACA,kBD1VM;;AC4VN;EACE,ODzVI;;AC4VN;EACE,OD9UQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 960d547..1eee450 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -129,13 +129,25 @@ header { } } -/** Board **/ -.board { - &.threeboard.STANDARD { display: grid; } - &.threeboard.ULTIMATE { display: none; } - &.nineboard.STANDARD { display: none; } - &.nineboard.ULTIMATE { display: grid; } +/** Boards **/ +.boards { + .threeboard.STANDARD { display: grid; } + .threeboard.ULTIMATE { display: none; } + .nineboard.STANDARD { display: none; } + .nineboard.ULTIMATE { display: grid; } + + &.this-user-1.player-1-False, + &.this-user-2.player-2-False, + &.game-complete-True { + .threeboard .shadow-square .square, + .nineboard .shadow-square.inner .square { + border: 1px solid $rose25 !important; + cursor: default !important; + } + } +} +.board { margin: 2rem auto 0 auto; height: $boardLengthDefault; aspect-ratio: 1 / 1; @@ -206,10 +218,6 @@ header { } } } - - &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } - &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } - &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Nine Board */ @@ -250,9 +258,9 @@ header { } .symbol { - font-size: 4rem; + font-size: 1.5rem; position: absolute; - margin-top: calc(47.5% - 2rem); + margin-top: calc(50% - .75rem); } } @@ -284,10 +292,6 @@ header { } } } - - &.this-user-1.player-1-False { .square { border: 1px solid $rose25; cursor: default; } } - &.this-user-2.player-2-False { .square { border: 1px solid $rose25; cursor: default; } } - &.game-complete-True { .square { border: 1px solid $rose25 !important; cursor: default !important; } } } /** Notification */ diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index eb32389..150c8b4 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -59,114 +59,28 @@

{{ notificationHeader }}

-
-
+
+
{% for square in board %}
{{ square }}
{% endfor %}
- + {% if gameMode == "ULTIMATE" %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {% for outer_square in board %} +
+
+ {% set outer_index = loop.index0 %} + {% for inner_square in outer_square %} +
+
{{ inner_square }}
+
+ {% endfor %} +
+
+ {% endfor %}
+ {% endif %}
From dc684fcdc9178f3b80d58cb493156de68dbdfbbc Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 14:40:17 +0000 Subject: [PATCH 17/20] [patch] UMA-20: CHANGELOG prep --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 379147c..09bb581 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [0.3.0] - ??? - UMA-17: Give the user the option of standard or ultimate tic-tac-toe - UMA-19: Create interactive 9x9 board and allow player to make a turn +- UMA-20: Force ultimate players to play in the correct square after a move is placed ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns From fd3129e448825702a2985eef04217c428a3cc264 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 19:30:13 +0000 Subject: [PATCH 18/20] [patch] UMA-20: force playable outer square --- src/app/game/game.py | 17 +++++-- src/app/login/login.py | 9 ++++ src/resources/static/scripts/game.js | 44 ++++++++++++++++++- src/resources/static/styles/css/game.css | 26 +++++++++++ src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/css/login.css | 5 ++- src/resources/static/styles/css/login.css.map | 2 +- src/resources/static/styles/scss/game.scss | 34 ++++++++++++++ src/resources/static/styles/scss/login.scss | 5 ++- .../static/styles/scss/variables.scss | 3 +- src/resources/templates/game.html | 2 + 11 files changed, 137 insertions(+), 12 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index 233c1df..feb2bf0 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -27,7 +27,7 @@ def game(game_id, user_id): game_mode = redis.get("gameMode") board = redis.get_complex("board") - game_state = get_game_state(board) + game_state = get_game_state(redis, board) print(game_state) print("user id") @@ -70,6 +70,8 @@ def game(game_id, user_id): return render_template( "game.html", board=board, + playableSquare=redis.get("playableSquare"), + innerStates=redis.get_complex("innerStates"), zero=redis.get("0"), one=redis.get("1"), two=redis.get("2"), @@ -125,6 +127,9 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): print("[place_ultimate_move] inner_square: " + inner_square) print(board) + # Set next playable outer square + redis.set("playableSquare", inner_square) + # Switch player turn if redis.get("whoseTurn") == 'player1': redis.set("whoseTurn", "player2") @@ -137,13 +142,17 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): return game_page -def get_game_state(board): +def get_game_state(redis, board): if isinstance(board[0], list): + print("[get_game_state] board[0]: " + str(board[0])) outer_state = Status.IN_PROGRESS + inner_states = [] for outer_square in board: - inner_state = get_game_state(outer_square) - print(inner_state) + inner_state = get_game_state(redis, outer_square) + inner_states.append(inner_state.value) + print("[get_game_state] inner_states: " + str(inner_states)) + redis.set_complex("innerStates", inner_states) return Status.IN_PROGRESS winning_combos = [ diff --git a/src/app/login/login.py b/src/app/login/login.py index 5f35cf9..a85a0ab 100644 --- a/src/app/login/login.py +++ b/src/app/login/login.py @@ -2,6 +2,7 @@ from src.app.model.board.nineboard import NineBoard from src.app.model.board.threeboard import ThreeBoard +from src.app.model.status import Status # Login Logic @@ -23,6 +24,7 @@ def login(): board_list = ThreeBoard.list(board) # second index is the state: 0 for empty, 1 for cross, 2 for circle redis.set_complex("board", board_list) + redis.set_complex("innerStates", []) elif game_mode == "ULTIMATE": redis.set("gameMode", game_mode) @@ -30,6 +32,13 @@ def login(): board_list = NineBoard.list(board) # second index is the state: 0 for empty, 1 for cross, 2 for circle redis.set_complex("board", board_list) + inner_states = [ + Status.IN_PROGRESS.value, Status.IN_PROGRESS.value, Status.IN_PROGRESS.value, + Status.IN_PROGRESS.value, Status.IN_PROGRESS.value, Status.IN_PROGRESS.value, + Status.IN_PROGRESS.value, Status.IN_PROGRESS.value, Status.IN_PROGRESS.value + ] + redis.set_complex("innerStates", inner_states) + redis.set("playableSquare", "-1") # -1 is all squares... else: print("Game Mode already set [" + redis.get("gameMode") + "]") # TODO :: err handle diff --git a/src/resources/static/scripts/game.js b/src/resources/static/scripts/game.js index a637a06..3b8c874 100644 --- a/src/resources/static/scripts/game.js +++ b/src/resources/static/scripts/game.js @@ -32,9 +32,20 @@ function initStandard(thisUserId, thisSymbol) { } function initUltimate(thisUserId, thisSymbol) { + const gameId = "ab12-3cd4-e5f6-78gh"; + const innerStates = JSON.parse(document.getElementById("inner-states").value); + const playableSquare = document.getElementById("playable-square").value; + console.log(playableSquare) + for (let i = 0; i < 9; i++) { - const outerSquare = document.getElementById(`nine-square-${i}`).getElementsByClassName("square")[0]; + const outerSquare = document.getElementById(`nine-square-${i}`); + if (playableSquare === "-1" || playableSquare === i.toString()) outerSquare.classList.add("playable") + + if (innerStates[i] === 2) { outerSquare.classList.add("draw") } + if (innerStates[i] === 3) { outerSquare.classList.add(thisSymbol === '1' ? "this-user" : "opponent-user"); console.log(i) } + if (innerStates[i] === 4) { outerSquare.classList.add(thisSymbol === '2' ? "this-user" : "opponent-user") } + let outerBoard = [] for (let j = 0; j < 9; j++) { const innerSquare = document.getElementById(`nine-square-${i}-${j}`).getElementsByClassName("square")[0]; @@ -52,7 +63,28 @@ function initUltimate(thisUserId, thisSymbol) { } else if (innerState === "2") { innerSquare.innerHTML = '' } + + outerBoard.push(innerState) } + + // // if outerSquare has a win or lose status, apply colouring and prevent selection... + // // how to obtain status? outer_board array? or can we generate that here(!) + // // make a request to the backend to tell if the board is complete? + // // if count of 1 > 3 or count 2 > 3, make the call to get game state for that square + // $.get(`/game/${gameId}/state//${outerSquare}`) + // .then((res) => { + // if (res === "Status.PLAYER_ONE_WINS") { + // // Add class to the outer square, depending on thisPlayer + // } else if (res === "Status.PLAYER_TWO_WINS") { + // // Add class to the outer square, depending on thisPlayer + // } + // }) + // .catch((e) => { + // console.log(`Error getting the [${outerSquare}] game state for game with ID [${gameId}]`); + // console.log(e); + // }) + // + // // Question :: would an outer board array we more performant? } } @@ -88,10 +120,20 @@ function placeMove(outerSquare, innerSquare) { if (userSymbol === '1' && playerTwoActive === 'True') return; if (userSymbol === '2' && playerOneActive === 'True') return; + // Disallow if square not playable + const outerSquareClasses = document.getElementById(`nine-square-${outerSquare}`).classList; + if (!outerSquareClasses.contains('playable')) return + + // Disallow if inner square complete if (document.getElementById(`nine-square-${outerSquare}-${innerSquare}`).getElementsByClassName("square")[0].innerHTML !== '') { return; } + // Disallow if outer square complete + if (outerSquareClasses.contains('this-user') || outerSquareClasses.contains('opponent-user') || outerSquareClasses.contains('draw')) { + return; + } + $.get(`/game/${gameId}/place-move/${thisUserId}/${outerSquare}/${innerSquare}`); location.reload(); } diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 776d470..1ba707a 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -225,11 +225,37 @@ header h1 { .nineboard .shadow-square.outer { margin: 0.5rem; } +.nineboard .shadow-square.outer:not(.playable, .this-user, .opponent-user) .inner:not(.playable, .this-user, .opponent-user) { + cursor: default !important; + opacity: 0.3; +} +.nineboard .shadow-square.outer:not(.playable, .this-user, .opponent-user) .inner:not(.playable, .this-user, .opponent-user) .square { + cursor: default !important; + border: 1px solid rgba(231, 4, 83, 0.2509803922) !important; +} .nineboard .shadow-square.outer .square { display: grid; grid-template-columns: 33.3% 33.33% 33.3%; height: 100%; } +.nineboard .shadow-square.outer.this-user .shadow-square.inner { + border: 1px solid #d8ff00 !important; + opacity: 1; +} +.nineboard .shadow-square.outer.this-user .shadow-square.inner .square { + border: 1px solid #d8ff00 !important; + background-color: #d8ff00 !important; + cursor: default !important; +} +.nineboard .shadow-square.outer.opponent-user .shadow-square.inner { + border: 1px solid #e70453 !important; + opacity: 1; +} +.nineboard .shadow-square.outer.opponent-user .shadow-square.inner .square { + border: 1px solid #e70453 !important; + background-color: #e70453 !important; + cursor: default !important; +} .nineboard .shadow-square.inner { margin: 0.375rem; border: 1px solid rgba(231, 4, 83, 0.2509803922); diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index d5406b7..27a23a1 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AAEE;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AAKrB;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA,QCrJmB;EDsJnB;EACA,YCzJe;ED0Jf,YCzJe;ED0Jf;;;AAGF;AAEE;EACE;EACA;EACA,kBDhKQ;ECiKR;;AAEA;EACE;EACA;EACA;EACA,kBDvKM;ECwKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpLK;ECqLL;;AAEA;EACE,ODtME;;AC2MR;EACE;;AAEA;EACE;EACA,kBDxMD;ECyMC;;AAEA;EACE,ODpNE;;;AC2NZ;AAEE;EACE;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;EACA,kBD1OQ;EC2OR;;AAEA;EACE;EACA;EACA;EACA,kBDjPM;ECkPN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD9PK;EC+PL;;AAEA;EACE,ODhRE;;ACqRR;EACE;;AAEA;EACE;EACA,kBDlRD;ECmRC;;AAEA;EACE,OD9RE;;;ACqSZ;AACA;EACE;EACA;EACA;EACA,kBD1SU;EC2SV;EACA,OC9Se;ED+Sf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODhUS;ECiUT;EACA,kBDjUW;;ACmUX;EACE,ODhUU;;ACoUZ;EACE,ODhVC;ECiVD;EACA,kBD1VM;;AC4VN;EACE,ODzVI;;AC4VN;EACE,OD9UQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AAEE;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AAKrB;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA,QCrJmB;EDsJnB;EACA,YCzJe;ED0Jf,YCzJe;ED0Jf;;;AAGF;AAEE;EACE;EACA;EACA,kBDhKQ;ECiKR;;AAEA;EACE;EACA;EACA;EACA,kBDvKM;ECwKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpLK;ECqLL;;AAEA;EACE,ODtME;;AC2MR;EACE;;AAEA;EACE;EACA,kBDxMD;ECyMC;;AAEA;EACE,ODpNE;;;AC2NZ;AAEE;EACE;;AAGE;EACE;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;EACA,kBD5QQ;EC6QR;;AAEA;EACE;EACA;EACA;EACA,kBDnRM;ECoRN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDhSK;ECiSL;;AAEA;EACE,ODlTE;;ACuTR;EACE;;AAEA;EACE;EACA,kBDpTD;ECqTC;;AAEA;EACE,ODhUE;;;ACuUZ;AACA;EACE;EACA;EACA;EACA,kBD5UU;EC6UV;EACA,OChVe;EDiVf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODlWS;ECmWT;EACA,kBDnWW;;ACqWX;EACE,ODlWU;;ACsWZ;EACE,ODlXC;ECmXD;EACA,kBD5XM;;AC8XN;EACE,OD3XI;;AC8XN;EACE,ODhXQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/css/login.css b/src/resources/static/styles/css/login.css index 3834e2b..f912e17 100644 --- a/src/resources/static/styles/css/login.css +++ b/src/resources/static/styles/css/login.css @@ -73,7 +73,7 @@ section form .form-control .field .selection { transform: scale3d(1, 1, 1); background-color: rgba(231, 4, 83, 0.2509803922); color: #ccc; - transition: 0.15s ease-in-out background-color; + transition: 0.15s ease-in-out; } section form .form-control .field .selection.selected { background-color: rgba(231, 4, 83, 0.7490196078) !important; @@ -104,13 +104,14 @@ section form input { } section form input:focus { border-bottom: 1px solid rgba(231, 4, 83, 0.7490196078); + transition: 0.15s ease-in-out; } section form button { width: 8.5rem; background-color: rgba(231, 4, 83, 0.2509803922); border: none; color: whitesmoke; - transition: 0.15s ease-in-out background-color; + transition: 0.15s ease-in-out; padding: 0.5rem; cursor: pointer; letter-spacing: 1px; diff --git a/src/resources/static/styles/css/login.css.map b/src/resources/static/styles/css/login.css.map index d65a82c..88d4bf8 100644 --- a/src/resources/static/styles/css/login.css.map +++ b/src/resources/static/styles/css/login.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,ODQS;ECPT,YCdU;EDeV;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODDhD;;ACEX;EAAM;EAAkB;EAAe,ODD9B;;ACGT;EACE;EACA;EACA,SEtBG;EFuBH;EACA;;AAEA;EACE;EACA;EACA,QE5Bc;EF6Bd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBDxCD;ECyCC,OD7BG;EC8BH;;AAEA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDpDH;;ACyDH;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD/DU;ECgEV;EACA;EACA;;AAEA;EACE;;AAIJ;EACE;EACA,kBDrFG;ECsFH;EACA,OD7EU;EC8EV;EACA;EACA;EACA;EACA,YCrGQ;EDsGR;;AAEA;EACE,YD/FC","file":"login.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/login.scss","../scss/variables.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE,ODQS;ECPT,YCdU;EDeV;EACA;EACA;EACA;;AAEA;EAAM;;AACN;EAAM;EAAiB;EAAqB;EAAe,ODDhD;;ACEX;EAAM;EAAkB;EAAe,ODD9B;;ACGT;EACE;EACA;EACA,SEtBG;EFuBH;EACA;;AAEA;EACE;EACA;EACA,QE5Bc;EF6Bd;EACA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAEA,kBDxCD;ECyCC,OD7BG;EC8BH,YClDA;;ADoDA;EACE;EACA;EACA;EACA;;AAGF;EACE;EACA,kBDpDH;;ACyDH;EACE;EACA;;AAGF;EACE;;AAIJ;EACE;EACA;EACA;EACA;EACA,OD/DU;ECgEV;EACA;EACA;;AAEA;EACE;EACA,YCxFE;;AD4FN;EACE;EACA,kBDtFG;ECuFH;EACA,OD9EU;EC+EV,YCjGI;EDkGJ;EACA;EACA;EACA,YCtGQ;EDuGR;;AAEA;EACE,YDhGC","file":"login.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 1eee450..07ce67b 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -225,11 +225,45 @@ header { .shadow-square.outer { margin: .5rem; + &:not(.playable, .this-user, .opponent-user) { + .inner:not(.playable, .this-user, .opponent-user) { + cursor: default !important; + opacity: .3; + + .square { + cursor: default !important; + border: 1px solid $rose25 !important; + } + } + } + .square { display: grid; grid-template-columns: 33.3% 33.33% 33.3%; height: 100%; } + + &.this-user .shadow-square.inner { + border: 1px solid $chartreuse !important; + opacity: 1; + + .square { + border: 1px solid $chartreuse !important; + background-color: $chartreuse !important; + cursor: default !important; + } + } + + &.opponent-user .shadow-square.inner { + border: 1px solid $rose !important; + opacity: 1; + + .square { + border: 1px solid $rose !important; + background-color: $rose !important; + cursor: default !important; + } + } } .shadow-square.inner { diff --git a/src/resources/static/styles/scss/login.scss b/src/resources/static/styles/scss/login.scss index b390d07..8c03857 100644 --- a/src/resources/static/styles/scss/login.scss +++ b/src/resources/static/styles/scss/login.scss @@ -52,7 +52,7 @@ section { background-color: $rose25; color: $text-light; - transition: .15s ease-in-out background-color; + transition: $ease-in; &.selected { background-color: $rose75 !important; @@ -90,6 +90,7 @@ section { &:focus { border-bottom: 1px solid $rose75; + transition: $ease-in; } } @@ -98,7 +99,7 @@ section { background-color: $rose25; border: none; color: $text-lightest; - transition: .15s ease-in-out background-color; + transition: $ease-in; padding: .5rem; cursor: pointer; letter-spacing: 1px; diff --git a/src/resources/static/styles/scss/variables.scss b/src/resources/static/styles/scss/variables.scss index 7a141dd..7fd02b0 100644 --- a/src/resources/static/styles/scss/variables.scss +++ b/src/resources/static/styles/scss/variables.scss @@ -1,4 +1,5 @@ @import "colours"; @import "spacing"; -$drop-shadow: 0px 13px 50px -13px #00000019; \ No newline at end of file +$drop-shadow: 0px 13px 50px -13px #00000019; +$ease-in: .15s ease-in-out; \ No newline at end of file diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index 150c8b4..96a7505 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -14,6 +14,8 @@ + +
From 6aecc441607ffb4a8baae7cb2e62b0650f46966f Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 19:33:27 +0000 Subject: [PATCH 19/20] [patch] UMA-21: CHANGELOG prep --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09bb581..c5e1e53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - UMA-17: Give the user the option of standard or ultimate tic-tac-toe - UMA-19: Create interactive 9x9 board and allow player to make a turn - UMA-20: Force ultimate players to play in the correct square after a move is placed +- UMA-21: Make game completable through correct outer square selection and evaluation ## [0.2.1] - 07/11/2023 - UMA-11: Allow players to make their turns From d954ea783f6e8c566f44c621e0aca54756e0e337 Mon Sep 17 00:00:00 2001 From: jrsmth Date: Sat, 11 Nov 2023 21:05:00 +0000 Subject: [PATCH 20/20] [patch] UMA-21: implement full selection and resolving --- src/app/game/game.py | 56 +++++++++++++++----- src/resources/static/scripts/game.js | 6 ++- src/resources/static/styles/css/game.css | 11 ++-- src/resources/static/styles/css/game.css.map | 2 +- src/resources/static/styles/scss/game.scss | 13 ++--- src/resources/templates/game.html | 5 +- 6 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/app/game/game.py b/src/app/game/game.py index feb2bf0..208d5a8 100644 --- a/src/app/game/game.py +++ b/src/app/game/game.py @@ -1,5 +1,6 @@ from flask import render_template, url_for, redirect, Blueprint +from src.app.model.board.threeboard import ThreeBoard from src.app.model.mood import Mood from src.app.model.status import Status from src.version.version import __version__ @@ -128,7 +129,12 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): print(board) # Set next playable outer square - redis.set("playableSquare", inner_square) + if get_game_state(redis, board[int(inner_square)]) != Status.IN_PROGRESS: + redis.set("playableSquare", "-1") # -1 is all squares... + else: + redis.set("playableSquare", inner_square) + + print("[place_ultimate_move] playableSquare: " + redis.get("playableSquare")) # Switch player turn if redis.get("whoseTurn") == 'player1': @@ -143,18 +149,6 @@ def place_ultimate_move(game_id, user_id, outer_square, inner_square): def get_game_state(redis, board): - - if isinstance(board[0], list): - print("[get_game_state] board[0]: " + str(board[0])) - outer_state = Status.IN_PROGRESS - inner_states = [] - for outer_square in board: - inner_state = get_game_state(redis, outer_square) - inner_states.append(inner_state.value) - print("[get_game_state] inner_states: " + str(inner_states)) - redis.set_complex("innerStates", inner_states) - return Status.IN_PROGRESS - winning_combos = [ [0, 1, 2], [3, 4, 5], @@ -166,6 +160,19 @@ def get_game_state(redis, board): [2, 4, 6] ] + if isinstance(board[0], list): + print("[get_game_state] board[0]: " + str(board[0])) + outer_state = Status.IN_PROGRESS + inner_states = [] + for outer_square in board: + inner_state = get_game_state(redis, outer_square) + inner_states.append(inner_state.value) + print("[get_game_state] inner_states: " + str(inner_states)) + if inner_states.count('1') == 0: + return Status.DRAW + redis.set_complex("innerStates", inner_states) + return get_game_state(redis, create_false_board(inner_states)) + if board.count(0) == 0: return Status.DRAW # FixMe :: this check needs to happen after test each player has won... @@ -196,3 +203,26 @@ def get_player_moves(player, board): player_moves.append(index) return player_moves + + +def convert_states_to_symbols(state): + if state == 1: return 0 + if state == 2: return 0 + if state == 3: return 1 + if state == 4: return 2 + + +def create_false_board(states): + board = ThreeBoard() + board.top_lhs = convert_states_to_symbols(states[0]) + board.top_mid = convert_states_to_symbols(states[1]) + board.top_rhs = convert_states_to_symbols(states[2]) + board.mid_lhs = convert_states_to_symbols(states[3]) + board.mid_mid = convert_states_to_symbols(states[4]) + board.mid_rhs = convert_states_to_symbols(states[5]) + board.bot_lhs = convert_states_to_symbols(states[6]) + board.bot_mid = convert_states_to_symbols(states[7]) + board.bot_rhs = convert_states_to_symbols(states[8]) + + print("[create_false_board] board: " + str(board.list())) + return board.list() diff --git a/src/resources/static/scripts/game.js b/src/resources/static/scripts/game.js index 3b8c874..69ada4e 100644 --- a/src/resources/static/scripts/game.js +++ b/src/resources/static/scripts/game.js @@ -39,12 +39,16 @@ function initUltimate(thisUserId, thisSymbol) { for (let i = 0; i < 9; i++) { const outerSquare = document.getElementById(`nine-square-${i}`); - if (playableSquare === "-1" || playableSquare === i.toString()) outerSquare.classList.add("playable") if (innerStates[i] === 2) { outerSquare.classList.add("draw") } if (innerStates[i] === 3) { outerSquare.classList.add(thisSymbol === '1' ? "this-user" : "opponent-user"); console.log(i) } if (innerStates[i] === 4) { outerSquare.classList.add(thisSymbol === '2' ? "this-user" : "opponent-user") } + if ( + (playableSquare === "-1" || playableSquare === i.toString()) && + (!outerSquare.classList.contains("this-user") && !outerSquare.classList.contains("opponent-user") && !outerSquare.classList.contains("draw")) + ) { outerSquare.classList.add("playable") } + let outerBoard = [] for (let j = 0; j < 9; j++) { const innerSquare = document.getElementById(`nine-square-${i}-${j}`).getElementsByClassName("square")[0]; diff --git a/src/resources/static/styles/css/game.css b/src/resources/static/styles/css/game.css index 1ba707a..3f18a6b 100644 --- a/src/resources/static/styles/css/game.css +++ b/src/resources/static/styles/css/game.css @@ -22,14 +22,6 @@ header #badge { height: 2.25rem; margin: 0.5rem; } -header h1 { - margin: 0.5rem; - text-transform: uppercase; - letter-spacing: 0.25rem; - font-weight: 200; - font-size: 1.5rem; - line-height: 2.25rem; -} /** Tooltip */ .tooltip .tooltip-text { @@ -256,6 +248,9 @@ header h1 { background-color: #e70453 !important; cursor: default !important; } +.nineboard .shadow-square.outer.draw .shadow-square.inner { + opacity: 0.1; +} .nineboard .shadow-square.inner { margin: 0.375rem; border: 1px solid rgba(231, 4, 83, 0.2509803922); diff --git a/src/resources/static/styles/css/game.css.map b/src/resources/static/styles/css/game.css.map index 27a23a1..a57b6e3 100644 --- a/src/resources/static/styles/css/game.css.map +++ b/src/resources/static/styles/css/game.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,OD5BS;;AC+BX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,ODrDd;;ACsDL;EAAmB,OD5DpB;;AC8DC;EACE;;AAMF;EAAkB,ODrEnB;;ACsEC;EAAkB,ODhEb;;ACkEL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBDpGM;;ACuGR;EACE;EACA;EACA,kBD1GM;;AC6GR;EACE;EACA,ODvGC;;AC0GH;EACE,OD3GC;EC4GD;EACA;EACA;;AAGF;EAA6B,OD3GpB;;AC4GT;EAA6B,ODlH1B;;ACmHH;EAA6B,ODnH1B;;ACoHH;EAA6B,OD9GpB;;;ACkHb;AAEE;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AAKrB;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA,QCrJmB;EDsJnB;EACA,YCzJe;ED0Jf,YCzJe;ED0Jf;;;AAGF;AAEE;EACE;EACA;EACA,kBDhKQ;ECiKR;;AAEA;EACE;EACA;EACA;EACA,kBDvKM;ECwKN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDpLK;ECqLL;;AAEA;EACE,ODtME;;AC2MR;EACE;;AAEA;EACE;EACA,kBDxMD;ECyMC;;AAEA;EACE,ODpNE;;;AC2NZ;AAEE;EACE;;AAGE;EACE;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAKN;EACE;EACA;EACA,kBD5QQ;EC6QR;;AAEA;EACE;EACA;EACA;EACA,kBDnRM;ECoRN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBDhSK;ECiSL;;AAEA;EACE,ODlTE;;ACuTR;EACE;;AAEA;EACE;EACA,kBDpTD;ECqTC;;AAEA;EACE,ODhUE;;;ACuUZ;AACA;EACE;EACA;EACA;EACA,kBD5UU;EC6UV;EACA,OChVe;EDiVf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,ODlWS;ECmWT;EACA,kBDnWW;;ACqWX;EACE,ODlWU;;ACsWZ;EACE,ODlXC;ECmXD;EACA,kBD5XM;;AC8XN;EACE,OD3XI;;AC8XN;EACE,ODhXQ","file":"game.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../scss/base.scss","../scss/colours.scss","../scss/game.scss","../scss/spacing.scss"],"names":[],"mappings":"AAEA;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE,kBCRO;EDSP,OCSc;EDRd;;;AEZF;AACA;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;AAEE;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;;AAIJ;AACA;EACE;EACA;;AAEA;EACE,ODnBS;;ACsBX;EACE;EACA;;AAEA;EACE;;AACA;EAAwB;;AAExB;EAAwB;;AACxB;EAAwB;;AAExB;EACE;;AAGF;EACE;EACA;EACA;;AAIA;EAAmB,OD5Cd;;AC6CL;EAAmB,ODnDpB;;ACqDC;EACE;;AAMF;EAAkB,OD5DnB;;AC6DC;EAAkB,ODvDb;;ACyDL;EACE;;;AAOV;AACA;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEA;EACE;EACA,kBD3FM;;AC8FR;EACE;EACA;EACA,kBDjGM;;ACoGR;EACE;EACA,OD9FC;;ACiGH;EACE,ODlGC;ECmGD;EACA;EACA;;AAGF;EAA6B,ODlGpB;;ACmGT;EAA6B,ODzG1B;;AC0GH;EAA6B,OD1G1B;;AC2GH;EAA6B,ODrGpB;;;ACyGb;AAEE;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AACvB;EAAuB;;AAKrB;AAAA;AAAA;AAAA;EAEE;EACA;;;AAKN;EACE;EACA,QC5ImB;ED6InB;EACA,YChJe;EDiJf,YChJe;EDiJf;;;AAGF;AAEE;EACE;EACA;EACA,kBDvJQ;ECwJR;;AAEA;EACE;EACA;EACA;EACA,kBD9JM;EC+JN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD3KK;EC4KL;;AAEA;EACE,OD7LE;;ACkMR;EACE;;AAEA;EACE;EACA,kBD/LD;ECgMC;;AAEA;EACE,OD3ME;;;ACkNZ;AAEE;EACE;;AAGE;EACE;EACA;;AAEA;EACE;EACA;;AAKN;EACE;EACA;EACA;;AAGF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAIJ;EACE;;AAIJ;EACE;EACA;EACA,kBDvQQ;ECwQR;;AAEA;EACE;EACA;EACA;EACA,kBD9QM;EC+QN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAIJ;EACE;;AAEA;EACE;EACA,kBD3RK;EC4RL;;AAEA;EACE,OD7SE;;ACkTR;EACE;;AAEA;EACE;EACA,kBD/SD;ECgTC;;AAEA;EACE,OD3TE;;;ACkUZ;AACA;EACE;EACA;EACA;EACA,kBDvUU;ECwUV;EACA,OC3Ue;ED4Uf;EACA;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;AAIJ;EAAiB;;AACjB;EAAiB;;AAEjB;EACE;EACA;;AAGF;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE,OD7VS;EC8VT;EACA,kBD9VW;;ACgWX;EACE,OD7VU;;ACiWZ;EACE,OD7WC;EC8WD;EACA,kBDvXM;;ACyXN;EACE,ODtXI;;ACyXN;EACE,OD3WQ","file":"game.css"} \ No newline at end of file diff --git a/src/resources/static/styles/scss/game.scss b/src/resources/static/styles/scss/game.scss index 07ce67b..85cf28a 100644 --- a/src/resources/static/styles/scss/game.scss +++ b/src/resources/static/styles/scss/game.scss @@ -9,15 +9,6 @@ header { height: 2.25rem; margin: .5rem; } - - h1 { - margin: .5rem; - text-transform: uppercase; - letter-spacing: .25rem; - font-weight: 200; - font-size: 1.5rem; - line-height: 2.25rem; - } } /** Tooltip */ @@ -264,6 +255,10 @@ header { cursor: default !important; } } + + &.draw .shadow-square.inner { + opacity: .1; + } } .shadow-square.inner { diff --git a/src/resources/templates/game.html b/src/resources/templates/game.html index 96a7505..65308f3 100644 --- a/src/resources/templates/game.html +++ b/src/resources/templates/game.html @@ -20,9 +20,10 @@
badge -
{{ version }}
+
+ {{ version }} +
-

Ultima