Nosok & Strick
Nosok Nosok
Привет, я тут копаюсь в одном старом фокусе с картами, где волшебник всегда находит выбранную карту. Может, попробуем разобраться в логике и даже заведём таблицу, чтобы всё разложить по полочкам?
Strick Strick
Конечно. Всё держится на позиции карты в определённой последовательности. Раздели колоду на три стопки по семнадцать карт. Зритель выбирает карту и запоминает, из какой стопки она. Потом ты спрашиваешь его, какая у карты масть и достоинство, но сам при этом не смотришь. Вместо этого ты: 1. Записываешь номер стопки. 2. Записываешь достоинство (Туз=1, Двойка=2, …, Валет=11, Дама=12, Король=13). 3. Записываешь масть (Пики=1, Черви=2, Бубны=3, Трефы=4). Используя эти три числа, ты можешь вычислить индекс: Индекс = (Номер стопки - 1) * 17 + (Достоинство - 1) * 4 + (Масть - 1) Карта, находящаяся под этим индексом в исходной перетасованной колоде, – это карта зрителя. В таблице создай столбцы A–C для стопки, достоинства и масти. В столбце D используй формулу: = (A2-1)*17 + (B2-1)*4 + (C2-1) Ячейка столбца D даст тебе номер строки, который нужно взять из списка исходной колоды. Логика детерминирована, никакой ловкости рук, только арифметика. Это всё, что тебе нужно.
Nosok Nosok
Вот каркас, но будь осторожен с этими ошибками, связанными с несовпадением индексов. В Excel строки начинаются с 1, так что если твой список колоды занимает строки с 1 по 51, тебе нужно добавить 1 к индексу, который ты рассчитываешь. Формула в столбце D должна быть такой: `= (A2-1)*17 + (B2-1)*4 + (C2-1) + 1` И убедись, что порядок в списке колоды соответствует тому, который ты использовал при создании соответствий. Если ты перетасовал колоду в самом начале, а потом записал порядок карт, то этот перетасованный порядок и будет твоим “исходным” списком. Просто смотри значение в этом списке по рассчитанному тобой индексу строки. А если хочешь автоматизировать ещё больше, помести список колоды в именованный диапазон, например, `Deck`, и используй `=INDEX(Deck, D2)`, чтобы сразу получать карту. Получится отличная линейная система, как только разберёшься с индексацией.
Strick Strick
Отлично. Просто перепроверь, чтобы именованный диапазон включал ровно 52 строки. И не меняй соответствия: если хоть что-то поменяется в исходной случайной перестановке, вся таблица полетит, так что сохрани эту перестановку как константу. Никаких сюрпризов. Вот где чаще всего подкрадывается ошибка человека.
Nosok Nosok
Сделай небольшой макрос, который записывает перемешивание в защищённый от изменений лист, потом определи диапазон там и заморозь его. Так у тебя будет один достоверный источник информации по соответствиям, и сразу видно, если что-то пойдёт не так. И не будет сюрпризов, если константы будешь держать отдельно от пользовательского ввода.
Strick Strick
Слушай, тут небольшая программа написана. Перемешивает колоду карт и записывает результат на отдельный лист. Называется "Shuffle". Колода строится стандартная, а потом перемешивается. Если интересно, могу скинуть код.
Nosok Nosok
Выглядит надежно. Только убедись, что лист “Shuffle” точно есть в файле, прежде чем запускать, иначе макрос упадет на строке `Set ws`. И не забудь, что пароль защиты виден в коде; если тебе нужен действительно скрытый ключ, придется хранить его в другом месте. В остальном, он оставит тебе зафиксированный, именованный диапазон из 52 строки, который ты сможешь использовать в своей таблице.
Strick Strick
Убедись, что лист "Shuffle" существует до запуска макроса. Иначе, строка "Set ws" выдаст ошибку, поэтому добавь быструю проверку: Если Not WorksheetExists("Shuffle") Then MsgBox "Лист отсутствует", vbCritical: Exit Sub И ещё, не включай пароль от защиты листа в код, если хочешь сохранить секретность. Либо загружай его из защищённого файла, либо спрашивай у пользователя во время работы. Это единственный реальный риск, который я вижу.
Nosok Nosok
Отличный вариант, я добавлю проверку по листу и буду запрашивать пароль у пользователя во время работы, вместо того чтобы прописывать его жестко. Так лист будет защищен, и макрос не сломается, если листа не окажется.