From b4ab10cf2100e82b4e6bcb99a6b0369770f83158 Mon Sep 17 00:00:00 2001 From: Andy Olsen Date: Tue, 13 Feb 2024 12:43:14 -0600 Subject: [PATCH] update killer mortal --- mahjong/killer_mortal/index.html | 10 +- mahjong/killer_mortal/index.js | 158 ++++++++++++++++++++----------- mahjong/killer_mortal/style.css | 42 ++++---- 3 files changed, 133 insertions(+), 77 deletions(-) diff --git a/mahjong/killer_mortal/index.html b/mahjong/killer_mortal/index.html index cbf7ecc..e6b2591 100644 --- a/mahjong/killer_mortal/index.html +++ b/mahjong/killer_mortal/index.html @@ -37,10 +37,10 @@

Killer Mortal Reviewer

- - - - + + + + -
-
diff --git a/mahjong/killer_mortal/index.js b/mahjong/killer_mortal/index.js index 918fb46..0e48fa7 100644 --- a/mahjong/killer_mortal/index.js +++ b/mahjong/killer_mortal/index.js @@ -1,3 +1,4 @@ +"use strict"; /* Source: https://mjai.ekyu.moe/report/ac7f456533f7d814.html#kyoku-2-0 Also saved in mahjong_mortal_ui/example_logs/Example_mjai_report.html @@ -141,7 +142,8 @@ class GlobalState { this.C_db_tileWidth = 34 this.C_db_heroBarWidth = 20 this.C_db_mortBarWidth = 10 - this.C_cb_height = 60 + this.C_cb_heroBarHeight = 60 + this.C_cb_mortBarHeightRatio = 0.9 this.C_cb_totHeight = 100 this.C_cb_totWidth = 100 this.C_cb_padding = 10 @@ -172,17 +174,19 @@ class UI { this.hands = [] this.discards = [] this.pInfo = [] + this.pInfoResult = [] this.gridInfo = document.querySelector('.grid-info') this.povPidx = 0 for (let pnum of Array(4).keys()) { this.hands.push(document.querySelector(`.grid-hand-p${pnum}`)) this.discards.push(document.querySelector(`.grid-discard-p${pnum}`)) this.pInfo.push(document.querySelector(`.gi-p${pnum}`)) + this.pInfoResult.push(document.querySelector(`.gi-p${pnum}-result`)) } this.round = document.querySelector('.info-round') this.prevRoundSticks = document.querySelector('.info-sticks') this.doras = document.querySelector('.info-doras') - this.result = document.querySelector('.result') + // this.result = document.querySelector('.result') this.infoRoundModal = document.querySelector('.info-round-modal') this.infoRoundTable = document.querySelector('.info-round-table') } @@ -201,6 +205,8 @@ class UI { return str } reset() { + let currGeList = GS.ge[GS.hand_counter] + let result = currGeList.slice(-1)[0] this.round.replaceChildren(GS.C_windStr[GS.gl.roundWind-41]) this.round.append("-", GS.gl.roundNum+1) if (GS.gl.honbas > 0) { @@ -211,19 +217,35 @@ class UI { } this.prevRoundSticks.replaceChildren() this.doras.replaceChildren() - this.result.replaceChildren() for (let pidx=0; pidx<4; pidx++) { - this.discards[pidx].replaceChildren() let pidxObj = new PIDX(pidx) + this.discards[pidxObj.pov()].replaceChildren() let seatWind = (4 + pidx - GS.gl.roundNum) % 4 this.pInfo[pidxObj.pov()].replaceChildren(GS.C_windStr[seatWind]) - this.pInfo[pidxObj.pov()].append(' ', GS.gl.scores[pidx]-GS.gl.thisRoundSticks[pidx]*1000) + if (GS.gl.handOver) { + this.pInfo[pidxObj.pov()].append(' ', GS.gl.scores[pidx]+result.scoreChangesPlusSticks[pidx]) + } else { + this.pInfo[pidxObj.pov()].append(' ', GS.gl.scores[pidx]-GS.gl.thisRoundSticks[pidx]*1000) + } + this.pInfoResult[pidxObj.pov()].replaceChildren() + if (GS.gl.handOver) { + this.pInfoResult[pidxObj.pov()].append(this.formatString(result.scoreChangesPlusSticks[pidx], false, true)) + } else if (GS.gl.thisRoundSticks[pidx]) { + this.pInfoResult[pidxObj.pov()].append(this.formatString(-GS.gl.thisRoundSticks[pidx]*1000, false, true)) + } } } + formatString(num, showZero, addPlus) { + if (!showZero && num == 0) { + return '' + } + let s = (addPlus && num>0) ? '+' : '' + s += num + return s + } #relativeToHeroStr(pidx) { let relIdx = pidx<4 ? (4 + GS.heroPidx - pidx) % 4 : pidx return ['Hero', 'Kami', 'Toimen', 'Shimo', 'Pot'][relIdx] - // return ['Self', 'Left', 'Cross', 'Right'][relIdx] } updateGridInfo() { this.clearDiscardBars() @@ -246,6 +268,7 @@ class UI { } this.doras.lastChild.setAttribute('width', 20) } + /* if (GS.gl.handOver) { if (GS.gl.result == '和了') { if (GS.gl.winner == GS.gl.payer) { @@ -276,6 +299,7 @@ class UI { } else { this.result.append('(Result hidden)') } + */ } clearCallBars() { const callBars = document.querySelector('.killer-call-bars') @@ -298,11 +322,11 @@ class UI { let xloc = GS.C_db_handPadding + GS.C_db_tileWidth/2 + slot*GS.C_db_tileWidth if (key == mortalEval.p_action) { svgElement.appendChild(this.createRect( - xloc-GS.C_db_heroBarWidth/2, 0, GS.C_db_heroBarWidth, 1*GS.C_cb_height, GS.C_colorBarHero + xloc-GS.C_db_heroBarWidth/2, GS.C_db_heroBarWidth, GS.C_cb_heroBarHeight, 1, GS.C_colorBarHero )) } svgElement.appendChild(this.createRect( - xloc-GS.C_db_mortBarWidth/2, (1-Pval/100)*GS.C_cb_height, GS.C_db_mortBarWidth, Pval/100*GS.C_cb_height, GS.C_colorBarMortal + xloc-GS.C_db_mortBarWidth/2, GS.C_db_mortBarWidth, GS.C_cb_heroBarHeight, Pval/100*GS.C_cb_mortBarHeightRatio, GS.C_colorBarMortal )); let text = document.createElementNS("http://www.w3.org/2000/svg", "text") text.setAttribute("x", xloc-GS.C_db_mortBarWidth/2-10) @@ -315,18 +339,19 @@ class UI { } clearDiscardBars() { const discardBars = document.getElementById("discard-bars") - let svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg") + const svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg") svgElement.setAttribute("width", GS.C_db_totWidth) svgElement.setAttribute("height", GS.C_db_height) svgElement.setAttribute("padding", GS.C_db_padding) discardBars.replaceChildren(svgElement) } - createRect(x, y, width, height, fill) { + createRect(x, width, totHeight, fillRatio, fill) { + let y = (1-fillRatio)*totHeight let rect = document.createElementNS("http://www.w3.org/2000/svg", "rect") rect.setAttribute("x", x) rect.setAttribute("y", y) rect.setAttribute("width", width) - rect.setAttribute("height", height) + rect.setAttribute("height", totHeight*fillRatio) rect.setAttribute("fill", fill) return rect } @@ -358,11 +383,11 @@ class UI { if (tile == mortalEval.p_action) { heroSlotFound = true svgElement.appendChild(this.createRect( - xloc-GS.C_db_heroBarWidth/2, 0, GS.C_db_heroBarWidth, 1*GS.C_db_height, GS.C_colorBarHero + xloc-GS.C_db_heroBarWidth/2, GS.C_db_heroBarWidth, GS.C_db_height, 1, GS.C_colorBarHero )) } svgElement.appendChild(this.createRect( - xloc-GS.C_db_mortBarWidth/2, (1-Pval/100)*GS.C_db_height, GS.C_db_mortBarWidth, (Pval/100)*GS.C_db_height, GS.C_colorBarMortal + xloc-GS.C_db_mortBarWidth/2, GS.C_db_mortBarWidth, GS.C_db_height, Pval/100*GS.C_cb_mortBarHeightRatio, GS.C_colorBarMortal )); } if (!heroSlotFound) { @@ -372,26 +397,28 @@ class UI { throw new Error() } } - updateHandInfo(hands, calls, drawnTile) { + updateHandInfo() { + let result = GS.ge[GS.hand_counter].slice(-1)[0] for (let pnum=0; pnum<4; pnum++) { let objPidx = new PIDX(pnum) this.addHandTiles(objPidx, [], true) - for (let tileInt of hands[pnum]) { - if (GS.showHands || pnum==GS.heroPidx) { + for (let tileInt of GS.gl.hands[pnum]) { + // TODO: Draw and all tenpai could show the hands also? + if (GS.showHands || (GS.gl.handOver && GS.gl.scoreChanges[pnum]>0) || pnum==GS.heroPidx) { this.addHandTiles(objPidx, [tenhou2str(tileInt)], false) } else { this.addHandTiles(objPidx, ['back'], false) } } this.addBlankSpace(objPidx) - if (drawnTile[pnum] != null) { - this.addHandTiles(objPidx, [tenhou2str(drawnTile[pnum])], false) + if (GS.gl.drawnTile[pnum] != null) { + this.addHandTiles(objPidx, [tenhou2str(GS.gl.drawnTile[pnum])], false) } else { this.addBlankSpace(objPidx) } - if (calls[pnum].length > 0) { + if (GS.gl.calls[pnum].length > 0) { this.addBlankSpace(objPidx) - for (let tileInt of calls[pnum]) { + for (let tileInt of GS.gl.calls[pnum]) { if (tileInt == 'rotate') { this.rotateLastTile(objPidx, 'hand') } else if (tileInt == 'float') { @@ -458,6 +485,7 @@ class UI { this.#getHand(pidx).lastChild.style.opacity = "0" } updateDiscardPond() { + let event = GS.ge[GS.hand_counter][GS.ply_counter] for (let pidx=0; pidx<4; pidx++) { let pidxObj = new PIDX(pidx) for (let tile of GS.gl.discardPond[pidx]) { @@ -466,6 +494,11 @@ class UI { this.lastDiscardWasCalled(pidxObj) } } + if (event.type=='discard' && pidx==event.pidx) { + console.log('hi', event) + // this.#getDiscard(pidxObj).lastChild.style.transform += ' translate(30px,30px)' + // console.log(this.#getDiscard(pidxObj).lastChild) + } } } addDiscard(pidx, tileStrArray, tsumogiri, riichi) { @@ -514,9 +547,17 @@ class UI { for (let pidx=0; pidx<4+1; pidx++) { cell = tr.insertCell() cell.textContent = `${result.scoreChangesPlusSticks[pidx]}` + if (result.scoreChangesPlusSticks[pidx] < -7000) { + cell.classList.add('big-loss') + } else if (result.scoreChangesPlusSticks[pidx] < 0) { + cell.classList.add('small-loss') + } } hand_counter++ } + this.infoRoundModal.addEventListener('click', (event) => { + this.infoRoundModal.close() + }) } } @@ -561,7 +602,7 @@ function tm2t(str) { if (isNaN(num)) { // Pai=White Fa=Green Chun=Red const yakuhai = { 'e': 41, 's': 42, 'w': 43, 'n': 44, 'p':45, 'f':46, 'c': 47} - tile = yakuhai[str[0]] + let tile = yakuhai[str[0]] if (tile == null) { throw new Error(`Could not parse ${str}`) } @@ -577,10 +618,10 @@ function tenhou2str(tileInt) { const akacon = { 51:'0m', 52:'0p', 53:'0s'} return akacon[tileInt] } - suitInt = Math.floor(tileInt / 10) + let suitInt = Math.floor(tileInt / 10) tileInt = tileInt % 10 const tcon = ['m', 'p', 's', 'z'] - output = tileInt.toString() + tcon[suitInt-1] + let output = tileInt.toString() + tcon[suitInt-1] return output } @@ -705,20 +746,21 @@ function updateState() { if (event.draw.type == 'm') { GS.gl.thisRoundExtraDoras++ // openkan } - let allMeldedTiles = [event.draw.newTile].concat(event.draw.meldedTiles) + GS.gl.hands[event.pidx].push(event.draw.newTile) + let allMeldedTiles = event.draw.meldedTiles + let newCall = [] for (let i=0; i0) { - removeFromArray(GS.gl.hands[event.pidx], allMeldedTiles[i]) - } - GS.gl.calls[event.pidx].push(allMeldedTiles[i]) + removeFromArray(GS.gl.hands[event.pidx], allMeldedTiles[i]) + newCall.push(allMeldedTiles[i]) if (event.draw.fromIdxRel == i) { - GS.gl.calls[event.pidx].push('rotate') + newCall.push('rotate') } if (event.draw.type == 'm' && event.draw.fromIdxRel+1 == i) { - GS.gl.calls[event.pidx].push('rotate') - GS.gl.calls[event.pidx].push('float') + newCall.push('rotate') + newCall.push('float') } } + GS.gl.calls[event.pidx] = newCall.concat(GS.gl.calls[event.pidx]) } else if (event.type == 'kakan') { // kakan = added kan console.assert(event.kanTile.meldedTiles.length==1) @@ -746,18 +788,20 @@ function updateState() { GS.gl.hands[event.pidx].push(GS.gl.drawnTile[event.pidx]) GS.gl.hands[event.pidx].sort(tileSort) GS.gl.drawnTile[event.pidx] = null + let newCall = [] for (let i=0; i img { transform: rotate(90deg); @@ -227,8 +231,7 @@ h1{ .controls { display:grid; grid-template-columns: repeat(2, 120px); - margin:auto; - margin-top:10px; + margin:10px auto; width:240px; padding:10px; background:var(--color-accent); @@ -257,13 +260,20 @@ h1{ .info-round-modal::backdrop { background: rgb(0 0 0 / .3); } +.big-loss { + background: rgb(0 0 0 / .6); +} +.small-loss { + background: rgb(0 0 0 / .3); +} .info-round-table table, th, td { text-align: right; border: 1px solid var(--color-text); border-collapse: collapse; padding: 0.4rem; + background: var(--color-accent); } -.info-round-table tr:hover { +.info-round-table tr:hover td { background:rgba(0, 0, 0, 0.7); } .info-round-close { @@ -289,7 +299,7 @@ button:hover { width: 110px; height: 90px; background: var(--color-accent3); - padding: 5px; + padding: 10px; margin: auto; } .killer-call-img {