fix a bunch of issues with cribbage site
authorGeoffrey Allott <geoffrey@allott.email>
Wed, 7 Jun 2023 22:42:15 +0000 (23:42 +0100)
committerGeoffrey Allott <geoffrey@allott.email>
Wed, 7 Jun 2023 22:42:15 +0000 (23:42 +0100)
site/modules/card.js
site/modules/cribbage.js
site/modules/words.js

index 032575b25872e4a91a6d5d56092ef24e7ac896ac..3ce85a59c9ccd1a7136bb6fb96682ca983666ca2 100644 (file)
@@ -1,3 +1,21 @@
+export function value_ace_low(rank) {
+    switch (rank) {
+        case "Ace": return 1;
+        case "Two": return 2;
+        case "Three": return 3;
+        case "Four": return 4;
+        case "Five": return 5;
+        case "Six": return 6;
+        case "Seven": return 7;
+        case "Eight": return 8;
+        case "Nine": return 9;
+        case "Ten": return 10;
+        case "Jack": return 10;
+        case "Queen": return 10;
+        case "King": return 10;
+    }
+}
+
 export function short_rank(rank) {
     switch (rank) {
         case "Ace": return "A";
index ea84c5cbc570b139c32b735a763d6c9c316074bd..004abf4b638ca7c88fc6ef568ab7d3d2f6fa5e2a 100644 (file)
@@ -1,6 +1,7 @@
 import { create_svg_element } from "./svg.js";
-import { card_href } from "./card.js";
+import { card_href, value_ace_low } from "./card.js";
 import { GameWithChat } from "./gamechat.js";
+import { break_lines } from "./words.js";
 import { CongratulateWinner } from "./winner.js";
 
 export class Cribbage extends GameWithChat {
@@ -11,6 +12,8 @@ export class Cribbage extends GameWithChat {
         this.user_icons = new Map();
         this.hands = new Map();
         this.played = new Map();
+        this.passed = new Set();
+        this.count = 0;
         this.scores = new Map();
         this.community = [];
         this.box = [];
@@ -32,9 +35,17 @@ export class Cribbage extends GameWithChat {
         this.take_initial_actions(actions);
     }
 
+    able_to_pass(username) {
+        return this.active === this.username &&
+            this.community.length !== 0 &&
+            this.hands.has(this.username) &&
+            this.hands.get(this.username).length !== 0 &&
+            this.hands.get(this.username).every(card => card.card !== null && this.count + value_ace_low(card.card.rank) > 31);
+    }
+
     redraw_players() {
         const active_player = this.active;
-        this.pass_control.classList.toggle("active", active_player === this.username && this.community.length !== 0 && this.hands.has(this.username) && this.hands.get(this.username).length !== 0);
+        this.pass_control.classList.toggle("active", this.able_to_pass());
         for (const [username, [icon, score, active]] of this.user_icons) {
             if (!this.seats.has(username)) {
                 this.svg.removeChild(icon);
@@ -162,6 +173,16 @@ export class Cribbage extends GameWithChat {
         }
     }
 
+    next_active_player(username) {
+        console.log('Finding player after', username);
+        let active = username;
+        do {
+            active = this.player_after(active);
+            console.log('.. got ', active);
+        } while (active !== username && (this.passed.has(active) || this.hands.has(active) && this.hands.get(active).length === 0));
+        return active;
+    }
+
     take_action(user_action) {
         super.take_action(user_action);
         switch (user_action.action.action) {
@@ -185,6 +206,7 @@ export class Cribbage extends GameWithChat {
                 for (const card of this.box) {
                     this.svg.removeChild(card.image);
                 }
+                this.count = 0;
                 this.community = [];
                 this.box = [];
                 for (const [username, hand] of this.hands) {
@@ -193,6 +215,8 @@ export class Cribbage extends GameWithChat {
                     }
                 }
                 this.hands.clear();
+                this.played.clear();
+                this.passed.clear();
                 this.active = this.player_after(user_action.username);
                 this.redraw_players();
                 break;
@@ -211,7 +235,8 @@ export class Cribbage extends GameWithChat {
                 if (!this.scores.has(user_action.username)) {
                     this.scores.set(user_action.username, 0);
                 }
-                this.set_info_text(user_action.username + " scores " + user_action.action.points + ": " + user_action.action.reason);
+                const info_text = user_action.username + " scores " + user_action.action.points + ": " + user_action.action.reason;
+                this.set_info_text(break_lines(info_text, 65));
                 this.scores.set(user_action.username, this.scores.get(user_action.username) + user_action.action.points);
                 if ([...this.hands.values()].every(hand => hand.length === 0)) {
                     this.hands = this.played;
@@ -228,6 +253,11 @@ export class Cribbage extends GameWithChat {
                 this.redraw_players();
                 break;
             case "PlayCard":
+                this.count += value_ace_low(user_action.action.card.rank);
+                if (this.count === 31) {
+                    this.passed.clear();
+                    this.count = 0;
+                }
                 const played = this.remove_card(user_action.username, user_action.action.card);
                 if (played !== undefined) {
                     this.svg.removeChild(played.image);
@@ -239,12 +269,17 @@ export class Cribbage extends GameWithChat {
                         image:this.card_image(user_action.username, user_action.action.card),
                     });
                 }
-                /* fallthrough */
+                this.active = this.next_active_player(user_action.username);
+                this.redraw_cards();
+                this.redraw_players();
+                break;
             case "Pass":
-                this.active = user_action.username;
-                do {
-                    this.active = this.player_after(this.active);
-                } while (this.active !== user_action.username && this.hands.has(this.active) && this.hands.get(this.active).length === 0);
+                this.passed.add(user_action.username);
+                if (this.passed.size === this.hands.size) {
+                    this.count = 0;
+                    this.passed.clear();
+                }
+                this.active = this.next_active_player(user_action.username);
                 this.redraw_cards();
                 this.redraw_players();
                 break;
index 95d03fa99ade1f7972094173c2f1ed280c66460c..54ab0e47bb1f7d185fac0669982f6777443f3eb0 100644 (file)
@@ -61,3 +61,21 @@ const nouns = [
 export function random_title() {
     return adjectives[random_int(26)] + " " + nouns[random_int(26)];
 }
+
+export function break_lines(text, line_length) {
+    const lines = [];
+    let sep = "";
+    let str = "";
+    for (const word of text.split(" ")) {
+        if (str.length > 0 && str.length + sep.length + word.length > line_length) {
+            lines.push(str);
+            sep = str = "";
+        }
+        str += sep + word;
+        sep = " ";
+    }
+    if (str.length > 0) {
+        lines.push(str);
+    }
+    return lines.join("\n");
+}