From c6302ad8c09fb170b2586f15e50449d5ce5e5bb6 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Sat, 10 Sep 2022 18:38:55 +0200 Subject: [PATCH 1/5] Add "Announcements" page to "Add game" component --- .../add-game/add-game.component.html | 8 +- .../add-game/add-game.component.scss | 4 + .../components/add-game/add-game.component.ts | 38 +++++++++ .../models/doppelkopf/enums/announcement.ts | 77 +++++++++++++++++-- 4 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/app/components/add-game/add-game.component.html b/src/app/components/add-game/add-game.component.html index 25be637..5b48448 100644 --- a/src/app/components/add-game/add-game.component.html +++ b/src/app/components/add-game/add-game.component.html @@ -3,12 +3,16 @@
+

Select the active players for the game:

{{player.firstName}}

Illegal amount of players!

- +
- +

Select the announcements for this game:

+
{{announcement.toString()}}
+

Illegal set of announcements!

+
diff --git a/src/app/components/add-game/add-game.component.scss b/src/app/components/add-game/add-game.component.scss index 06447c2..89272cd 100644 --- a/src/app/components/add-game/add-game.component.scss +++ b/src/app/components/add-game/add-game.component.scss @@ -31,3 +31,7 @@ .visible-true { display: inherit; } + +#announcement-warn { + color: $warn; +} diff --git a/src/app/components/add-game/add-game.component.ts b/src/app/components/add-game/add-game.component.ts index ffd9c66..d8a118e 100644 --- a/src/app/components/add-game/add-game.component.ts +++ b/src/app/components/add-game/add-game.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {Player} from '../../models/doppelkopf/player'; +import * as Announcement from '../../models/doppelkopf/enums/announcement'; @Component({ selector: 'app-add-game', @@ -10,6 +11,8 @@ export class AddGameComponent implements OnInit { potentialPlayers: Player[] = []; actualPlayers: Player[] = []; + selectedAnnouncements: Announcement.Announcement[] = []; + currentPage: number = 0; constructor() { @@ -80,4 +83,39 @@ export class AddGameComponent implements OnInit { switchToNextPage(): void { this.currentPage++; } + + /** + * Toggles the activity status for the given announcement + * @param announcement The announcement to toggle activity for + */ + toggleAnnouncement(announcement: Announcement.Announcement): void { + let index = this.selectedAnnouncements.indexOf(announcement); + if(index !== -1){ + this.selectedAnnouncements.splice(index, 1); + } else { + this.selectedAnnouncements.push(announcement); + } + } + + /** + * Checks if the given announcement is already marked as selected + * @param announcement The announcement to check the status for + */ + isAnnouncementActive(announcement: Announcement.Announcement): boolean { + return this.selectedAnnouncements.indexOf(announcement) !== -1; + } + + /** + * Returns a list of all possible announcements + */ + getAllPossibleAnnouncements(): Announcement.Announcement[] { + return Announcement.getAllAnnouncementValues(); + } + + /** + * Checks, if the currently selected announcements are a valid set of announcements + */ + checkAnnouncementsValid(): boolean { + return Announcement.checkValidity(this.selectedAnnouncements); + } } diff --git a/src/app/models/doppelkopf/enums/announcement.ts b/src/app/models/doppelkopf/enums/announcement.ts index 8e6b3e2..659f651 100644 --- a/src/app/models/doppelkopf/enums/announcement.ts +++ b/src/app/models/doppelkopf/enums/announcement.ts @@ -1,10 +1,71 @@ export enum Announcement { - RE = 0, - CONTRA = 1, - RE_NO_NINETY = 2.1, - CONTRA_NO_NINETY = 2.2, - RE_NO_SIXTY = 3.1, - CONTRA_NO_SIXTY = 3.2, - RE_NO_THIRTY = 4.1, - CONTRA_NO_THIRTY = 4.2 + RE = 'Re', + CONTRA = 'Contra', + RE_NO_NINETY = 'Re: No ninety', + CONTRA_NO_NINETY = 'Contra: No ninety', + RE_NO_SIXTY = 'Re: No sixty', + CONTRA_NO_SIXTY = 'Contra: No sixty', + RE_NO_THIRTY = 'Re: No thirty', + CONTRA_NO_THIRTY = 'Contra: No thirty' +} + +/** + * Returns all available announcement values + */ +export function getAllAnnouncementValues(): Announcement[] { + return [ + Announcement.RE, + Announcement.CONTRA, + Announcement.RE_NO_NINETY, + Announcement.CONTRA_NO_NINETY, + Announcement.RE_NO_SIXTY, + Announcement.CONTRA_NO_SIXTY, + Announcement.RE_NO_THIRTY, + Announcement.CONTRA_NO_THIRTY + ]; +} + +/** + * Checks if the selected announcements are a valid set of announcements. + * E.g.: If RE_NO_NINETY is newly selected, RE also has to be selected + * @param alreadySelected + * @param newSelected + */ +export function checkValidity(selectedAnnouncements: Announcement[]): boolean { + // First check all "RE" Announcements + if(selectedAnnouncements.indexOf(Announcement.RE_NO_THIRTY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.RE_NO_SIXTY) === -1) { + return false; + } + } + if(selectedAnnouncements.indexOf(Announcement.RE_NO_SIXTY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.RE_NO_NINETY) === -1) { + return false; + } + } + if(selectedAnnouncements.indexOf(Announcement.RE_NO_NINETY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.RE) === -1) { + return false; + } + } + + // Now same for "CONTRA" + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_THIRTY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_SIXTY) === -1) { + return false; + } + } + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_SIXTY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_NINETY) === -1) { + return false; + } + } + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_NINETY) !== -1) { + if(selectedAnnouncements.indexOf(Announcement.CONTRA) === -1) { + return false; + } + } + + // all fine, return true + return true } From f69f7f1731698caac44cc8ce151e463d27cab8d7 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Sat, 10 Sep 2022 18:45:22 +0200 Subject: [PATCH 2/5] add-game.component.ts code cleanup --- .../components/add-game/add-game.component.ts | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/app/components/add-game/add-game.component.ts b/src/app/components/add-game/add-game.component.ts index d8a118e..2ce39ed 100644 --- a/src/app/components/add-game/add-game.component.ts +++ b/src/app/components/add-game/add-game.component.ts @@ -16,6 +16,16 @@ export class AddGameComponent implements OnInit { currentPage: number = 0; constructor() { + this.generateDemoData(); + } + + ngOnInit(): void { + } + + /** + * Generates demo data to test the UI + */ + generateDemoData() { this.potentialPlayers.push({ firebonkId: 1, uuid: 'abc-def-ghi-j', @@ -42,19 +52,32 @@ export class AddGameComponent implements OnInit { firstName: 'Moritz' }); - this.actualPlayers.push(...this.potentialPlayers.slice(0,4)); + this.actualPlayers.push(...this.potentialPlayers.slice(0, 4)); } - ngOnInit(): void { + /** + * Switches the entry mask UI to the next page + */ + switchToNextPage(): void { + this.currentPage++; } + /** + * ____ __ + * / __ \/ /___ ___ _____ __________ + * / /_/ / / __ `/ / / / _ \/ ___/ ___/ + * / ____/ / /_/ / /_/ / __/ / (__ ) + * /_/ /_/\__,_/\__, /\___/_/ /____/ + * /____/ + */ + /** * Toggles if the given player is should be an active player for the current game * @param player The player to toggle the activity for */ togglePlayer(player: Player): void { let index = this.actualPlayers.indexOf(player); - if(index !== -1){ + if (index !== -1) { this.actualPlayers.splice(index, 1); } else { this.actualPlayers.push(player); @@ -78,11 +101,12 @@ export class AddGameComponent implements OnInit { } /** - * Switches the entry mask UI to the next page + * ___ __ + * / | ____ ____ ____ __ ______ ________ ____ ___ ___ ____ / /______ + * / /| | / __ \/ __ \/ __ \/ / / / __ \/ ___/ _ \/ __ `__ \/ _ \/ __ \/ __/ ___/ + * / ___ |/ / / / / / / /_/ / /_/ / / / / /__/ __/ / / / / / __/ / / / /_(__ ) + * /_/ |_/_/ /_/_/ /_/\____/\__,_/_/ /_/\___/\___/_/ /_/ /_/\___/_/ /_/\__/____/ */ - switchToNextPage(): void { - this.currentPage++; - } /** * Toggles the activity status for the given announcement @@ -90,7 +114,7 @@ export class AddGameComponent implements OnInit { */ toggleAnnouncement(announcement: Announcement.Announcement): void { let index = this.selectedAnnouncements.indexOf(announcement); - if(index !== -1){ + if (index !== -1) { this.selectedAnnouncements.splice(index, 1); } else { this.selectedAnnouncements.push(announcement); From bed8992ddd4e328c105fd1202d92286ad6c7f5dd Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Sat, 10 Sep 2022 19:26:12 +0200 Subject: [PATCH 3/5] Add "team selection" page to "add game" component --- .../add-game/add-game.component.html | 8 ++- .../add-game/add-game.component.scss | 10 +++- .../components/add-game/add-game.component.ts | 59 +++++++++++++++++++ .../models/doppelkopf/enums/announcement.ts | 40 +++++++++++++ src/app/models/doppelkopf/enums/team.ts | 2 +- 5 files changed, 114 insertions(+), 5 deletions(-) diff --git a/src/app/components/add-game/add-game.component.html b/src/app/components/add-game/add-game.component.html index 5b48448..5ec16b8 100644 --- a/src/app/components/add-game/add-game.component.html +++ b/src/app/components/add-game/add-game.component.html @@ -9,13 +9,19 @@
+

Players: {{getPlayerNamesAsString()}}

Select the announcements for this game:

{{announcement.toString()}}

Illegal set of announcements!

- +

Players: {{getPlayerNamesAsString()}}

+

Highest Announcements: {{getHighestAnnouncements()}}

+

Please select the elder(s):

+
{{player.firstName}}
+

Illegal game teams!

+
diff --git a/src/app/components/add-game/add-game.component.scss b/src/app/components/add-game/add-game.component.scss index 89272cd..22c8b0a 100644 --- a/src/app/components/add-game/add-game.component.scss +++ b/src/app/components/add-game/add-game.component.scss @@ -20,7 +20,7 @@ color: $inactive; } -#player-amount-warn { +#player-amount-warn, #announcement-warn, #team-warn { color: $warn; } @@ -32,6 +32,10 @@ display: inherit; } -#announcement-warn { - color: $warn; +.elder-player-false { + color: $inactive; +} + +.elder-player-true { + color: $active; } diff --git a/src/app/components/add-game/add-game.component.ts b/src/app/components/add-game/add-game.component.ts index 2ce39ed..e9af485 100644 --- a/src/app/components/add-game/add-game.component.ts +++ b/src/app/components/add-game/add-game.component.ts @@ -1,6 +1,7 @@ import {Component, OnInit} from '@angular/core'; import {Player} from '../../models/doppelkopf/player'; import * as Announcement from '../../models/doppelkopf/enums/announcement'; +import {Team} from '../../models/doppelkopf/enums/team'; @Component({ selector: 'app-add-game', @@ -100,6 +101,18 @@ export class AddGameComponent implements OnInit { return this.actualPlayers.length !== 4; } + /** + * Returns the names of the active players as a comma-separated string + */ + getPlayerNamesAsString(): string { + let playerNames = ''; + for(let player of this.actualPlayers) { + playerNames += player.firstName + ', '; + } + // Remove last ", " + return playerNames.substring(0, playerNames.length-2); + } + /** * ___ __ * / | ____ ____ ____ __ ______ ________ ____ ___ ___ ____ / /______ @@ -142,4 +155,50 @@ export class AddGameComponent implements OnInit { checkAnnouncementsValid(): boolean { return Announcement.checkValidity(this.selectedAnnouncements); } + + getHighestAnnouncements(): string { + return Announcement.returnTwoHighestAnnouncements(this.selectedAnnouncements); + } + + /** + * ______ + * /_ __/__ ____ _____ ___ _____ + * / / / _ \/ __ `/ __ `__ \/ ___/ + * / / / __/ /_/ / / / / / (__ ) + * /_/ \___/\__,_/_/ /_/ /_/____/ + */ + + /** + * Toggles the players team + * @param player The player to toggle the team for + */ + toggleElderPlayer(player: Player): void { + if(player.team === Team.RE) { + player.team = Team.CONTRA; + } else { + player.team = Team.RE; + } + } + + /** + * Checks if the player is an elder + * @param player The player to check + */ + isPlayerElder(player: Player): boolean { + return player.team === Team.RE; + } + + /** + * Checks if the current team assignment is valid + */ + checkValidTeamAssignment(): boolean { + let numberOfElderPlayers: number = 0; + for(let player of this.actualPlayers) { + if(player.team === Team.RE) { + numberOfElderPlayers++; + } + } + + return !(numberOfElderPlayers !== 1 && numberOfElderPlayers !== 2); + } } diff --git a/src/app/models/doppelkopf/enums/announcement.ts b/src/app/models/doppelkopf/enums/announcement.ts index 659f651..194a743 100644 --- a/src/app/models/doppelkopf/enums/announcement.ts +++ b/src/app/models/doppelkopf/enums/announcement.ts @@ -69,3 +69,43 @@ export function checkValidity(selectedAnnouncements: Announcement[]): boolean { // all fine, return true return true } + +export function returnTwoHighestAnnouncements(selectedAnnouncements: Announcement[]): string { + let finalString: string = ''; + + // First check "RE" announcements + if(selectedAnnouncements.indexOf(Announcement.RE_NO_THIRTY) !== -1) { + finalString += Announcement.RE_NO_THIRTY; + } else if (selectedAnnouncements.indexOf(Announcement.RE_NO_SIXTY) !== -1) { + finalString += Announcement.RE_NO_SIXTY; + } else if (selectedAnnouncements.indexOf(Announcement.RE_NO_NINETY) !== -1) { + finalString += Announcement.RE_NO_NINETY; + } else if (selectedAnnouncements.indexOf(Announcement.RE) !== -1) { + finalString += Announcement.RE; + } + + // If there was a "RE" announcement, add a ", " so we can list the CONTRA announcement properly + if(finalString !== '') { + finalString += ', '; + } + + // Now check "CONTRA" + if(selectedAnnouncements.indexOf(Announcement.CONTRA_NO_THIRTY) !== -1) { + finalString += Announcement.CONTRA_NO_THIRTY; + } else if (selectedAnnouncements.indexOf(Announcement.CONTRA_NO_SIXTY) !== -1) { + finalString += Announcement.CONTRA_NO_SIXTY; + } else if (selectedAnnouncements.indexOf(Announcement.CONTRA_NO_NINETY) !== -1) { + finalString += Announcement.CONTRA_NO_NINETY; + } else if (selectedAnnouncements.indexOf(Announcement.CONTRA) !== -1) { + finalString += Announcement.CONTRA; + } else { + // Remove the last two chars from the finalString (", ") + finalString = finalString.substring(0, finalString.length-2); + } + + if(finalString === '') { + finalString = 'None'; + } + + return finalString; +} diff --git a/src/app/models/doppelkopf/enums/team.ts b/src/app/models/doppelkopf/enums/team.ts index 3604fb2..9bc7ae7 100644 --- a/src/app/models/doppelkopf/enums/team.ts +++ b/src/app/models/doppelkopf/enums/team.ts @@ -1,4 +1,4 @@ export enum Team { RE = 0, - KONTRA = 1 + CONTRA = 1 } From a9aca1351c7b518f050e955e7616761c57644bd2 Mon Sep 17 00:00:00 2001 From: Patrick Mueller Date: Sat, 10 Sep 2022 19:33:55 +0200 Subject: [PATCH 4/5] Some button styling --- .../components/add-game/add-game.component.html | 6 +++--- .../components/add-game/add-game.component.scss | 15 +++++++-------- src/app/components/header/header.component.html | 2 +- src/styles.scss | 1 + 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/app/components/add-game/add-game.component.html b/src/app/components/add-game/add-game.component.html index 5ec16b8..0059c44 100644 --- a/src/app/components/add-game/add-game.component.html +++ b/src/app/components/add-game/add-game.component.html @@ -4,14 +4,14 @@

Select the active players for the game:

-
{{player.firstName}}
+
{{player.firstName}}

Illegal amount of players!

Players: {{getPlayerNamesAsString()}}

Select the announcements for this game:

-
{{announcement.toString()}}
+
{{announcement.toString()}}

Illegal set of announcements!

@@ -19,7 +19,7 @@

Players: {{getPlayerNamesAsString()}}

Highest Announcements: {{getHighestAnnouncements()}}

Please select the elder(s):

-
{{player.firstName}}
+
{{player.firstName}}

Illegal game teams!

diff --git a/src/app/components/add-game/add-game.component.scss b/src/app/components/add-game/add-game.component.scss index 22c8b0a..29d00da 100644 --- a/src/app/components/add-game/add-game.component.scss +++ b/src/app/components/add-game/add-game.component.scss @@ -12,11 +12,11 @@ color: $text; } -.active-true { +.active-true, .elder-player-true { color: $active; } -.active-false { +.active-false, .elder-player-false { color: $inactive; } @@ -32,10 +32,9 @@ display: inherit; } -.elder-player-false { - color: $inactive; -} - -.elder-player-true { - color: $active; +.togglebtn { + text-align: center; + max-width: 10em; + background-color: $button; + margin: .5em; } diff --git a/src/app/components/header/header.component.html b/src/app/components/header/header.component.html index e545b5e..2bc64cc 100644 --- a/src/app/components/header/header.component.html +++ b/src/app/components/header/header.component.html @@ -1,5 +1,5 @@ diff --git a/src/app/components/add-game/add-game.component.scss b/src/app/components/add-game/add-game.component.scss index 29d00da..bd85815 100644 --- a/src/app/components/add-game/add-game.component.scss +++ b/src/app/components/add-game/add-game.component.scss @@ -2,6 +2,16 @@ #add-game { padding-top: $header_height; + display: grid; + grid-template-areas: 'entry entry scores'; +} + +#game-infos { + grid-area: entry; +} + +#scores { + grid-area: scores; } #which-players div { @@ -20,7 +30,7 @@ color: $inactive; } -#player-amount-warn, #announcement-warn, #team-warn { +#player-amount-warn, #announcement-warn, #team-warn, #score-warn { color: $warn; } @@ -38,3 +48,15 @@ background-color: $button; margin: .5em; } + +.team-Re { + background-color: $secondary; +} + +.team-Contra { + background-color: $primary; +} + +table.point-entry td { + padding: .5em; +} diff --git a/src/app/components/add-game/add-game.component.ts b/src/app/components/add-game/add-game.component.ts index e9af485..079d0e3 100644 --- a/src/app/components/add-game/add-game.component.ts +++ b/src/app/components/add-game/add-game.component.ts @@ -30,27 +30,32 @@ export class AddGameComponent implements OnInit { this.potentialPlayers.push({ firebonkId: 1, uuid: 'abc-def-ghi-j', - firstName: 'Patrick' + firstName: 'Patrick', + team: Team.CONTRA }); this.potentialPlayers.push({ firebonkId: 2, uuid: 'abc-def-ghi-k', - firstName: 'Julian' + firstName: 'Julian', + team: Team.CONTRA }); this.potentialPlayers.push({ firebonkId: 3, uuid: 'abc-def-ghi-l', - firstName: 'Yannick' + firstName: 'Yannick', + team: Team.CONTRA }); this.potentialPlayers.push({ firebonkId: 4, uuid: 'abc-def-ghi-m', - firstName: 'Janina' + firstName: 'Janina', + team: Team.CONTRA }); this.potentialPlayers.push({ firebonkId: 5, uuid: 'abc-def-ghi-n', - firstName: 'Moritz' + firstName: 'Moritz', + team: Team.CONTRA }); this.actualPlayers.push(...this.potentialPlayers.slice(0, 4)); @@ -106,11 +111,11 @@ export class AddGameComponent implements OnInit { */ getPlayerNamesAsString(): string { let playerNames = ''; - for(let player of this.actualPlayers) { + for (let player of this.actualPlayers) { playerNames += player.firstName + ', '; } // Remove last ", " - return playerNames.substring(0, playerNames.length-2); + return playerNames.substring(0, playerNames.length - 2); } /** @@ -173,7 +178,7 @@ export class AddGameComponent implements OnInit { * @param player The player to toggle the team for */ toggleElderPlayer(player: Player): void { - if(player.team === Team.RE) { + if (player.team === Team.RE) { player.team = Team.CONTRA; } else { player.team = Team.RE; @@ -193,12 +198,88 @@ export class AddGameComponent implements OnInit { */ checkValidTeamAssignment(): boolean { let numberOfElderPlayers: number = 0; - for(let player of this.actualPlayers) { - if(player.team === Team.RE) { + for (let player of this.actualPlayers) { + if (player.team === Team.RE) { numberOfElderPlayers++; } } return !(numberOfElderPlayers !== 1 && numberOfElderPlayers !== 2); } + + /** + * _____ + * / ___/_________ ________ _____ + * \__ \/ ___/ __ \/ ___/ _ \/ ___/ + * ___/ / /__/ /_/ / / / __(__ ) + * /____/\___/\____/_/ \___/____/ + */ + + /** + * Checks if the sum of all points is exactly 240 + */ + totalScoreValid(): boolean { + let totalScore: number = 0; + for (let player of this.actualPlayers) { + totalScore += player.finalCardScore ?? 0; + } + + return totalScore === 240; + } + + /** + * ______ _____ + * / ____/___ _____ ___ ___ / ___/_________ ________ + * / / __/ __ `/ __ `__ \/ _ \ \__ \/ ___/ __ \/ ___/ _ \ + * / /_/ / /_/ / / / / / / __/ ___/ / /__/ /_/ / / / __/ + * \____/\__,_/_/ /_/ /_/\___/ /____/\___/\____/_/ \___/ + */ + + /** + * Calculates the game points for the given player + * @param player The player to calculate points for + */ + calculateCurrentScore(player: Player): number { + let gameScore: number = 0; + let teamScore = this.getTeamScore(player); + + // Won? If so, by how much? + if (teamScore > 210) { + gameScore += 4; + } else if (teamScore > 180) { + gameScore += 3; + } else if (teamScore > 150) { + gameScore += 2; + } else if (teamScore > 120) { + gameScore += 1; + } else if (teamScore < 30) { + gameScore -= 4; + } else if (teamScore < 60) { + gameScore -= 3; + } else if (teamScore < 90) { + gameScore -= 2; + } else { + gameScore -= 1; + } + + // TODO Announcements etc + + return gameScore; + } + + /** + * Calculates the team card score of the given players team + * @param player The player to calculate the teams points for + */ + getTeamScore(player: Player): number { + let totalTeamScore: number = player.finalCardScore ?? 0; + + for (let otherPlayer of this.actualPlayers) { + if (otherPlayer !== player && otherPlayer.team === player.team) { + totalTeamScore += otherPlayer.finalCardScore ?? 0; + } + } + + return totalTeamScore; + } } diff --git a/src/app/models/doppelkopf/enums/team.ts b/src/app/models/doppelkopf/enums/team.ts index 9bc7ae7..3ffa526 100644 --- a/src/app/models/doppelkopf/enums/team.ts +++ b/src/app/models/doppelkopf/enums/team.ts @@ -1,4 +1,4 @@ export enum Team { - RE = 0, - CONTRA = 1 + RE = 'Re', + CONTRA = 'Contra' } diff --git a/src/styles.scss b/src/styles.scss index b7e777c..aa649c7 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -13,7 +13,7 @@ $header_height: 3em; /* Global defaults */ html, body { - height: 100%; + height: 95%; background-color: $primary; color: $text; font-family: sans-serif;