Главная страница «Первого сентября»Главная страница журнала «Информатика»Содержание №7/2008


В мир информатики
Games.exe

Игра с кубиком

В данной статье описана компьютерная программа, моделирующая игру с игральной костью, условия которой изложены в статье “Цифровые корни”.

Будем рассматривать вариант игры, в котором участвуют компьютер и человек.

В программе использованы следующие величины:

n — предельное число очков (до которого ведется игра);

выпало — число, выпавшее на кубике при первом “бросании”;

всего — общее число просуммированных очков;

начинает и очередной — номер участника, соответственно начинающего игру и делающего очередной ход (1 — компьютер, 2 — человек);

выбрал1 — число на гранях, выбранное компьютером при очередном ходе;

выбрал2 — то же, вторым участником игры;

верхнее — число, оказавшееся на верхней грани кубика (при первом “бросании” или после очередного хода участников игры).

Общая схема программы:

Условимся на этапе 1 (см. схему программы в колонке слева) число n выбирать случайным образом из диапазона 30–40. Для этого используем функцию rnd:

n := 30 + rnd(11)

Также случайным образом определим номер участника, начинающего игру (“бросающего” кубик):

начинает := 1 + rnd(2)

и выпавшее число:

выпало := 1 + rnd(6)

Действия на этапе 4 можно описать в виде оператора цикла с постусловием:

цикл
    Выбор числа первым участником
    если всего < n
       то
           Выбор числа вторым участником
    все
конец_цикла при
всего >= n

Выбор числа компьютером будем проводить в соответствии со стратегией, которую обсудим ниже.

Перед выбором участниками игры того или иного числа будем выводить перечень чисел, которые можно выбрать. Ясно, что этот перечень зависит от текущего числа на верхней грани кубика (значения верхнее и 7 – верхнее выбирать нельзя1). Вывод перечня оформим в виде отдельной вспомогательной процедуры2.

алг Вывод_возможных_чисел(арг цел верхнее_число)
нач
   вывод нс, "Можно выбрать числа:"
   выбор
     при верхнее_число = 1: вывод "2 3 4 5"
     при верхнее_число = 2: вывод "1 3 4 6"
     при верхнее_число = 3: вывод "1 2 5 6"
     при верхнее_число = 4: вывод "1 2 5 6"
     при верхнее_число = 5: вывод "1 3 4 6"
     при верхнее_число = 6: вывод "2 3 4 5"
   все
кон

Примечание. Можно объединить некоторые значения величины верхнее_число в пары (использовав сложные условия). Как сформировать пары, продумайте самостоятельно.

В случае ввода человеком недопустимого значения числа выбрал2 на экран будем выводить соответствующее сообщение и предложим повторить ввод (применим оператор цикла с постусловием). Правильное значение числа выбрал2 удовлетворяет условию:

выбрал2 > 0 и выбрал2 < 7 и выбрал2 <> верхнее и выбрал2 <> 7 – верхнее.

После выбора числа (“поворота кубика”) каждым участником игры необходимо менять значения величин всего, верхнее и очередной.

Этап 5 можно оформить в виде:

|Определение победителя

вывод нс, "Игра закончилась!"
если всего = n
  то
    если очередной = 1
      то
          вывод нс, "Выиграли Вы. Поздравляем!"
      иначе
          вывод нс, "Выиграл компьютер!"
   все
  иначе
     если очередной = 2
       то
         вывод нс, "Выиграли Вы. Поздравляем!"
       иначе
         вывод нс, "Выиграл компьютер!"
     все
все

Осталось обсудить механизм выбора числа компьютером при его ходе.

Будем идти, так сказать, от простого3 к сложному и в данной статье применим стратегию, которую назовем “квазиоптимальной”. Ее суть состоит в следующем.

1. Найдем ближайшее большее по сравнению с всего число, обеспечивающее выигрыш (как это сделать — опишем ниже); имя этой величины — большее_оптимальное.

2. Определим значение величины разность:

разность := большее_оптимальное – всего

3. Исследуем три варианта значения разность:

1) если разность = 9, то, как указывалось в статье “Цифровые корни”, такая позиция для компьютера является проигрышной (если, конечно, второй участник знает выигрышную стратегию). В этом случае будем выбирать минимально возможное число (1 или 2). Соответствующий фрагмент программы выглядит так:

если разность = 9
  то
    Выбираем 1 или 2
    если верхнее <> 1 и верхнее <> 6
       то |Можно выбрать 1
          выбрал1 := 1
       иначе
         выбрал1 := 2
все

2) если разность < 7, то можно получить следующую выигрышную позицию, выбрав на кубике число разность, если это допустимо. В случае невозможности такого выбора также выберем минимально возможное число, например:

при разность = 6:
если верхнее <> 6 и верхнее <> 1
   то |Можно выбрать 6
      выбрал1 := 6
   иначе
      |Выбираем минимально возможное число
      выбрал1 := 2 |1 выбрать нельзя
    все

и т.п.;

3) если разность = 8 или если разность = 7, то одним ходом следующую выигрышную позицию получить нельзя — здесь также будем выбирать минимально возможное число.

Определение “квазиоптимального” хода компьютера целесообразно оформить в виде вспомогательной функции (ее имя ниже — Выбор_компьютера). Прежде чем приводить такую функцию4, заметим, что ее аргументами являются величины n, всего, верхнее и представим для анализа фрагмент функции, относящийся к определению значения большее_оптимальное:

большее_оптимальное := n
нц пока большее_оптимальное > всего
     большее_оптимальное :=   большее_оптимальное — 9
кц
|Найдено значение большее_оптимальное,
|большее или равное всего
|Уточняем значение большее_оптимальное
большее_оптимальное := большее_оптимальное + 9

Функция на школьном алгоритмическом языке:

алг цел Выбор_компьютера(арг цел n, всего, верхнее)
нач цел разность, большее_оптимальное
|Определяем значение большее_оптимальное

… (см. выше)

|Определяем значение разность
разность := большее_оптимальное — всего

|Рассматриваем три варианта значения

|разность
  если разность = 9
    то |Проигрышная позиция
     |Выбираем 1 или 2
     если верхнее <> 1 и верхнее <> 6
       то
         знач := 1
       иначе
         знач := 2
       все
    иначе
       если разность > 6
       то |Выигрышную позицию сразу
       |получить нельзя
       |Выбираем 1 или 2
       если верхнее <> 1 и верхнее <> 6
          то |Можно выбрать 1
             знач := 1
          иначе
             знач := 2
        все
       иначе |разность <= 6
         выбор
            при разность = 6:
            если верхнее <> 6 и верхнее <> 1
               то |Можно выбрать 6
                  знач := 6
               иначе
                  |Выбираем минимально
                  |возможное число
                  знач := 2 |1 выбрать нельзя
           все
           при разность = 5:
              если верхнее <> 5 и верхнее <> 2
                то |Можно выбрать 5
                  знач := 5
                иначе
                  |Выбираем минимально возможное
                  знач := 1
              все
         при разность = 4:
             …
          при разность = 1:
            если верхнее <> 1 и верхнее <> 6
               то |Можно выбрать 1
                   знач := 1
               иначе
                  знач := 2
            все
          все
      все
   все
кон

Вся программа имеет вид:

алг Игра_с_кубиком
нач цел n, начинает, выпало, очередной, всего, верхнее, выбрал1, выбрал2
  |Определяем значение n
  n := 30 + rnd(11)
  вывод нс, "Игра будет продолжаться до ", n
  |Определяем начинающего игру
  начинает := 1 + rnd(2)
  если начинает = 1
    то
      вывод нс, "Первым бросает компьютер"
      |После этого очередной ход делает 2-й
      |участник игры
      очередной := 2
    иначе
      вывод нс, "Первым бросаете Вы"
     |После этого очередной ход делает |компьютер
     очередной := 1
   все
вывод нс, "Для продолжения игры — нажмите любую клавишу"
  нц
  кц при inkey <> ""
  выпало := 1 + rnd(6)
  всего := выпало
  верхнее := выпало
  вывод нс, "На кубике выпало число ",  выпало
  нц
     если очередной = 1
       то
         вывод нс, "Очередной ход делает компьютер"
         вывод нс, "Общая сумма чисел равна ", всего
         вывод "(игра до ", n, ")"
         Вывод_возможных_чисел(верхнее)
         вывод нс, "Для продолжения игры — нажмите любую клавишу"
         нц
         кц при inkey <> ""
         выбрал1 := Выбор_компьютера(n, всего, верхнее)
         вывод нс, "Компьютер выбрал ", выбрал1
         верхнее := выбрал1
         всего := всего + выбрал1
        |После этого очередной ход делает
        |2-й участник игры
        очередной := 2
      иначе
         если всего < n
           то
            вывод нс, "Очередной ход делаете Вы"
            вывод нс, "Общая сумма чисел равна ", всего
            вывод "(игра до ", n, ")"
            Вывод_возможных_чисел(верхнее)
            вывод нс, "Ваш выбор? "
            нц
               ввод выбрал2
               если выбрал2 < 1 или
                        выбрал2 > 6 или
                        выбрал2 = верхнее или
                        выбрал2 = 7 — верхнее
                  то
                    вывод нс, "Неправильный выбор! Попробуйте еще"
              все
           кц при выбрал2 > 0 и
                         выбрал2 < 7 и
                         выбрал2 <> верхнее и
                         выбрал2 <> 7 — верхнее
              верхнее := выбрал2
              всего := всего + выбрал2
              |После этого очередной ход делает
              |компьютер
              очередной := 1
         все
     все
  кц при всего >= n
  |Определение победителя
   вывод нс, "Игра закончилась!"
…(см. выше)
кон

Конечно, применение “квазиоптимальной” стратегии не всегда сможет обеспечить компьютеру выигрыш, даже если после первого бросания кубика или после какого-то хода позиция будет для него выигрышной.

Так сказать, “полностью оптимальная” стратегия игры компьютера обсуждается в статье “О выигрышной стратегии компьютера в игре с кубиком” в этом выпуске ниже. Ознакомьтесь, пожалуйста, с ней и выполните предложенное в статье задание (см. также рубрику “Внимание! Конкурс”).

Другие задания для самостоятельной работы

Разработайте программу, моделирующую рассмотренную игру с кубиком, в двух вариантах:

1) аналогичном описанному;

2) в котором играют два человека.

В каждом из них предусмотрите возможность того, что один из участников игры может сдаться (например, путем ввода числа 0). Разработанные программы (можно и одну) присылайте в редакцию. Все приславшие правильные программы будут награждены дипломами.

TopList