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 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