Menu
CoddyTech

Перечисления в классах

Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 44 из 65.

Перечисление можно объявить внутри класса, рядом с его переменными. Тогда его варианты будут принадлежать этому классу:

# weapon.gd
class_name Weapon
extends RefCounted

enum Kind { SWORD, BOW, STAFF }

var kind: Kind

func _init(weapon_kind: Kind) -> void:
	kind = weapon_kind

func is_ranged() -> bool:
	return kind == Kind.BOW or kind == Kind.STAFF

Внутри weapon.gd перечисление называется Kind. Во всех остальных файлах сначала указывается имя класса — Weapon.Kind.BOW — в значениях, аннотациях типов и шаблонах match:

# blacksmith.gd
class_name Blacksmith
extends RefCounted

static func repair_cost(kind: Weapon.Kind) -> int:
	match kind:
		Weapon.Kind.SWORD:
			return 20
		Weapon.Kind.BOW:
			return 15
	return 30

Варианты по-прежнему являются числами: Weapon.new(Weapon.Kind.BOW).kind выводит 1. Само перечисление работает как словарь, сопоставляющий имена и числа:

print(Weapon.Kind.keys())       # ["SWORD", "BOW", "STAFF"]
print(Weapon.Kind.find_key(1))  # BOW
print(Weapon.Kind["STAFF"])     # 2
print(Weapon.Kind.size())       # 3
for kind in Weapon.Kind.values():
	print(Weapon.Kind.find_key(kind), ": ", Blacksmith.repair_cost(kind))

Цикл выводит SWORD: 20, BOW: 15 и STAFF: 30. GDScript не проверяет, что число является одним из вариантов: Weapon.new(7) создаёт оружие, у которого kind равно 7. Передавай именованные варианты, и код останется корректным.

Перечисление, описывающее класс, должно находиться внутри этого класса, чтобы читателю было понятно, откуда берётся Kind в Weapon.Kind.BOW.

challenge icon

Задание

Легко

Сортируй зелья с помощью перечисления, которое находится в классе Potion.

  • В potion.gd объяви enum Kind { HEAL, MANA, POISON } и укажи тип kind как Kind.
  • Potion.from_text(text, strength) — статическая функция, которая преобразует "MANA" в Kind.MANA и возвращает новое зелье.
  • describe() возвращает HEAL potion: +20 HP, MANA potion: +15 MP или POISON potion: -5 HP, используя название вида и силу.
  • В belt.gd функция summary() возвращает по одной строке для каждого вида в порядке перечисления: HEAL: 2 (35 total), с количеством зелий этого вида и, в скобках, суммой их силы. Для видов, у которых нет зелий, строка тоже выводится.

Предоставленный код считывает количество следующих зелий (HEAL 20), добавляет каждое в пояс, выводит его описание, а затем сводку. Для HEAL 20, POISON 5, HEAL 15 он выводит:

Added HEAL potion: +20 HP
Added POISON potion: -5 HP
Added HEAL potion: +15 HP
HEAL: 2 (35 total)
MANA: 0 (0 total)
POISON: 1 (5 total)

Твой код нужно написать в potion.gd и belt.gd. В main.gd находится предоставленный код ввода/вывода, его нельзя редактировать.

Попробуйте сами

extends Node

func _ready():
	# Предоставленный код ввода/вывода: оставьте его без изменений
	var belt := Belt.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		var potion := Potion.from_text(parts[0], int(parts[1]))
		belt.add(potion)
		print("Added ", potion.describe())
	for line in belt.summary():
		print(line)
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор GDScript