全站通知:
Widget:GachaType
刷
历
编
跳到导航
跳到搜索
<!DOCTYPE html> <html lang="zh-CN"> <head>
<meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>恋与深空抽卡状态判定工具</title> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://cdn.tailwindcss.com"></script> <style> /* 添加防止水平滚动的样式 */ body { overflow-x: hidden; width: 100vw; margin: 0; padding: 0; box-sizing: border-box; }
#app { font-size: 20.8px; width: 100%; overflow-x: hidden; padding: 10px 10px; box-sizing: border-box; }
/* 修改容器最大宽度和边距 */ .max-w-2xl { max-width: min(42rem, 100%); width: 100%; padding-left: 0.5rem; padding-right: 0.5rem; margin: 0 auto; box-sizing: border-box; }
/* 在小屏幕上调整网格布局和间距 */ @media (max-width: 640px) { .grid.grid-cols-2 { grid-template-columns: 1fr; } /* 调整内边距 */ .sci-fi-card { padding: 0.75rem !important; margin-left: -0.5rem !important; margin-right: -0.5rem !important; border-radius: 0.5rem !important; } .p-6 { padding: 0.75rem !important; } .px-6 { padding-left: 0.75rem !important; padding-right: 0.75rem !important; }
/* 调整输入框和下拉框的内边距 */ .sci-fi-input { padding: 0.5rem 0.75rem !important; }
/* 调整网格间距 */ .grid.gap-5 { gap: 0.75rem !important; }
/* 确保文本不会溢出 */ .status-line { padding-left: 1rem !important; padding-right: 0.5rem !important; word-break: break-word; }
/* 调整状态行的间距 */ .ml-4 { margin-left: 0.75rem !important; } }
.sci-fi-card { background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 255, 255, 0.95) 100%); box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); border: 1px solid rgba(255, 255, 255, 0.6); } .sci-fi-input { background: rgba(255, 255, 255, 0.9); border: 1px solid rgba(0, 0, 0, 0.1); color: rgba(0, 0, 0, 0.8); font-size: 16px !important; padding: 0.75rem 1rem !important; height: auto !important; line-height: 1.5 !important; -webkit-text-size-adjust: 100%; } .sci-fi-input:focus { border-color: rgba(59, 130, 246, 0.5); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1); outline: none; } .sci-fi-select { padding-right: 3rem !important; background-image: linear-gradient(45deg, transparent 50%, rgba(0, 0, 0, 0.4) 50%), linear-gradient(135deg, rgba(0, 0, 0, 0.4) 50%, transparent 50%); background-position: calc(100% - 1.5rem) center, calc(100% - 1rem) center; background-size: 0.5rem 0.5rem, 0.5rem 0.5rem; background-repeat: no-repeat; } .status-line { position: relative; padding-left: 1.3rem !important; padding-top: 0.4rem !important; padding-bottom: 0.4rem !important; font-size: 1.3rem !important; } .status-line::before { content: ; position: absolute; left: 0; top: 50%; width: 8px; height: 8px; background: rgba(59, 130, 246, 0.5); transform: translateY(-50%); } .status-line .text-sm { font-size: 1.1rem !important; } .text-xl { font-size: 1.95rem !important; } label.text-sm { font-size: 1.3rem !important; } .text-red-500.text-sm { font-size: 1.1rem !important; } .text-gray-500.mt-1 { font-size: 1.1rem !important; } .grid.gap-5 { gap: 1.5rem !important; } label.mb-2 { margin-bottom: 0.75rem !important; } .ml-4 { margin-left: 1.5rem !important; } .detail-text { font-size: 1.1rem !important; line-height: 1.7rem !important; } .p-6.space-y-4 > .status-line:first-child { padding-top: 0 !important; } </style>
</head> <body>
抽卡状态判定工具
GACHA STATUS CALCULATOR
<label class="block text-sm text-gray-600 mb-2">多少抽内必得5星</label> <input type="number" v-model="remainingTo5Star" class="w-full px-4 py-2.5 rounded-lg sci-fi-input text-sm" placeholder="输入1-70之间的数值" inputmode="numeric" pattern="[0-9]*" @change="validateInput" >
输入1-70之间的数值
<label class="block text-sm text-gray-600 mb-2">上次抽卡的卡池</label> <select v-model="currentPoolType" class="w-full px-4 py-2.5 rounded-lg sci-fi-input sci-fi-select text-sm appearance-none"> <option value="single">单人月卡池</option> <option value="daily">日卡池</option> <option value="triple">多人月卡池</option> </select>
<label class="block text-sm text-gray-600 mb-2">上次获得的5星</label> <select v-model="lastObtainedCard" class="w-full px-4 py-2.5 rounded-lg sci-fi-input sci-fi-select text-sm appearance-none"> <template v-if="currentPoolType === 'triple'"> <option value="targeted">UP卡是定向</option> <option value="up_with_target">UP卡非定向(当时已选定向)</option> <option value="up_no_target">UP卡非定向(当时未选定向)</option> <option value="standard_with_target">常驻卡(当时已选定向)</option> <option value="standard_no_target">常驻卡(当时未选定向)</option> </template> <template v-else> <option value="up_no_target">UP卡</option> <option value="standard_no_target">常驻卡</option> </template> </select>
<label class="block text-sm text-gray-600 mb-2">下次卡池类型</label> <select v-model="nextPoolType" class="w-full px-4 py-2.5 rounded-lg sci-fi-input sci-fi-select text-sm appearance-none"> <option value="same">继续参与本次卡池(如有定向则选定向)</option> <option value="single">单人月卡池</option> <option value="daily">日卡池</option> <option value="triple">多人月卡池</option> </select>
小保底 模板:SmallPity/70 {{ currentPulls < 60 ? `还需 ${60 - currentPulls} 抽提升概率` : `当前概率 ${11 + ((currentPulls - 61) * 10)}% → ${Math.min(100, 11 + ((currentPulls - 60) * 10))}%` }}
大保底 模板:LastObtainedCard.includes('standard') ? '已触发' : '未触发' {{ lastObtainedCard.includes('standard') ? '下个5星思念必定是UP思念' : `下个5星思念有${currentPoolType === 'triple' ? '75' : '50'}%概率为UP思念` }}
定向 模板:TargetedPity/1 {{ currentPoolType !== 'triple' ? '切换到多人月卡池后可选择定向' : nextPoolType === 'triple' && nextPoolType !== 'same' ? '切换多人卡池会重置定向心愿值' : targetedPity === 1 ? '下个5星思念必定是定向思念' : lastObtainedCard.includes('no_target') ? '未选定向无累积' : '未累积定向值' }}
<template v-for="(step, index) in pullSteps" :key="index">
在 模板:Step.pulls 抽触发保底获得模板:Step.cardType <template v-if="step.note">(模板:Step.note)</template>
</template>
<script> const { createApp, ref, computed, watch } = Vue
const app = createApp({ setup() { const remainingTo5Star = ref(1) const currentPoolType = ref('single') const lastObtainedCard = ref('standard_no_target') const nextPoolType = ref('same') const inputError = ref(false) const smallPity = ref(0) const bigPity = ref(0) const targetedPity = ref(0) const remainingPulls = ref(0) const statusMessage = ref()
const currentPulls = computed(() => { return Math.max(0, 70 - remainingTo5Star.value) })
const nextPoolTypeDisplay = computed(() => { switch (nextPoolType.value) { case 'same': return currentPoolType.value === 'single' ? '单人月卡' : currentPoolType.value === 'daily' ? '日卡' : '多人月卡' case 'single': return '单人月卡' case 'daily': return '日卡' case 'triple': return '多人月卡' default: return } })
const determineStatus = () => { // 计算小保底状态 smallPity.value = currentPulls.value let baseStatus = // 大保底状态判定 if (lastObtainedCard.value.includes('standard')) { bigPity.value = 1 baseStatus = '当前处于大保底状态,下次获得5星必定是UP思念' } else { // 如果上次出了UP(包括定向和非定向),就重置大保底 bigPity.value = 0 baseStatus = '当前处于小保底状态,下次5星思念有75%概率为UP思念' }
// 定向许愿状态判定 if (currentPoolType.value === 'triple') { if (lastObtainedCard.value === 'targeted') { // 出了定向UP,重置心愿值 targetedPity.value = 0 baseStatus += '\n定向许愿已重置(获得了定向UP思念)' } else if (lastObtainedCard.value === 'standard_with_target' || lastObtainedCard.value === 'up_with_target') { // 选择了定向但出了非定向卡,获得心愿值 targetedPity.value = 1 baseStatus += '\n已累积1点心愿值,下次获得UP思念时必定是定向思念' } else { // 未选定向或其他情况 targetedPity.value = 0 baseStatus += '\n上次未选择定向,未累积心愿值' } } else { targetedPity.value = 0 }
// 预计抽数计算逻辑 const isTargetTriplePool = nextPoolType.value === 'triple' || (nextPoolType.value === 'same' && currentPoolType.value === 'triple')
if (isTargetTriplePool) { // 目标是在多人月卡池获得定向卡 if (currentPoolType.value === 'triple' && nextPoolType.value === 'same') { // 继续参与当前多人月卡池(不会重置定向状态) if (targetedPity.value === 1) { // 已有心愿值,下次必定是定向 remainingPulls.value = remainingTo5Star.value } else { // 继续参与且会选择定向,下次出金必定累积心愿值 remainingPulls.value = remainingTo5Star.value + 70 } } else { // 切换到新的多人月卡池或从其他卡池切换到多人月卡池 // 由于会选择定向,第一次出金必定累积心愿值 remainingPulls.value = remainingTo5Star.value + 70 } } else { // 目标是在单人月卡或日卡池获得UP卡 if (lastObtainedCard.value.includes('standard')) { // 已触发大保底,只需要等当前保底 remainingPulls.value = remainingTo5Star.value } else { // 未触发大保底最坏情况需要再一轮 remainingPulls.value = remainingTo5Star.value + 70 } }
// 添加预计抽数的说明 if (currentPoolType.value === 'triple') { if (targetedPity.value === 1) { baseStatus += '\n下个5星必定是定向思念' } else { baseStatus += '\n需要先获得一个非定向思念来积心愿值,获得一个定向思念' } } else { if (lastObtainedCard.value.includes('standard')) { baseStatus += '\n下个5星必定是UP思念' } else { baseStatus += '\n最坏情况需要触发两次保底' } }
statusMessage.value = baseStatus }
const validateInput = () => { // 转换为数字 let value = parseInt(remainingTo5Star.value) // 如果是空值或非数字,设为1 if (remainingTo5Star.value === || isNaN(value)) { remainingTo5Star.value = 1 inputError.value = true return }
// 限制范围在1-70之间 if (value < 1) { remainingTo5Star.value = 1 inputError.value = true } else if (value > 70) { remainingTo5Star.value = 70 inputError.value = true } else { inputError.value = false } determineStatus() }
// 监听所有输入的变化 watch( [currentPoolType, lastObtainedCard, nextPoolType], () => { determineStatus() }, { immediate: true } )
// 单独监听 remainingTo5Star watch( remainingTo5Star, (newVal) => { // 允许输入框为空,只在失焦时再处理默认值 if (newVal !== ) { determineStatus() } } )
// 监听卡池类型变化,重置上次获得的5星选项 watch( currentPoolType, (newVal, oldVal) => { if (newVal !== 'triple' && oldVal === 'triple') { // 从多人月卡切换到其他卡池时,重置为默认选项 lastObtainedCard.value = 'standard_no_target' } } )
const pullSteps = computed(() => { const steps = [] // 如果总抽数大于70,说明需要两次出金 if (remainingPulls.value > 70) { // 第一次出金(必定不是目标思念) steps.push({ pulls: remainingTo5Star.value, cardType: lastObtainedCard.value.includes('standard') ? 'UP思念' : '5星思念', note: nextPoolType.value === 'triple' || (nextPoolType.value === 'same' && currentPoolType.value === 'triple') ? '累积心愿值' : undefined }) // 第二次出金(必定是目标思念) steps.push({ pulls: 70, cardType: (nextPoolType.value === 'triple' || (nextPoolType.value === 'same' && currentPoolType.value === 'triple')) ? '定向思念' : 'UP思念' }) } else { // 只需要一次出金就能获得目标思念 steps.push({ pulls: remainingPulls.value, cardType: (nextPoolType.value === 'triple' || (nextPoolType.value === 'same' && currentPoolType.value === 'triple')) ? '定向思念' : 'UP思念' }) } return steps })
return { remainingTo5Star, inputError, validateInput, currentPulls, currentPoolType, lastObtainedCard, nextPoolType, smallPity, bigPity, targetedPity, remainingPulls, statusMessage, nextPoolTypeDisplay, determineStatus, pullSteps } } })
app.mount('#app') </script>
</body> </html>