В пятницу должны быть котики. Их есть у меня.
Игра третья — B4.
Это — настоящий пасьянс. Сложный, как запрос в Perl.
Потому успехом будет пользоваться только у математиков с Хабра и командировочных в поезде Москва-Екатеринбург.
В своем докладе я коротенько (строк на 40) расскажу о генерации раскладов, выдвину лемму о сходимость любого расклада, имеющего две степени свободы и продемонстрирую как я был сапогом, а стал дедушкой.
Правила
Правила такие же, как в игре Четыре комнаты. В комнате лежит цветной мусор. Мусор можно гонять по комнате движениями пальца по экрану — либо по горизонтали, либо — по вертикали.
Красный мусор можно выбросить через красную стенку. Желтый мусор — через желтую. Синий- через синюю. Голубой — голубую. Больше правил нет.
Поонятненько? Перейдем к примерам.
Посмотрите на рисунок 1. Необходимо очистить комнату от цветного мусора.
Рисунок 1. Простейший расклад
Решение для расклада на рисунке 1 состоит из двух ходов.
- сдвинуть фишки вправо (исчезнет красный мусор через красную стенку)
- сдвинуть фишки вверх (исчезнет синий мусор)
Пасьянс решен.
На рисунке 2 пример сложнее.
Рисунок 2. Если первый ход сделать вверх — пасьянс не сойдется.
Решение для расклада на рисунке 2 состоит из пяти ходов.
- сдвинуть фишки вправо
- сдвинуть фишки вниз
- сдвинуть фишки влево(исчезнет желтый мусор)
- сдвинуть фишки вверх(исчезнет синий мусор)
- сдвинуть фишки вправо
Пасьянс решен.
Пример номер 66
Генерация раскладов
В пасьянсах очень важна генерация раскладов. С одной стороны они должны быть случайными, с другой стороны всегда должна быть возможность повторить случайный расклад — либо подкинуть его приятелю на слабо!, либо сыграть заново самому.
Проблема в том, что моя игра универсальная — есть игра под iPhone, а есть интернет вариант. Как добиться одного и того же расклада на Objective C и JavaScipt?
Как ни странно — решение лежит в Visual Studio от Microsoft.
Я залез в math библиотеки VS и вытащил код функции псевдо-случайной генерации чисел.
- (int)microsoft_rnd {
holdrand = holdrand * 214013 + 2531011;
return ((holdrand >> 16) & 0x7FFF);
}
Задавая начальное значение в глобальной переменной holdrand — я могу повторить случайную последовательность столько раз, сколько захочу. Для удобства я завел 1 000 000 начальных раскладов и расширил функционал своего класса.
- (int) microsoft_rand:(int) number{
return [self microsoft_rnd] % number;
}
// Пример использования функции - получение случайного числа в диапазоне 1 - 4
...
int k = 1 + [self microsoft_rand:4];
...
На JavaScript данная функция выглядит чуть иначе
function microsoft_rnd()
{
var r;
var big = 4294967295+1;
microsoft_rnd.seed = (microsoft_rnd.seed * 214013 + 2531011)%big;
r = microsoft_rnd.seed;
r = Math.floor(r/65536);
r = r%32768;
return r;
}
function microsoft_rand(number)
{
return (microsoft_rnd())%number;
};
Экспериментально проверено, что результат работы функции во всех системах идентичен.
Таким образом задавая holdrand равным, например 2015, я получаю один и тот же расклад как на iPhone, так и в браузере.
Как я проверял игру
Первый раз запустив игру я расстроился. Выбранный мной расклад не сошелся. Я завелся. То есть завел большую картинку с симпатичной теткой, закрыл ее кнопками от 256 первых раскладов и начал играть с умом. При правильном решении очередного расклада — кнопка исчезала и тетка оголялась.
В результате на третий день я решил 255 из 256 раскладов. Не смог решить лишь один — в котором изначально не было движения по горизонтали.
Отсюда родилась лемма, которую не смог доказать — при наличии двух степеней свободы собирается любой полный пасьянс на доске 5 на 5 и выше.
Всем удачных выходных
Спасибо за внимание, анимация котиков танцы нанайских мальчиков — исключительно мудрецам, сложившим пасьянс.
Автор: PapaBubaDiop