Menu
CoddyTech

Recap - Shape Calculator

Part of the Object Oriented Programming section of Coddy's GDScript journey. Lesson 25 of 65.

challenge icon

Challenge

Medium

Build a shape calculator that handles real shapes, a shape-like object from outside the hierarchy, and objects it cannot measure.

  • Shape is abstract, with the abstract methods area() -> float, perimeter() -> float and shape_name() -> String. Its normal method describe() returns NAME: area A, perimeter P with two decimals.
  • Circle (radius), Rectangle (width, height) and Triangle (sides a, b, c) extend Shape. Their names are Circle, Rectangle and Triangle. A circle's area is PI * r * r and its perimeter 2 * PI * r. For the triangle, use Heron's formula: with s = (a + b + c) / 2, the area is sqrt(s * (s - a) * (s - b) * (s - c)).
  • CustomShape does NOT extend Shape. It has a custom_name and a size; area() is size * size, perimeter() is 4 * size, and describe() uses the same format as Shape, with its custom name.
  • ShapeCalculator has two static functions. process(thing) returns [Shape] plus describe() for a Shape, [Duck] plus describe() for any other object that has a describe() method, and Cannot measure this object otherwise. total_area(things) adds up area() of every object that has an area() method.

The supplied code reads how many objects follow, then one per line: circle R, rectangle W H, triangle A B C, custom NAME SIZE or unknown (a plain RefCounted object). It prints process() for each one and the total area. For circle 5, custom Hexa 3 and unknown it prints:

[Shape] Circle: area 78.54, perimeter 31.42
[Duck] Hexa: area 9.00, perimeter 12.00
Cannot measure this object
Total area: 87.54

Your code goes in shape.gd, circle.gd, rectangle.gd, triangle.gd, custom_shape.gd and shape_calculator.gd. main.gd holds the supplied input/output code and cannot be edited.

Try it yourself

extends Node

func _ready():
	# Supplied input/output code: keep it as it is
	var count := int(OS.read_string_from_stdin())
	var things := []
	for i in count:
		var p := OS.read_string_from_stdin().split(" ")
		if p[0] == "circle":
			things.append(Circle.new(float(p[1])))
		elif p[0] == "rectangle":
			things.append(Rectangle.new(float(p[1]), float(p[2])))
		elif p[0] == "triangle":
			things.append(Triangle.new(float(p[1]), float(p[2]), float(p[3])))
		elif p[0] == "custom":
			things.append(CustomShape.new(p[1], float(p[2])))
		else:
			things.append(RefCounted.new())
	for thing in things:
		print(ShapeCalculator.process(thing))
	print("Total area: %.2f" % ShapeCalculator.total_area(things))

All lessons in Object Oriented Programming

Practice on your own: Online GDScript compiler