From: Geoffrey Allott Date: Sat, 20 May 2023 19:50:05 +0000 (+0100) Subject: break out bet controls into a separate class X-Git-Url: https://git.pointlesshacks.com/?a=commitdiff_plain;h=a6a1139a3505ac31f7506fce72b8c537cadf1900;p=pokerwave.git break out bet controls into a separate class --- diff --git a/site/modules/poker.js b/site/modules/poker.js index b83354e..f3058f1 100644 --- a/site/modules/poker.js +++ b/site/modules/poker.js @@ -4,6 +4,106 @@ import { card_href, suit_href } from "./card.js"; import { Chatroom } from "./chatroom.js"; import { CongratulateWinner } from "./winner.js"; +function set_element_attributes(element, attributes) { + for (const [attr, value] of attributes) { + element.setAttribute(attr, value); + } +} + +function create_svg_element(svg, name, class_list, attributes) { + const element = document.createElementNS(svgns, name); + set_element_attributes(element, attributes); + for (const cls of class_list) { + element.classList.add(cls); + } + svg.append(element); + return element; +} + +export class BetControls { + constructor(game) { + this.game = game + this.mouse_clicked = false; + document.addEventListener("mousedown", () => this.mouse_clicked = true); + document.addEventListener("mouseup", () => this.mouse_clicked = false); + + this.background = create_svg_element(this.game.svg, "rect", ["controls"], [["x", "310"], ["y", "410"], ["width", "185"], ["height", "85"], ["rx", "15"]]) + this.bet_size_area = create_svg_element(this.game.svg, "rect", ["bet-size-area"], [["x", "317"], ["y", "417"], ["width", "38"], ["height", "16"]]) + this.bet_size_area.onclick = () => { + const chips = prompt("Chips to bet", this.bet_size_text.textContent); + if (chips !== null && !isNaN(Number(chips))) { + const bet = Math.max(this.game.min_bet(), Math.min(this.game.all_in_bet(), Number(chips))); + this.bet_size_text.textContent = Number(chips); + const p = (bet - this.game.min_bet()) / (this.game.all_in_bet() - this.game.min_bet()); + const x = Math.max(360, Math.min(475, Math.sqrt(p) * 115 + 360)); + this.bet_slider_thumb.setAttribute("x", x); + } + }; + + this.bet_size = create_svg_element(this.game.svg, "text", ["bet-size"], [["x", "336"], ["y", "429"]]) + this.bet_size_text = document.createTextNode("150"); + this.bet_size.append(this.bet_size_text); + + const point = this.game.svg.createSVGPoint(); + const move_slider = e => { + point.x = e.clientX; + point.y = e.clientY; + const coords = point.matrixTransform(this.game.svg.getScreenCTM().inverse()); + const x = Math.max(360, Math.min(475, coords.x - 5)); + const p = Math.pow((x - 360) / 115, 2); + const bet = Math.round(this.game.min_bet() * (1 - p) + this.game.all_in_bet() * p); + this.bet_size_text.textContent = bet; + this.bet_slider_thumb.setAttribute("x", x); + }; + + this.bet_slider = create_svg_element(this.game.svg, "g", ["bet-slider"], []); + this.bet_slider_area = create_svg_element(this.bet_slider, "rect", ["bet-slider-area"], [["x", "360"], ["y", "417"], ["width", "125"], ["height", "16"]]) + this.bet_slider_track = create_svg_element(this.bet_slider, "rect", ["bet-slider-track"], [["x", "360"], ["y", "422"], ["width", "125"], ["height", "6"]]) + this.bet_slider_thumb = create_svg_element(this.bet_slider, "rect", ["bet-slider-thumb"], [["x", "360"], ["y", "419"], ["width", "10"], ["height", "12"]]) + this.bet_slider_area.onmousedown = this.bet_slider_track.onmousedown = this.bet_slider_thumb.onmousedown = move_slider; + this.bet_slider_area.onmousemove = this.bet_slider_track.onmousemove = this.bet_slider_thumb.onmousemove = e => { if (this.mouse_clicked) move_slider(e); }; + this.bet_slider_area.ontouchmove = this.bet_slider_track.ontouchmove = this.bet_slider_thumb.ontouchmove = e => move_slider(e.touches.item(0)); + + this.fold_control = create_svg_element(this.game.svg, "rect", ["fold-control"], [["x", "315"], ["y", "440"], ["width", "55"], ["height", "50"], ["rx", "10"]]) + this.fold_control.onclick = () => this.game.send({type: "TakeAction", action: {action: "Fold"}}); + + this.fold_control_label = create_svg_element(this.game.svg, "text", ["fold-control-label"], [["x", "342.5"], ["y", "470"]]) + this.fold_control_text = document.createTextNode("Fold"); + this.fold_control_label.append(this.fold_control_text); + + this.call_control = create_svg_element(this.game.svg, "rect", ["call-control"], [["x", "375"], ["y", "440"], ["width", "55"], ["height", "50"], ["rx", "10"]]) + this.call_control.onclick = () => this.game.send({type: "TakeAction", action: {action: "Bet", chips: this.game.chips_to_call()}}); + + this.call_control_label = create_svg_element(this.game.svg, "text", ["call-control-label"], [["x", "402.5"], ["y", "470"]]); + this.call_control_text = document.createTextNode("Call"); + this.call_control_label.append(this.call_control_text); + + this.bet_control = create_svg_element(this.game.svg, "rect", ["bet-control"], [["x", "435"], ["y", "440"], ["width", "55"], ["height", "50"], ["rx", "10"]]) + this.bet_control.onclick = () => { + const chips = +this.bet_size_text.textContent; + if (chips !== null && !isNaN(Number(chips))) { + game.send({type: "TakeAction", action: {action: "Bet", chips: Number(chips)}}); + } + } + + this.bet_control_label = create_svg_element(this.game.svg, "text", ["bet-control-label"], [["x", "462.5"], ["y", "470"]]) + this.bet_control_text = document.createTextNode("Bet"); + this.bet_control_label.append(this.bet_control_text); + } + + redraw() { + this.fold_control.classList.toggle("active", this.game.active === this.game.username && this.game.chips_to_call() > 0); + this.call_control.classList.toggle("active", this.game.active === this.game.username); + this.call_control_text.textContent = this.game.active === this.game.username && this.game.chips_to_call() == 0 ? "Check" : "Call"; + const can_bet = this.game.active === this.game.username && this.game.chips_to_call() < this.game.all_in_bet(); + this.bet_control.classList.toggle("active", can_bet); + this.bet_size_area.classList.toggle("active", can_bet); + this.bet_slider.classList.toggle("active", can_bet); + this.bet_size_text.textContent = this.game.min_bet(); + this.bet_slider_thumb.setAttribute("x", 360); + } +}; + export class TexasHoldEm { constructor(container, summary, actions, username, send, close) { this.container = container; @@ -23,10 +123,6 @@ export class TexasHoldEm { this.big_blind = this.small_blind * 2; this.error_text_timeout = null; - this.mouse_clicked = false; - document.addEventListener("mousedown", () => this.mouse_clicked = true); - document.addEventListener("mouseup", () => this.mouse_clicked = false); - this.svg = document.createElementNS(svgns, "svg"); this.svg.classList.add("texas-hold-em"); this.svg.setAttribute("viewBox", "0 0 500 500"); @@ -80,149 +176,7 @@ export class TexasHoldEm { pot_size.append(this.pot_size_text); this.svg.append(pot_size); - const controls = document.createElementNS(svgns, "rect"); - controls.setAttribute("x", "310"); - controls.setAttribute("y", "410"); - controls.setAttribute("width", "185"); - controls.setAttribute("height", "85"); - controls.setAttribute("rx", "15"); - controls.classList.add("controls"); - this.svg.append(controls); - - this.bet_size_area = document.createElementNS(svgns, "rect"); - this.bet_size_area.setAttribute("x", "317"); - this.bet_size_area.setAttribute("y", "417"); - this.bet_size_area.setAttribute("width", "38"); - this.bet_size_area.setAttribute("height", "16"); - this.bet_size_area.classList.add("bet-size-area"); - this.bet_size_area.onclick = () => { - const chips = prompt("Chips to bet", this.bet_size_text.textContent); - if (chips !== null && !isNaN(Number(chips))) { - const bet = Math.max(this.min_bet(), Math.min(this.all_in_bet(), Number(chips))); - this.bet_size_text.textContent = Number(chips); - const p = (bet - this.min_bet()) / (this.all_in_bet() - this.min_bet()); - const x = Math.max(360, Math.min(475, Math.sqrt(p) * 115 + 360)); - this.bet_slider_thumb.setAttribute("x", x); - } - }; - this.svg.append(this.bet_size_area); - - this.bet_size = document.createElementNS(svgns, "text"); - this.bet_size.setAttribute("x", "336"); - this.bet_size.setAttribute("y", "429"); - this.bet_size.classList.add("bet-size"); - this.bet_size_text = document.createTextNode("150"); - this.bet_size.append(this.bet_size_text); - this.svg.append(this.bet_size); - - const move_slider = e => { - point.x = e.clientX; - point.y = e.clientY; - const coords = point.matrixTransform(this.svg.getScreenCTM().inverse()); - const x = Math.max(360, Math.min(475, coords.x - 5)); - const p = Math.pow((x - 360) / 115, 2); - const bet = Math.round(this.min_bet() * (1 - p) + this.all_in_bet() * p); - this.bet_size_text.textContent = bet; - this.bet_slider_thumb.setAttribute("x", x); - }; - - this.bet_slider = document.createElementNS(svgns, "g"); - this.bet_slider.classList.add("bet-slider"); - - this.bet_slider_area = document.createElementNS(svgns, "rect"); - this.bet_slider_area.setAttribute("x", "360"); - this.bet_slider_area.setAttribute("y", "417"); - this.bet_slider_area.setAttribute("width", "125"); - this.bet_slider_area.setAttribute("height", "16"); - this.bet_slider_area.onmousedown = move_slider; - this.bet_slider_area.onmousemove = e => { if (this.mouse_clicked) move_slider(e); }; - this.bet_slider_area.ontouchmove = e => move_slider(e.touches.item(0)); - this.bet_slider_area.classList.add("bet-slider-area"); - this.bet_slider.append(this.bet_slider_area); - - this.bet_slider_track = document.createElementNS(svgns, "rect"); - this.bet_slider_track.setAttribute("x", "360"); - this.bet_slider_track.setAttribute("y", "422"); - this.bet_slider_track.setAttribute("width", "125"); - this.bet_slider_track.setAttribute("height", "6"); - this.bet_slider_track.classList.add("bet-slider-track"); - const point = this.svg.createSVGPoint(); - this.bet_slider_track.onmousedown = move_slider; - this.bet_slider_track.onmousemove = e => { if (this.mouse_clicked) move_slider(e); }; - this.bet_slider_track.ontouchmove = e => move_slider(e.touches.item(0)); - this.bet_slider.append(this.bet_slider_track); - - this.bet_slider_thumb = document.createElementNS(svgns, "rect"); - this.bet_slider_thumb.setAttribute("x", "360"); - this.bet_slider_thumb.setAttribute("y", "419"); - this.bet_slider_thumb.setAttribute("width", "10"); - this.bet_slider_thumb.setAttribute("height", "12"); - this.bet_slider_thumb.classList.add("bet-slider-thumb"); - this.bet_slider_thumb.onmousedown = move_slider; - this.bet_slider_thumb.onmousemove = e => { if (this.mouse_clicked) move_slider(e); }; - this.bet_slider_thumb.ontouchmove = e => move_slider(e.touches.item(0)); - this.bet_slider.append(this.bet_slider_thumb); - - this.svg.append(this.bet_slider); - - this.fold_control = document.createElementNS(svgns, "rect"); - this.fold_control.setAttribute("x", "315"); - this.fold_control.setAttribute("y", "440"); - this.fold_control.setAttribute("width", "55"); - this.fold_control.setAttribute("height", "50"); - this.fold_control.setAttribute("rx", "10"); - this.fold_control.onclick = () => this.send({type: "TakeAction", action: {action: "Fold"}}); - this.fold_control.classList.add("fold-control"); - this.svg.append(this.fold_control); - - const fold_control_label = document.createElementNS(svgns, "text"); - const fold_control_text = document.createTextNode("Fold"); - fold_control_label.append(fold_control_text); - fold_control_label.setAttribute("x", "342.5"); - fold_control_label.setAttribute("y", "470"); - fold_control_label.classList.add("fold-control-label"); - this.svg.append(fold_control_label); - - this.call_control = document.createElementNS(svgns, "rect"); - this.call_control.setAttribute("x", "375"); - this.call_control.setAttribute("y", "440"); - this.call_control.setAttribute("width", "55"); - this.call_control.setAttribute("height", "50"); - this.call_control.setAttribute("rx", "10"); - this.call_control.onclick = () => this.send({type: "TakeAction", action: {action: "Bet", chips: this.chips_to_call()}}); - this.call_control.classList.add("call-control"); - this.svg.append(this.call_control); - - const call_control_label = document.createElementNS(svgns, "text"); - this.call_control_text = document.createTextNode("Call"); - call_control_label.append(this.call_control_text); - call_control_label.setAttribute("x", "402.5"); - call_control_label.setAttribute("y", "470"); - call_control_label.classList.add("call-control-label"); - this.svg.append(call_control_label); - - this.bet_control = document.createElementNS(svgns, "rect"); - this.bet_control.setAttribute("x", "435"); - this.bet_control.setAttribute("y", "440"); - this.bet_control.setAttribute("width", "55"); - this.bet_control.setAttribute("height", "50"); - this.bet_control.setAttribute("rx", "10"); - this.bet_control.onclick = () => { - const chips = +this.bet_size_text.textContent; - if (chips !== null && !isNaN(Number(chips))) { - this.send({type: "TakeAction", action: {action: "Bet", chips: Number(chips)}}); - } - } - this.bet_control.classList.add("bet-control"); - this.svg.append(this.bet_control); - - const bet_control_label = document.createElementNS(svgns, "text"); - const bet_control_text = document.createTextNode("Bet"); - bet_control_label.append(bet_control_text); - bet_control_label.setAttribute("x", "462.5"); - bet_control_label.setAttribute("y", "470"); - bet_control_label.classList.add("bet-control-label"); - this.svg.append(bet_control_label); + this.bet_controls = new BetControls(this) this.close_control = document.createElementNS(svgns, "rect"); this.close_control.setAttribute("x", "460"); @@ -323,15 +277,7 @@ export class TexasHoldEm { } redraw_players() { - this.fold_control.classList.toggle("active", this.active === this.username && this.chips_to_call() > 0); - this.call_control.classList.toggle("active", this.active === this.username); - this.call_control_text.textContent = this.active === this.username && this.chips_to_call() == 0 ? "Check" : "Call"; - const can_bet = this.active === this.username && this.chips_to_call() < this.all_in_bet(); - this.bet_control.classList.toggle("active", can_bet); - this.bet_size_area.classList.toggle("active", can_bet); - this.bet_slider.classList.toggle("active", can_bet); - this.bet_size_text.textContent = this.min_bet(); - this.bet_slider_thumb.setAttribute("x", 360); + this.bet_controls.redraw() this.pot_size_text.textContent = this.pot || ""; for (const [username, [user, stack, active, bet]] of this.user_icons) { if (!this.seats.has(username)) {