Доброго дня форумчане! Хочу написать калькулятор наиболее выгодного хода для игр типа 3 в ряд/lines то, что написал, вложил. Не получается организовать следующее. Есть поле 8*8, оно заполнено значениями от 1-5. Если в этом поле встречаются 3-5 ячеек подряд горизонтально или вертикально с одинаковыми значениями, то значения удаляются, количество удаленных значений записывается в таблицу рядом(то есть нашлось 3 ячейки со значением 5, после удаления записали количество этих ячеек в табличку рядом). После удаления все вышестоящие ячейки падают вниз(или до низа диапазона 8*8, или на ближайшую заполненную ячейку). Затем проверка повторяется до тех пор, пока будет что удалять. Это действие хочу прокрутить с любым возможным вариантом хода, чтобы понять, какой ход в данный момент самый выгодный. Надеюсь понятно объяснил :) В примере сделал макрос, который расскажет поэтапно каждое действие.
Доброго дня форумчане! Хочу написать калькулятор наиболее выгодного хода для игр типа 3 в ряд/lines то, что написал, вложил. Не получается организовать следующее. Есть поле 8*8, оно заполнено значениями от 1-5. Если в этом поле встречаются 3-5 ячеек подряд горизонтально или вертикально с одинаковыми значениями, то значения удаляются, количество удаленных значений записывается в таблицу рядом(то есть нашлось 3 ячейки со значением 5, после удаления записали количество этих ячеек в табличку рядом). После удаления все вышестоящие ячейки падают вниз(или до низа диапазона 8*8, или на ближайшую заполненную ячейку). Затем проверка повторяется до тех пор, пока будет что удалять. Это действие хочу прокрутить с любым возможным вариантом хода, чтобы понять, какой ход в данный момент самый выгодный. Надеюсь понятно объяснил :) В примере сделал макрос, который расскажет поэтапно каждое действие.lFJl
Как метко выразился один гуру: решение большой и сложной задачи по программированию - это последовательное решение нескольких отдельных задач попроще. В Вашем случае необходимо написать отдельные процедуры для следующих вещей:
1). Падение значений вниз. Самое простое и базовое. 2). Обнаружение и работа с ситуацией удаления значений. Здесь нужно будет перебрать значения игрового поля, проверить для них количество одинаковых соседей, прилегающих по вертикали и горизонтали и, если условия для удаления соблюдены - значения удаляем. Запоминаем ход и заработанные очки. После удаления можно запустить код процедуры из пункта "1". 3). Перебор всех возможных ходов с поиском лучшего. Для каждого хода прокручиваем цикл процедур из пунктов "1" и "2" и запоминаем результаты самого успешного хода. Если следующий просмотренный ход будет лучше - перезапоминаем результаты.
Для реализации любого из этих пунктов крайне рекомендую овладеть работой с массивами. Поиск по сайту и/или гугл в помощь.
В качестве учебного материала предлагаю взглянуть на мою реализацию "осыпающихся" значений. Код нарочно примитивизирован и снабжён комментариями. Тестовый файл во вложении.
[vba]
Код
Sub Move_Values_Down() ' Объявляем переменные: итераторы и массив для значений Dim i&, j&, k&, aMap ' Присваиваем переменной двух-мерный массив значений из диапазона aMap = ThisWorkbook.Worksheets("RioTable").Range("B2:I9") ' Перебираем "столбцы" массива с первого до последнего For j = 1 To UBound(aMap, 2) ' Перебираем "строки" массива от последней до 2-й For i = UBound(aMap, 1) To 2 Step -1 ' Для каждой проверяемой "ячейки" смотрим, не равна ли она нулю If aMap(i, j) = 0 Then ' А если равна - перебираем ячейки вверх по "столбцу" For k = i - 1 To 1 Step -1 ' И если нашли НЕ нулевую, то... If aMap(k, j) <> 0 Then ' Кидаем значение вниз aMap(i, j) = aMap(k, j) aMap(k, j) = 0 Exit For End If Next k End If Next i Next j ' Отображаем изменения в массиве на листе ThisWorkbook.Worksheets("RioTable").Range("B2:I9") = aMap End Sub
[/vba]
lFJl, здравствуйте.
Как метко выразился один гуру: решение большой и сложной задачи по программированию - это последовательное решение нескольких отдельных задач попроще. В Вашем случае необходимо написать отдельные процедуры для следующих вещей:
1). Падение значений вниз. Самое простое и базовое. 2). Обнаружение и работа с ситуацией удаления значений. Здесь нужно будет перебрать значения игрового поля, проверить для них количество одинаковых соседей, прилегающих по вертикали и горизонтали и, если условия для удаления соблюдены - значения удаляем. Запоминаем ход и заработанные очки. После удаления можно запустить код процедуры из пункта "1". 3). Перебор всех возможных ходов с поиском лучшего. Для каждого хода прокручиваем цикл процедур из пунктов "1" и "2" и запоминаем результаты самого успешного хода. Если следующий просмотренный ход будет лучше - перезапоминаем результаты.
Для реализации любого из этих пунктов крайне рекомендую овладеть работой с массивами. Поиск по сайту и/или гугл в помощь.
В качестве учебного материала предлагаю взглянуть на мою реализацию "осыпающихся" значений. Код нарочно примитивизирован и снабжён комментариями. Тестовый файл во вложении.
[vba]
Код
Sub Move_Values_Down() ' Объявляем переменные: итераторы и массив для значений Dim i&, j&, k&, aMap ' Присваиваем переменной двух-мерный массив значений из диапазона aMap = ThisWorkbook.Worksheets("RioTable").Range("B2:I9") ' Перебираем "столбцы" массива с первого до последнего For j = 1 To UBound(aMap, 2) ' Перебираем "строки" массива от последней до 2-й For i = UBound(aMap, 1) To 2 Step -1 ' Для каждой проверяемой "ячейки" смотрим, не равна ли она нулю If aMap(i, j) = 0 Then ' А если равна - перебираем ячейки вверх по "столбцу" For k = i - 1 To 1 Step -1 ' И если нашли НЕ нулевую, то... If aMap(k, j) <> 0 Then ' Кидаем значение вниз aMap(i, j) = aMap(k, j) aMap(k, j) = 0 Exit For End If Next k End If Next i Next j ' Отображаем изменения в массиве на листе ThisWorkbook.Worksheets("RioTable").Range("B2:I9") = aMap End Sub
Rioran, Понимаю, что это лучше всего сделать массивом в итоге, да и я бы начал делать... Да вот с массивами пока сложновато мне. Но я думаю освою! :) Спасибо з пример, буду разбираться!
А по поводу подсчета очков, может совет дадите как лучше сделать. Когда мы сделали ход, подсчитывается сколько и каких соединилось по 3,4...7 это для каждой цифры берется значение с 1 таблички. После того как цифры упали, и снова совпали то значения уже с таблички 2 берутся.
Надеюсь понятно разъяснил? Пока что-то не могу понять, как это сделать, чтоб считал сначала по 1, затем по 2 таблице
Rioran, Понимаю, что это лучше всего сделать массивом в итоге, да и я бы начал делать... Да вот с массивами пока сложновато мне. Но я думаю освою! :) Спасибо з пример, буду разбираться!
А по поводу подсчета очков, может совет дадите как лучше сделать. Когда мы сделали ход, подсчитывается сколько и каких соединилось по 3,4...7 это для каждой цифры берется значение с 1 таблички. После того как цифры упали, и снова совпали то значения уже с таблички 2 берутся.
Доброго дня! Наконец руки дошли продолжить "мысль" Решил поэтапно подойти к вопросу, написал несколько макросов: 1) заполняем диапазон случайными(в том числе исключаем возможность повторов 3 в ряд) 2) Падение значений вниз 3) нахождение ходов+сам ход
в планах 4) Подсчет очков(делим на подпункты) 4.1) Находим 3 и более в ряд 4.2) Подсчитываем очки, и записываем, в случае если очков набирается больше, чем в предыдущий ход 5) выполняем ход с наибольшим количеством очков. 6) В итоге все сведу в 1 макрос, который будет для пользователя показывать один, самый выгодный по очкам ход.
Застрял на подсчете очков, не могу придумать, как лучше(да и вообще) это реализовать.
Доброго дня! Наконец руки дошли продолжить "мысль" Решил поэтапно подойти к вопросу, написал несколько макросов: 1) заполняем диапазон случайными(в том числе исключаем возможность повторов 3 в ряд) 2) Падение значений вниз 3) нахождение ходов+сам ход
в планах 4) Подсчет очков(делим на подпункты) 4.1) Находим 3 и более в ряд 4.2) Подсчитываем очки, и записываем, в случае если очков набирается больше, чем в предыдущий ход 5) выполняем ход с наибольшим количеством очков. 6) В итоге все сведу в 1 макрос, который будет для пользователя показывать один, самый выгодный по очкам ход.
Застрял на подсчете очков, не могу придумать, как лучше(да и вообще) это реализовать.lFJl
Были мысли сделать так: искать сначала 5 в ряд(горизонталь, вертикаль), затем 4 и 3 соответственно. Затем записываю, что нашел(какую цифру и сколько в ряд, но тоже не понятно, как сделать пока что), удаляю значения и смотрю дальше. Но как быть с теми, которые могут быть например по горизонтали и по вертикали одновременно? Так же были мысли подсчитать количество удаляемых в ряд, но это сразу отпало, т.к. очки зависят от того, сколько в ряд одинаковых значений набираем.
Были мысли сделать так: искать сначала 5 в ряд(горизонталь, вертикаль), затем 4 и 3 соответственно. Затем записываю, что нашел(какую цифру и сколько в ряд, но тоже не понятно, как сделать пока что), удаляю значения и смотрю дальше. Но как быть с теми, которые могут быть например по горизонтали и по вертикали одновременно? Так же были мысли подсчитать количество удаляемых в ряд, но это сразу отпало, т.к. очки зависят от того, сколько в ряд одинаковых значений набираем.lFJl
Но как быть с теми, которые могут быть например по горизонтали и по вертикали одновременно?
Как вам идея сделать двух-мерный массив, где будут запоминаться точки текущего хода, которые надо "сжечь"? Тогда можно будет сделать следующее:
1). Ищем 3 и более подряд точек по горизонтали, потом по вертикали. 2). Если нашли группу таких точек - добавляем во "временный" массив со столбцами: "Номер Группы", "Координата Х", "Координата У". 3). Создаём "основной массив" с аналогичными столбцами. Копируем в него точки из "временного". 4). Если находим новую группу точек - запоминаем координаты во "временном". Каждую точку проверяем, не встречается ли она в уже собранных точках "основного" массива. 4а). Если не встречается - то добавляем в массив как новую группу. 4б). Если встречается - то номера всех встреченных на пересечениях групп исправляем на минимальное.
В конце получится массив с точками с отдельными группами. Для каждой группы можно будет подсчитать очки согласно Вашей логике.
***
P.S. Прям самому захотелось сделать "3 в ряд", но пока держусь.
Но как быть с теми, которые могут быть например по горизонтали и по вертикали одновременно?
Как вам идея сделать двух-мерный массив, где будут запоминаться точки текущего хода, которые надо "сжечь"? Тогда можно будет сделать следующее:
1). Ищем 3 и более подряд точек по горизонтали, потом по вертикали. 2). Если нашли группу таких точек - добавляем во "временный" массив со столбцами: "Номер Группы", "Координата Х", "Координата У". 3). Создаём "основной массив" с аналогичными столбцами. Копируем в него точки из "временного". 4). Если находим новую группу точек - запоминаем координаты во "временном". Каждую точку проверяем, не встречается ли она в уже собранных точках "основного" массива. 4а). Если не встречается - то добавляем в массив как новую группу. 4б). Если встречается - то номера всех встреченных на пересечениях групп исправляем на минимальное.
В конце получится массив с точками с отдельными группами. Для каждой группы можно будет подсчитать очки согласно Вашей логике.
***
P.S. Прям самому захотелось сделать "3 в ряд", но пока держусь.Rioran
Роман, Москва, voronov_rv@mail.ru Яндекс-Деньги: 41001312674279
Сообщение отредактировал Rioran - Среда, 21.09.2016, 18:45
Rioran, Можете пример написать? я хочу сделать 2 типа расчета, когда допустим: 08000 88888 08000 где это будет 3 и 5 подряд, и 7 подряд. В разных играх по разному считается, поэтому важно думаю.
Мне уже снится, как я решаю эту задачку, и никак не могу решить ее
Rioran, Можете пример написать? я хочу сделать 2 типа расчета, когда допустим: 08000 88888 08000 где это будет 3 и 5 подряд, и 7 подряд. В разных играх по разному считается, поэтому важно думаю.
Мне уже снится, как я решаю эту задачку, и никак не могу решить ее lFJl