diff --git a/__test__/components/Pref.test.tsx b/__test__/components/Pref.test.tsx index 48a4801..6f16df5 100644 --- a/__test__/components/Pref.test.tsx +++ b/__test__/components/Pref.test.tsx @@ -96,8 +96,8 @@ it('renders Pref', () => { target: { value: '4b0e835d-002f-4478-8d89-e384f19cd999' }, }) const buttonConnect = screen.find('div.multiplayer button') - expect(buttonConnect.length).toBe(1) - buttonConnect.simulate('click') + expect(buttonConnect.length).toBe(2) + buttonConnect.at(0).simulate('click') const buttonsResetApply = screen.find('div.button-wrapper button') expect(buttonsResetApply.length > 0).toBeTruthy() buttonsResetApply.forEach((button) => { diff --git a/src/components/TableP.tsx b/src/components/TableP.tsx index 9b87d85..8946b56 100644 --- a/src/components/TableP.tsx +++ b/src/components/TableP.tsx @@ -23,6 +23,11 @@ const TableP = () => { const cardsInHand = useAppSelector((state) => state.settings.cardsInHand) const discardMode = useAppSelector((state) => state.game.discardMode) + const playersTurn = useAppSelector((state) => state.game.playersTurn) + const locked = useAppSelector((state) => state.game.locked).some( + (l) => l === true, + ) + const size = useContext(GameSizeContext) const winHeight = size.height const winWidth = size.width @@ -56,8 +61,11 @@ const TableP = () => { winWidth={winWidth} > diff --git a/src/components/screens/EndScreen.tsx b/src/components/screens/EndScreen.tsx index 2343824..629def5 100644 --- a/src/components/screens/EndScreen.tsx +++ b/src/components/screens/EndScreen.tsx @@ -12,6 +12,7 @@ import { CLOSE_SCREEN_END_INIT } from '../../constants/ActionTypes' import useKeyDown from '../../utils/hooks/gamecontrols/useKeyDown' import { endScreenExitableDelay } from '../../constants/visuals' import { EndScreenNoCloseStateType } from '../../types/state' +import { reasonTranslate } from '../../utils/checkVictory' // import { GameSizeContext } from '../../utils/contexts/GameSizeContext' const textMap = { lose: 'You Lose!', tie: 'Tie Game', win: 'You Win!' } @@ -96,8 +97,8 @@ const useStyles = createUseStyles({ notetext: { top: '62%', height: '5em', - 'font-size': '5vh', - 'line-height': '5vh', + 'font-size': '4vh', + 'line-height': '4vh', }, text: { @@ -128,7 +129,7 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => { const _ = useContext(I18nContext) const classes = useStyles(endScreenState) - const { type, surrender } = endScreenState + const { type, surrender, reasons } = endScreenState // const size = useContext(GameSizeContext) @@ -145,7 +146,17 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => { ) let noteText: string | null = null - if (surrender) { + if (reasons) { + const reasonTexts = [ + ...(reasons.win + ? reasons.win.map((reason) => reasonTranslate(reason, true, _)) + : []), + ...(reasons.lose + ? reasons.lose.map((reason) => reasonTranslate(reason, false, _)) + : []), + ] + noteText = reasonTexts.join(_.i18n('. ')) + } else if (surrender) { switch (type) { case 'win': noteText = _.i18n( @@ -252,5 +263,4 @@ const EndScreen = (endScreenState: EndScreenNoCloseStateType) => { ) } - export default memo(EndScreen) diff --git a/src/components/screens/Pref.tsx b/src/components/screens/Pref.tsx index 3664d1e..0eef9ce 100644 --- a/src/components/screens/Pref.tsx +++ b/src/components/screens/Pref.tsx @@ -63,8 +63,9 @@ const Pref = () => { const _ = useContext(I18nContext) const dispatch = useAppDispatch() - const copied = useRef(null) + const yourIdInputRef = useRef(null) const copiedTimer = useRef(null) + const [copied, setCopied] = useState(false) const isMultiplayer = useAppSelector((state) => state.multiplayer.on) const yourId = useAppSelector((state) => state.multiplayer.yourId) @@ -757,6 +758,7 @@ const Pref = () => { {_.i18n(': ')} { target.select() copy(target.value) .then(() => { - if (copied.current !== null) { - copied.current.classList.add('copied-shown') - if (copiedTimer.current !== null) { - clearTimeout(copiedTimer.current) - } - copiedTimer.current = setTimeout(() => { - if (copied.current !== null) { - copied.current.classList.remove('copied-shown') - } - }, copiedDuration) + setCopied(true) + if (copiedTimer.current !== null) { + clearTimeout(copiedTimer.current) } + copiedTimer.current = setTimeout(() => { + setCopied(false) + }, copiedDuration) }) .catch((error) => { console.error('Failed to copy text: ', error) }) - if (copied.current !== null) { - copied.current.classList.add('copied-shown') - if (copiedTimer.current !== null) { - clearTimeout(copiedTimer.current) - } - copiedTimer.current = setTimeout(() => { - if (copied.current !== null) { - copied.current.classList.remove('copied-shown') - } - }, copiedDuration) - } } }} /> - - {_.i18n('Copied 📋✅')} - +
diff --git a/src/epics/game_general/checkSurrenderEpic.ts b/src/epics/game_general/checkSurrenderEpic.ts index 4fd3845..a865f40 100644 --- a/src/epics/game_general/checkSurrenderEpic.ts +++ b/src/epics/game_general/checkSurrenderEpic.ts @@ -36,3 +36,4 @@ export default ( } }), ) +// TODO: fix: multiplayer mode, opponent surrenders, game freezes diff --git a/src/epics/game_general/checkVictoryEpic.ts b/src/epics/game_general/checkVictoryEpic.ts index ff2008d..3acf2ff 100644 --- a/src/epics/game_general/checkVictoryEpic.ts +++ b/src/epics/game_general/checkVictoryEpic.ts @@ -8,9 +8,9 @@ import { withLatestFrom, filter, mergeMap, takeUntil } from 'rxjs/operators' import { isOfType } from 'typesafe-actions' import { ofType, StateObservable } from 'redux-observable' import { RootStateType } from '../../types/state' -import { resNames } from '../../constants/resourceNames' import { EMPTY, Observable, of } from 'rxjs' import { getWinState } from '../../utils/startWinState' +import { checkVictory } from '../../utils/checkVictory' export default ( action$: Observable, @@ -23,31 +23,12 @@ export default ( const { winTower, winResource } = getWinState(state.settings) const { player, opponent } = state.status - const playerWin = - player.tower >= winTower || - opponent.tower <= 0 || - resNames.some((resName) => player[resName] >= winResource) - const opponentWin = - opponent.tower >= winTower || - player.tower <= 0 || - resNames.some((resName) => opponent[resName] >= winResource) + const res = checkVictory(player, opponent, winTower, winResource) - if (playerWin && !opponentWin) { + if (res) { return of({ type: SCREEN_END, - payload: { type: 'win' }, - }).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL)))) - } - if (!playerWin && opponentWin) { - return of({ - type: SCREEN_END, - payload: { type: 'lose' }, - }).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL)))) - } - if (playerWin && opponentWin) { - return of({ - type: SCREEN_END, - payload: { type: 'tie' }, + payload: res, }).pipe(takeUntil(action$.pipe(ofType(ABORT_ALL)))) } diff --git a/src/i18n/main/ar.ts b/src/i18n/main/ar.ts index d72c097..9fd8550 100644 --- a/src/i18n/main/ar.ts +++ b/src/i18n/main/ar.ts @@ -31,6 +31,11 @@ export const i18n = { 'You Win!': 'فزت!', 'You Lose!': 'خسرت!', 'Tie Game': 'لعبة التعادل', + '%s has reached the victory condition': 'لقد وصل %s إلى حالة النصر', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': 'لقد وصل %s إلى حالة النصر', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'لم يتبق لخصمك أي برج', + 'You have no tower left': 'لم يتبق لك أي برج', + '. ': '. ', Preferences: 'التفضيلات', ': ': ':', 'Your Name': 'اسمك', @@ -60,6 +65,7 @@ export const i18n = { 'Your ID': 'معرفك', "Enter your opponent's ID": 'أدخل معرف خصمك', Connect: 'الاتصال', + Copy: 'نسخ', 'Copied 📋✅': 'تم النسخ 📋✅', 'Connecting to the network ⌛': 'الاتصال بالشبكة ⌛', 'Connected to the network (but not to anyone) 🟡': diff --git a/src/i18n/main/cs.ts b/src/i18n/main/cs.ts index 7695380..b775009 100644 --- a/src/i18n/main/cs.ts +++ b/src/i18n/main/cs.ts @@ -44,6 +44,13 @@ export const i18n = { 'You Lose!': 'Prohrál jsi!', 'Tie Game': 'Remízová hra', + '%s has reached the victory condition': '%s dosáhla vítězné podmínky', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s dosáhly vítězné podmínky', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Vašemu protivníkovi nezbyla žádná věž', + 'You have no tower left': 'Nezbyla ti žádná věž', + + '. ': '. ', + Preferences: 'Předvolby', ': ': ': ', 'Your Name': 'Vaše jméno', @@ -80,6 +87,7 @@ export const i18n = { 'Your ID': 'Vaše ID', "Enter your opponent's ID": 'Zadejte ID soupeře', Connect: 'Připojit', + Copy: 'Kopie', 'Copied 📋✅': 'Zkopírováno 📋✅', 'Connecting to the network ⌛': 'Připojení k síti ⌛', diff --git a/src/i18n/main/de.ts b/src/i18n/main/de.ts index 137e13b..c4eb501 100644 --- a/src/i18n/main/de.ts +++ b/src/i18n/main/de.ts @@ -44,6 +44,14 @@ export const i18n = { 'You Lose!': 'Sie verlieren!', 'Tie Game': 'Unentschieden Spiel', + '%s has reached the victory condition': '%s hat die Siegbedingung erreicht', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': + '%s haben die Siegbedingung erreicht', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Ihr Gegner hat keinen Turm mehr', + 'You have no tower left': 'Sie haben keinen Turm mehr', + + '. ': '. ', + Preferences: 'Voreinstellungen', ': ': ': ', 'Your Name': 'Ihr Name', @@ -80,6 +88,7 @@ export const i18n = { 'Your ID': 'Ihre ID', "Enter your opponent's ID": 'Geben Sie die ID Ihres Gegners ein', Connect: 'Verbinden', + Copy: 'Kopieren', 'Copied 📋✅': 'Kopiert 📋✅', 'Connecting to the network ⌛': 'Verbindung zum Netzwerk herstellen ⌛', diff --git a/src/i18n/main/en.ts b/src/i18n/main/en.ts index 0b73426..e59ee06 100644 --- a/src/i18n/main/en.ts +++ b/src/i18n/main/en.ts @@ -44,6 +44,15 @@ export const i18n = { 'You Lose!': 'You Lose!', 'Tie Game': 'Tie Game', + '%s has reached the victory condition': + '%s has reached the victory condition', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': + '%s have reached the victory condition', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Your opponent has no tower left', + 'You have no tower left': 'You have no tower left', + + '. ': '. ', + Preferences: 'Preferences', ': ': ': ', 'Your Name': 'Your Name', @@ -80,6 +89,7 @@ export const i18n = { 'Your ID': 'Your ID', "Enter your opponent's ID": "Enter your opponent's ID", Connect: 'Connect', + Copy: 'Copy', 'Copied 📋✅': 'Copied 📋✅', 'Connecting to the network ⌛': 'Connecting to the network ⌛', diff --git a/src/i18n/main/es.ts b/src/i18n/main/es.ts index 4d6dff8..8cb9bbb 100644 --- a/src/i18n/main/es.ts +++ b/src/i18n/main/es.ts @@ -44,6 +44,15 @@ export const i18n = { 'You Lose!': '¡Tú pierdes!', 'Tie Game': 'Juego empatado', + '%s has reached the victory condition': + '%s ha alcanzado la condición de victoria', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': + '%s han alcanzado la condición de victoria', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'A tu oponente no le quedan torres', + 'You have no tower left': 'A ti no te quedan torres', + + '. ': '. ', + Preferences: 'Preferencias', ': ': ': ', 'Your Name': 'Tu nombre', @@ -80,6 +89,7 @@ export const i18n = { 'Your ID': 'Tu ID', "Enter your opponent's ID": 'Introduce el ID de tu oponente', Connect: 'Conectar', + Copy: 'Copiar', 'Copied 📋✅': 'Copiado 📋✅', 'Connecting to the network ⌛': 'Conectando a la red ⌛', diff --git a/src/i18n/main/fr.ts b/src/i18n/main/fr.ts index 7542b01..eda725e 100644 --- a/src/i18n/main/fr.ts +++ b/src/i18n/main/fr.ts @@ -44,6 +44,15 @@ export const i18n = { 'You Lose!': 'Vous avez perdu', 'Tie Game': 'Match nul', + '%s has reached the victory condition': + '%s a atteint la condition de victoire', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': + '%s ont atteint la condition de victoire', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Votre adversaire n’a plus de tour', + 'You have no tower left': 'Vous n’avez plus de tour', + + '. ': '. ', + Preferences: 'Préférences', ': ': '\u00A0: ', 'Your Name': 'Votre nom', @@ -80,6 +89,7 @@ export const i18n = { 'Your ID': 'Votre ID', "Enter your opponent's ID": 'Entrez l’ID de votre adversaire', Connect: 'Connectez', + Copy: 'Copier', 'Copied 📋✅': 'Copié 📋✅', 'Connecting to the network ⌛': 'Connexion au réseau en cours ⌛', diff --git a/src/i18n/main/it.ts b/src/i18n/main/it.ts index f76ef47..744de44 100644 --- a/src/i18n/main/it.ts +++ b/src/i18n/main/it.ts @@ -44,6 +44,15 @@ export const i18n = { 'You Lose!': 'Tu perdi!', 'Tie Game': 'Gioco del pareggio', + '%s has reached the victory condition': + '%s ha raggiunto la condizione di vittoria', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': + '%s hanno raggiunto la condizione di vittoria', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Il tuo avversario non ha più torri', + 'You have no tower left': 'Tu non hai più torri', + + '. ': '. ', + Preferences: 'Preferenze', ': ': ': ', 'Your Name': 'Il tuo nome', @@ -80,6 +89,7 @@ export const i18n = { 'Your ID': 'Il tuo ID', "Enter your opponent's ID": "Inserisci l'ID del tuo avversario", Connect: 'Collega', + Copy: 'Copia', 'Copied 📋✅': 'Copiato 📋✅', 'Connecting to the network ⌛': 'Connettendo alla rete ⌛', diff --git a/src/i18n/main/ja.ts b/src/i18n/main/ja.ts index ea961aa..91b8fdc 100644 --- a/src/i18n/main/ja.ts +++ b/src/i18n/main/ja.ts @@ -44,6 +44,13 @@ export const i18n = { 'You Lose!': '負け!', 'Tie Game': '引き分け', + '%s has reached the victory condition': '%sは勝利条件に達しました', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%sは勝利条件に達しました', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': '対戦相手にはタワーが残っていません', + 'You have no tower left': 'あなたにはタワーが残っていません', + + '. ': '。', + Preferences: '設定', ': ': ':', 'Your Name': 'あなたの名前', @@ -79,6 +86,7 @@ export const i18n = { 'Your ID': 'あなたのID', "Enter your opponent's ID": '相手のIDを入力する', Connect: '接続', + Copy: 'コピー', 'Copied 📋✅': 'コピー済み 📋✅', 'Connecting to the network ⌛': 'ネットワークに接続する ⌛', diff --git a/src/i18n/main/pl.ts b/src/i18n/main/pl.ts index b137317..7a844a7 100644 --- a/src/i18n/main/pl.ts +++ b/src/i18n/main/pl.ts @@ -44,6 +44,13 @@ export const i18n = { 'You Lose!': 'Przegrałeś', 'Tie Game': 'Remis', + '%s has reached the victory condition': '%s osiągnęła warunek zwycięstwa', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s osiągnęły warunek zwycięstwa', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Twój przeciwnik nie ma już żadnej wieży', + 'You have no tower left': 'Ty nie masz już żadnej wieży', + + '. ': '. ', + Preferences: 'Preferencje', ': ': ': ', 'Your Name': 'Twoje imię', @@ -80,6 +87,7 @@ export const i18n = { 'Your ID': 'Twoje ID', "Enter your opponent's ID": 'Wpisz ID przeciwnika', Connect: 'Połącz', + Copy: 'Kopiuj', 'Copied 📋✅': 'Skopiowane 📋✅', 'Connecting to the network ⌛': 'Łączenie się z siecią ⌛', diff --git a/src/i18n/main/pt-BR.ts b/src/i18n/main/pt-BR.ts index 02cc176..3c4480f 100644 --- a/src/i18n/main/pt-BR.ts +++ b/src/i18n/main/pt-BR.ts @@ -44,6 +44,13 @@ export const i18n = { 'You Lose!': 'Você Perdeu!', 'Tie Game': 'Empate', + '%s has reached the victory condition': '%s atingiu a condição de vitória', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s atingiram a condição de vitória', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'Seu oponente não tem mais nenhuma torre', + 'You have no tower left': 'Você não tem mais nenhuma torre', + + '. ': '. ', + Preferences: 'Preferências', ': ': ': ', 'Your Name': 'Seu Nome', @@ -80,6 +87,7 @@ export const i18n = { 'Your ID': 'Seu ID', "Enter your opponent's ID": 'Insira o ID de seu oponente', Connect: 'Conectar', + Copy: 'Copiar', 'Copied 📋✅': 'Copiado 📋✅', 'Connecting to the network ⌛': 'Conectando à rede ⌛', diff --git a/src/i18n/main/ru.ts b/src/i18n/main/ru.ts index 87e253f..578c947 100644 --- a/src/i18n/main/ru.ts +++ b/src/i18n/main/ru.ts @@ -44,6 +44,14 @@ export const i18n = { 'You Lose!': 'Вы проиграли!', 'Tie Game': 'Ничья!', + '%s has reached the victory condition': '%s достиг победного состояния', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s достигли победного состояния', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': + 'У вашего противника не осталось ни одной башни', + 'You have no tower left': 'У вас не осталось ни одной башни', + + '. ': '. ', + Preferences: 'Настройки', ': ': ': ', 'Your Name': 'Ваше имя', @@ -79,6 +87,7 @@ export const i18n = { 'Your ID': 'Ваш ID', "Enter your opponent's ID": 'Введите ID оппонента', Connect: 'Соединение', + Copy: 'Копировать', 'Copied 📋✅': 'Скопировано 📋✅', 'Connecting to the network ⌛': 'Соединение с сетью ⌛', diff --git a/src/i18n/main/uk.ts b/src/i18n/main/uk.ts index cc86d9e..8ff1d4f 100644 --- a/src/i18n/main/uk.ts +++ b/src/i18n/main/uk.ts @@ -44,6 +44,13 @@ export const i18n = { 'You Lose!': 'Ви програли!', 'Tie Game': 'Нічия!', + '%s has reached the victory condition': '%s досягла умови перемоги', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s досягли умови перемоги', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': 'У вашого супротивника не залишилося вежі', + 'You have no tower left': 'У вас не залишилося вежі', + + '. ': '. ', + Preferences: 'Налаштування', ': ': ': ', 'Your Name': "Ваше ім'я", @@ -79,6 +86,7 @@ export const i18n = { 'Your ID': 'Ваш ID', "Enter your opponent's ID": 'Введіть ID опонента', Connect: "З'єднання", + Copy: 'Копія', 'Copied 📋✅': 'Скопійовано 📋✅', 'Connecting to the network ⌛': "З'єднання з мережею ⌛", diff --git a/src/i18n/main/zh-Hans.ts b/src/i18n/main/zh-Hans.ts index 28e5d58..4b4ee18 100644 --- a/src/i18n/main/zh-Hans.ts +++ b/src/i18n/main/zh-Hans.ts @@ -43,6 +43,13 @@ export const i18n = { 'You Lose!': '你输了!', 'Tie Game': '握手言和', + '%s has reached the victory condition': '%s已达到胜利条件', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s已达到胜利条件', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': '对手城堡已被完全摧毁', + 'You have no tower left': '你的城堡已被完全摧毁', + + '. ': '。', + Preferences: '设置', ': ': ':', 'Your Name': '你的名字', @@ -78,6 +85,7 @@ export const i18n = { 'Your ID': '你的ID', "Enter your opponent's ID": '输入对手ID', Connect: '连接', + Copy: '复制', 'Copied 📋✅': '已复制 📋✅', 'Connecting to the network ⌛': '正在连接到网络 ⌛', diff --git a/src/i18n/main/zh-Hant.ts b/src/i18n/main/zh-Hant.ts index 5407935..bd4deb9 100644 --- a/src/i18n/main/zh-Hant.ts +++ b/src/i18n/main/zh-Hant.ts @@ -43,6 +43,13 @@ export const i18n = { 'You Lose!': '你輸了!', 'Tie Game': '握手言和', + '%s has reached the victory condition': '%s已達到勝利條件', // %s = 'Your tower', "Opponent's tower" + '%s have reached the victory condition': '%s已達到勝利條件', // %s = 'Your bricks', "Opponent's bricks", "Your gems", ... + 'Your opponent has no tower left': '對手塔樓已被完全摧毀', + 'You have no tower left': '你的塔樓已被完全摧毀', + + '. ': '。', + Preferences: '設定', ': ': ':', 'Your Name': '你的名字', @@ -78,6 +85,7 @@ export const i18n = { 'Your ID': '你的ID', "Enter your opponent's ID": '輸入對手ID', Connect: '連線', + Copy: '複製', 'Copied 📋✅': '已複製 📋✅', 'Connecting to the network ⌛': '正在連線到網路 ⌛', diff --git a/src/reducers/screen.ts b/src/reducers/screen.ts index d9616dd..399689b 100644 --- a/src/reducers/screen.ts +++ b/src/reducers/screen.ts @@ -50,6 +50,7 @@ export default produce((draft: ScreenStateType, action: RootActionType) => { case SCREEN_END_MAIN: { draft.end.type = action.payload.type draft.end.surrender = action.payload.surrender + draft.end.reasons = action.payload.reasons break } } diff --git a/src/types/state.ts b/src/types/state.ts index c941162..f4168f3 100644 --- a/src/types/state.ts +++ b/src/types/state.ts @@ -76,14 +76,21 @@ export type SettingsStateType = SettingsType & SettingsStateNameType export type SettingsStateAllPartialType = Partial +export type GameEndReasonsType = { + win?: number[] + lose?: number[] +} + export type EndScreenStateType = { type: 'win' | 'tie' | 'lose' | null // null = close screen surrender?: boolean + reasons?: GameEndReasonsType } export type EndScreenNoCloseStateType = { type: 'win' | 'tie' | 'lose' surrender?: boolean + reasons?: GameEndReasonsType } export const isEndScreenNoCloseState = ( diff --git a/src/utils/checkVictory.ts b/src/utils/checkVictory.ts new file mode 100644 index 0000000..2dbf04b --- /dev/null +++ b/src/utils/checkVictory.ts @@ -0,0 +1,106 @@ +import { resNames } from '../constants/resourceNames' +import { + EndScreenStateType, + GameEndReasonsType, + PersonStatusType, +} from '../types/state' +import { I18nContextType } from '../i18n/types' + +const getTrueIndexes = (arr: boolean[]): number[] => + arr.reduce((acc, value, index) => { + if (value) { + acc.push(index) + } + return acc + }, []) + +export const checkVictory = ( + player: PersonStatusType, + opponent: PersonStatusType, + winTower: number, + winResource: number, +) => { + const winReasons = [ + opponent.tower <= 0, + player.tower >= winTower, + player.bricks >= winResource, + player.gems >= winResource, + player.recruits >= winResource, + ] + const loseReasons = [ + player.tower <= 0, + opponent.tower >= winTower, + opponent.bricks >= winResource, + opponent.gems >= winResource, + opponent.recruits >= winResource, + ] + + const winReasonIndexes = getTrueIndexes(winReasons) + const loseReasonIndexes = getTrueIndexes(loseReasons) + + const reasons: GameEndReasonsType = {} + + if (winReasonIndexes.length > 0) { + reasons.win = winReasonIndexes + } + if (loseReasonIndexes.length > 0) { + reasons.lose = loseReasonIndexes + } + + let type: EndScreenStateType['type'] = null + + if (winReasons.includes(true) && !loseReasons.includes(true)) { + type = 'win' + } else if (!winReasons.includes(true) && loseReasons.includes(true)) { + type = 'lose' + } else if (winReasons.includes(true) && loseReasons.includes(true)) { + type = 'tie' + } + + return type + ? { + type, + reasons, + } + : null +} + +export const reasonTranslate = ( + reasonIndex: number, + isWin: boolean, + _: I18nContextType, +) => { + if (isWin) { + if (reasonIndex === 0) { + return _.i18n('Your opponent has no tower left') + } else if (reasonIndex === 1) { + return _.i18n('%s has reached the victory condition').replace( + '%s', + _.i18n('Your %s').replace('%s', _.i18n('tower')), + ) + } else { + return _.i18n('%s have reached the victory condition').replace( + '%s', + _.i18n('Your %s').replace('%s', _.i18n(resNames[reasonIndex - 2])), + ) + } + } else { + // is lose + if (reasonIndex === 0) { + return _.i18n('You have no tower left') + } else if (reasonIndex === 1) { + return _.i18n('%s has reached the victory condition').replace( + '%s', + _.i18n("Opponent's %s").replace('%s', _.i18n('tower')), + ) + } else { + return _.i18n('%s have reached the victory condition').replace( + '%s', + _.i18n("Opponent's %s").replace( + '%s', + _.i18n(resNames[reasonIndex - 2]), + ), + ) + } + } +} diff --git a/src/window.scss b/src/window.scss index fb03bcb..fd24458 100644 --- a/src/window.scss +++ b/src/window.scss @@ -285,25 +285,14 @@ @apply flex-grow; } } - .copied, button { - @apply flex-grow-0 py-1 ltr:ml-2 rtl:mr-2; + @apply flex-grow-0 py-1 px-4 ltr:ml-2 rtl:mr-2; &:active { @apply border-b-0; padding-top: calc(0.25rem + 2px); padding-bottom: calc(0.25rem + 2px); } } - .copied { - @apply px-1 opacity-0; - transition: opacity 150ms linear; - &.copied-shown { - @apply opacity-100; - } - } - button { - @apply px-4; - } #yourId { @apply cursor-pointer; }