Программирование аркадных игр и обучение информатике

Программирование аркадных игр
и обучение информатике

Chapter 4: Циклы; Игра с угадыванием случайного числа

Последний шаг прежде чем начать программирование графики - научиться, как использовать циклы. Многие игры “цикличны.” Они вновь и вновь повторяют один и тот же код. Например, игра по угадыванию чисел, приведённая ниже, делает шаг внутри цикла после каждой догадки пользователя:

Видео: Цикл for
Привет! Я задумал случайное число от 1 до 100.
--- Попытка 1
Угадай, что я загадал: 50
Слишком большое.
--- Попытка 2
Угадай, что я загадал: 25
Слишком большое.
--- Попытка 3
Угадай, что я загадал: 17
Слишком большое.
--- Попытка 4
Угадай, что я загадал: 9
Слишком маленькое.
--- Попытка 5
Угадай, что я загадал: 14
Слишком большое.
--- Попытка 6
Угадай, что я загадал: 12
Слишком большое.
--- Попытка 7
Угадай, что я загадал: 10
Слишком маленькое.
Оу, у тебя больше нет попыток. Загаданное число было 11.

Подождите, какая у этого связь с видеоиграми? Каждый кадр frame в игре отображается с помощью цикла. Вы можете знать про статистику fps, кадров в секунду, которая зачастую показывается во многих играх. FPS означает количество раз, сколько компьютер меняет изображение на экране каждую секунду. Чем выше значение, тем плавнее идёт игра. (Хотя частота выше 60 - это быстрее, чем большинство мониторов могут обновлять свою картинку, так что зачастую нет смысла преследовать большее значение.)

fig.fps
Figure 4.1: FPS в играх

Цикл в этих играх работает так, как это показано на рисунке 4.2. Внутренности цикла похожи на калькулятор, который мы сделали в первой главе.

fig.game_loop
Figure 4.2: Игровой цикл

Могут существовать даже циклы внутри циклов. Посмотрите на схему “Нарисовать всё” на рисунке 4.2. Внутри себя, схема содержит цикл, который выглядит как рисунок 4.3.

fig.draw_everything
Figure 4.3: Цикл с прорисовкой всего

В Python'е есть два основных цикла: цикл for и цикл while. Если программа хочет повторить открывок кода определённое количество раз, она использует цикл for. Все остальные циклы делаются с помощью while.

Например, цикл, печатающий на экране все имена учеников, будет использовать for, потому что нам известно количество учеников. Цикл, которые ждёт и проверяет, нажал ли пользователь какую-либо кнопку мыши, будет использовать while из-за того, что компьютеру не известно, сколько придётся ждать ввода пользователя.

4.1 Цикл "For"

Нижеприведённый пример кода использует for для вывода предложения пять раз.

Заметьте сходства кода с кодом, использующим оператор if. Оба используют отступы и двоеточие.
for i in range(5):
    print ("Я не буду жевать жевачку в классе.")
Вывод:
Я не буду жевать жевачку в классе.
Я не буду жевать жевачку в классе.
Я не буду жевать жевачку в классе.
Я не буду жевать жевачку в классе.
Я не буду жевать жевачку в классе.

i, используемая на первой строке, является переменной. Это новая переменная, которая может быть названа любым разрешённым для переменной именем. Программисты часто используют i как имя, потому что i - сокращение английского слова increment(увеличение). Эта переменная помогает следить за выполнением условия по завершению цикла.

Функция range контролирует, сколько раз должен выполниться код в цикле. В данном случае это пять раз.

Следующий пример кода написатает слово "Please," пять раз, а надпись "Can I go to the mall?" только один раз. Фраза "Can I go to the mall?" не предназначена для того, чтобы находится в цикле for. Поэтому она не выведется на экран до тех пока, пока цикл for не закончится.
for i in range(5):
    print ("Please,")
print ("Can I go to the mall?")
Вывод:
Please,
Please,
Please,
Please,
Please,
Can I go to the mall?

Этот пример берёт написаный выше код и смещает третью строку. Это изменение заставит программу напечатать "Please," и "Can I go to the mall?" 5 раз. После того, как было перемещено предложение "Can I go to the mall?", оно стало частью цикла for, что заставит его повториться пять раз сразу же после слов "Please,".
for i in range(5):
    print ("Please,")
    print ("Can I go to the mall?")
Вывод:
Please,
Can I go to the mall?
Please,
Can I go to the mall?
Please,
Can I go to the mall?
Please,
Can I go to the mall?
Please,
Can I go to the mall?

Функция range возвращает множество чисел. В вышеприведённом примере код range(10) вернёт 10 чисел, от нуля до девяти включительно.

Нижеприведённый код выведет номера от 0 до 9. Заметьте, что цикл начинается от 0 и не включает в себя число 10. Это вполне естественно, если вы думаете, что range(10) будет включать в себя поданное значение 10, но всё-таки оно останавливается за единицу до него.
for i in range(10):
    print (i)
Вывод:
0
1
2
3
4
5
6
7
8
9

Заметьте, что вместо имени переменной i можно использовать и другое имя. Например, программист мог бы использовать имя lineNumber, если бы программа шла по строкам текстового файла.

Если программист на самом деле хочет пройти от 1 до 10, то для этого есть несколько методов. Первый: использовать функцию range, подав ей два числа: первое - с какого начинать, второе - то, на котором надо закончить, прибавив к нему единицу. В данном случае, это будет 11.

Требуется немного практики, чтобы привыкнуть к использованию цикла for, включающим в себя первое указанное число, но не доходящим до последнего указанного числа.
for i in range(1,11):
    print (i)
Вывод:
1
2
3
4
5
6
7
8
9
10

Нижеприведённый код всё ещё использует переменную i, идущую от 0 до 9. Однако на этот раз, прежде чем вывести переменную, программист добавляет к ней единицу.

# Print the numbers 1 to 10.
for i in range(10):
    print (i+1)

4.1.1 Идти по циклу с шагом больше единицы

Для программы не составит труда увеличивать переменную на 2 или использовать какой-либо другой метод увеличения в случае надобности. Всегда есть два путя для достижения этой цели. Самый простой: добавить третье число в функцию range. Оно и заставит функцию увеличивать числа на 2. Другой способ это всё так же увеличивать i на единицу, однако умножать это значение на 2 перед выводом.
# Два способа печатать чётные числа от 2 до 10
for i in range(2,12,2):
    print (i)

for i in range(5):
    print ((i+1)*2)
Вывод:
2
4
6
8
10
2
4
6
8
10

Также вполне реально уменьшать, а не увеличивать значение, вплоть до нуля.
for i in range(10,0,-1):
    print(i)
Вывод:
10
9
8
7
6
5
4
3
2
1

Если циклу нужно пройти через разные числа, которые не формируют из себя последовательность с закономерностью, то в данном случае можно брать числа из списка:

for i in [2,6,4,2,4,6,7,4]:
    print(i)

Это выводит:

2
6
4
2
4
6
7
4

4.1.2 Циклы в циклах

Попробуйте предсказать, что выведет нижеприведённый код. Затем введите код и проверьте, правы ли вы.

# Что это выводит? Почему?
for i in range(3):
    print ("a")
for j in range(3):
	print ("b")
Видео: циклы for внутри других циклов

Следующий отрывок кода практически идентичен предыдущему. Второй for был смещён налево, так что теперь он гнездится внутри первого цикла. Это сильно меняет результат запуска кода. Попробуйте и убедитесь сами.

# Что это выводит? Почему?
for i in range(3):
    print ("a")
    for j in range(3):
        print ("b")

print("Готово")

Это видео показывает, что творится в вышеприведённом кода:

Видео: анимация цикла for

4.1.3 Ввод суммы чисел

Частое действие при работе с циклами - сохранение суммы. Нижеприведённый код сложит все введённые пользователем числа:

total=0
for i in range(5):
    newNumber = int (input( "Введите число: " ))
    total += newNumber
print("Сумма чисел: ",total)
Ваш браузер не поддерживает видео.

Заметьте, что строка 1 создаёт переменную total, задав ей начальное значение 0. Очень легко об этом позабыть. Также заметьте, что строка кода номер 4 прибавляет ввод пользователя к общей сумме, сохранённой в total. Частая ошибка в данном случае - прибавление i в этом примере.

Нижеприведённый код добавляет все числа от 1 до 100. Он демонстрирует обычный пример того, как сумма меняется внутри цикла. Он также использует отдельную переменную для сохранения общей суммы.

# Чему равна переменная sum?
sum=0
for i in range(1,101):
    sum = sum + i
print(sum)

Этот код посчитает, сколько раз пользователь ввёл число 0:

total=0
for i in range(5):
    newNumber = int (input( "Введите число: " ))
    if newNumber == 0:
        total += 1
print("Вы ввели ноль ",total," раз")

Программист, который понимает гнездящиеся циклы for и сохранение суммы, должнен быть способен предсказать, что же выведет код приведённый ниже.

# Чему равно значение a?
a=0
for i in range(10):
    a=a+1
print(a)

# Чему равно значение a?
a=0
for i in range(10):
    a=a+1
for j in range(10):
    a=a+1
print(a)

# Чему равно значение a?
a=0
for i in range(10):
    a=a+1
    for j in range(10):
        a=a+1
print(a)

4.2 Примеры циклов for

# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Print 'Hi' 10 times
for i in range(10):
    print("Hi")

# Print 'Hello' 5 times and 'There' once
for i in range(5):
    print("Hello")
print("There")

# Print 'Hello' 'There' 5 times
for i in range(5):
    print("Hello")
    print("There")

# Print the numbers 0 to 9
for i in range(10):
    print(i)

# Two ways to print the numbers 1 to 10
for i in range(1, 11):
    print(i)

for i in range(10):
    print(i + 1)

# Two ways to print the even numbers 2 to 10
for i in range(2, 12, 2):
    print(i)

for i in range(5):
    print((i + 1) * 2)

# Count down from 10 down to 1 (not zero)
for i in range(10, 0, -1):
    print(i)

# Print numbers out of a list
for i in [2, 6, 4, 2, 4, 6, 7, 4]:
    print(i)

# What does this print? Why?
for i in range(3):
    print("a")
    for j in range(3):
        print("b")

# What is the value of a?
a = 0
for i in range(10):
    a = a + 1
print(a)

# What is the value of a?
a = 0
for i in range(10):
    a = a + 1
for j in range(10):
    a = a + 1
print(a)

# What is the value of a?
a = 0
for i in range(10):
    a = a + 1
    for j in range(10):
        a = a + 1
print(a)

# What is the value of sum?
sum = 0
for i in range(1, 101):
    sum = sum + i

4.3 Циклы while

Видео: цикл while

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

Цикл while может быть использован там же, где и сам for. Его также можно использовать в случаях, когда цикл должен продолжаться до того, как произойдёт какое-либо событие. Например, программа будет проверять, что делает мышь до тех пор коа пользователь не нажмёт кнопку "Закрыть".

Цикл for вроде этого:

for i in range(10):
    print (i)
...может быть реализован с помощью цикла while, написанного следующим образом:
i=0
while i < 10:
    print(i)
    i = i + 1

Как можно видеть в коде, цикл for более компактен, чем цикл while. Кроме этого, он легче читается. В остальном же программа делает тоже самое с циклом while.

Первая строка перед циклом while устанавливает временную переменную, которая будет считать сколько раз выполнился цикл.

Строка 2 содержит сам цикл while. Формат цикла while очень схож с оператором if. Если условие выполняется, код внутри цикла будет повторён.

Частая ошибка - путать местами циклы for и while. Нижеприведённый код показывает пример, где программист не смог определиться, хочет ли он использовать цикл for или while.

while range(10):
    print(i)

Кстати, можно сократить код:

i=i+1

Кодом:

i += 1

Это также может быть использовано как для вычитания, так и умножения. Например:

i=0
while i < 10:
    print(i)
    i += 1

Что будет выведено?

i=1
while i <= 2**32:
    print(i)
    i *= 2

Зачастую с помощью while зацикливают программу до момента, пока пользователь не выскажет желания выйти:

quit="n"
while quit == "n":
    quit = input ("Вы хотите выйти из программы? ")

Существует несколько способов выхода из цикла. Использовать переменную типа Boolean для проверки условия, которая изменяется после действий.

done=False
while not(done):
    quit = input ("Вы хотите выйти? ")
    if quit == "y" :
        done = True;

    attack = input ("Ваш эльф атакует дракона? ")
    if attack == "y":
        print ("Плохой выбор, вы умерли.")
        done = True;

Это не идеальный вариант, потому что если пользователь скажет, что он хочет выйти, программа всё ещё будет продолжаться до следующего вопроса, где спрашивается, хочет ли он напасть на дракона.

Вот пример цикла while, где код повторяется до того момента, когда значение станет близким к единице.

value=0
increment=.5
while value < 0.999:
    value += increment
    increment *= 0.5
    print(value)

4.3.1 Частые проблемы с циклами while

Программист хочет досчитать от 10 до 0. Где ошибка и как её можно исправить?

i = 10
while i == 0:
    print (i)
    i -= 1

Где ошибка в этом цикле, который пытается досчитать до 10? Что случится, когда его запустят? Как это следует исправить?

i=1
while i < 10:
    print (i)

4.4 Примеры циклов while

# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# A while loop can be used anywhere a for loop is used:
i = 0
while i < 10:
    print(i)
    i = i + 1

# This is the same as:
for i in range(10):
    print(i)

# It is possible to short hand the code:
# i = i + 1
# With the following:
# i += 1
# This can be done with subtraction, and multiplication as well.
i = 0
while i < 10:
    print(i)
    i += 1

# What would this print?
i = 1
while i <= 2**32:
    print(i)
    i *= 2

# A very common operation is to loop until the user performs
# a request to quit
quit = "n"
while quit == "n":
    quit = input("Do you want to quit? ")

# There may be several ways for a loop to quit. Using a boolean
# to trigger the event is a way of handling that.
done = False
while not done:
    quit = input("Do you want to quit? ")
    if quit == "y":
        done = True

    attack = input("Does your elf attach the dragon? ")
    if attack == "y":
        print("Bad choice, you died.")
        done = True

value = 0
increment = 0.5
while value < 0.999:
    value += increment
    increment *= 0.5
    print(value)

# -- Common problems with while loops --

# The programmer wants to count down from 10
# What is wrong and how to fix it?
i = 10
while i == 0:
    print(i)
    i -= 1

# What is wrong with this loop that tries
# to count to 10? What will happen when it is run?
i = 1
while i < 10:
    print(i)

4.5 Случайные числа

4.5.1 Функция randrange

Видео: случайные числа

Случайные числа часто используются в играх или симуляционных программах.

По умолчанию Python не знает, откуда брать случайные числа. Для этой цели нужно импортировать код библиотеки, которая умеет создавать случайные числа. Так что для использования случайных чисел, в самом верху программы нужно добавить выражение import:

import random

Как и с pygame, важно не создавать файл с таким же именем, как и импортируемая библиотека. Создание файла с названием random.py чревато тем, что Python будет пытаться импортировать созданный вами файл, вместо системной библиотеки, создающей случайные числа.

После этого, случайные числа могут быть созданы с помощью функции randrange. Например, этот код создаёт случайное число от 0 до 49. По умолчанию нижняя граница равна нулю.

my_number=random.randrange(50)

Этот код создаёт случайное число от 100 до 200. Второй параметр задаёт верхнюю границу(не включая её). Так что если вы хотите случайные числа до 200, задайте верхнюю границу 201.

my_number=random.randrange(100,201)

Если программе требуется выбрать случайные элемент из списка, этого легко достигнуть:

my_list=["rock","paper","scissors"]
random_index=random.randrange(3)
print(my_list[random_index])

4.5.2 Функция random

Все предыдущие премеры генерируют целые числа. Если же программисту нужно число с плавающей точкой, ему следует использовать функцию random.

Нижеприведённый код генерирует случайное число в интервале от 0 до 1, например: 0.4355991106620656.

my_number=random.random()

Это число может быть изменено с помощью простой математики. Например, следующий код создаёт случайное дробное число в интервале от 10 до 15:

my_number=random.random()*5+10

4.6 Проверочные вопросы, не связаные с циклами

  1. Вычеркните имена переменных, запрещённые в Python.
    pi
    PI
    fred
    Fred
    GreatBigVariable
    greatBigVariable
    great_big_variable
    great.big.variable
    2x
    x2x
    total%
    #left
    
  2. Обведите имена переменных, которые разрешены, но не корректны.
    pi
    PI
    fred
    Fred
    GreatBigVariable
    greatBigVariable
    great_big_variable
    great.big.variable
    2x
    x2x
    total%
    #left
    
  3. Дайте пример выражения на Python:
  4. Что такое "оператор" в языке Python?
  5. Что выводит следующая программа?
    x=3
    x+1
    print(x)
    
  6. Исправьте следующий код:
    user_name=input("Введите своё имя: )"
    
  7. Исправьте следующий код:
    value=int(input(print("Введите свой возраст")))
    
  8. Исправьте следующий код:
    temperature = float (input("Температура"))
    if temperature > = 90
        print("Снаружи жарко.")
    
  9. Исправьте следующий код:
    print("Welcome to Oregon Trail!")
    userInput = input("What is your occupation?")
    
    print("A. Banker")
    print("B. Carpenter")
    print("C. Farmer")
    
    if userInput = A:
        money=100
    else if userInput = B:
        money=70
    else if userInput = C:
        money=50
    
    
  10. Что не так с этим кодом?
    x=input("Введите число:")
    if x > 100
        print ("Вы ввели большое число.")
    else
    	print ("Вы ввели небольшое число.")
    
  11. Напишите программу, которая просит пользователя, сколько четвертаков и пятаков у него есть, а затем пишет общую стоимость этих денег.

4.7 Проверочные вопросы о циклах

Нажмите здесь для теста с несколькими вариантами ответов (англ. яз).

  1. Напишите программу на Python, которая будет использовать цикл for, чтобы вывести ваше имя на экран 10 раз, а затем выведет слово "Готово" в самом конце.
  2. Напишите программу на Python, которая будет использовать цикл for, чтобы вывести на экран слова "Красный", а затем "Золотой" 20 раз.
  3. Напишите программу на Python, которая будет использовать цикл for, чтобы вывести на экран чётные числа от 2 to 100 включительно.
  4. Напишите программу на Python, которая будет использовать цикл while, чтобы сосчитать от 10 до 0 (включительно). Затем, выведите "Полетели!" в самом конце.
  5. В этой программе 4 ошибки. Найдите и исправьте их.
    print ("Эта программа берёт три числа и возвращает их сумму.")
    total=0
    
    for i in range(3):
        x=input("Введите число: ")
        total=total+i
        print ("Сумма:",x)
    
  6. Напишите программу на Python, которая:
    • просит пользователя ввести семь чисел
    • пишет общую сумму чисел
    • Пишет сколько пользователь ввёл положительных чисел, отрицательных чисел и нулей.

4.8 Проверочные вопросы о случайных числах

  1. Напишите программу, которая выводит случайное число в интервале от 1 до 10 (включительно).
  2. Напишите программу, которая выводит случайное дробное число в интервале от 1 до 10 (включительно).
  3. Подкидыватель монеток
    • Создайте программу, которая будет выводит случайно 0 или 1.
    • Вместо 0 и 1, выводите “орёл” или “решка”.
    • Добавьте цикл, чтобы программа так делала 50 раз.
    • Выведите на экран, сколько раз выпал орёл и сколько - решка.
  4. Создайте программу, которая играет в “камень, ножницы, бумагу”
    • Создайте программу, которая случайно выводит 0, 1 или 2.
    • Вместо 0, 1 или 2 выводите “камень”, “ножницы”, “бумага”, используя оператор if. Не берите их из списка, как было показано ранее в этой главе.
    • Сделайте так, чтобы программа сначала спрашивала выбор пользователя.
      • Будет проще, если он будет вводить 1, 2, или 3.
    • Добавьте условие чтобы можно было понять, кто выйграл.

You are not logged in. Log in here and track your progress.