Menu
CoddyTech

车辆租赁服务

本课属于 Coddy GDScript 学习旅程的“面向对象编程”单元。第 65 课,共 65 课。

challenge icon

挑战

中等

构建一个车辆租赁服务:包含两种车辆、租赁记录,以及负责管理它们的租赁机构。价格以整数美元计(int)。

Vehicle 位于 vehicle.gd 中:

  • 构造函数接收 vin、make、model 和 daily_rate;available 的初始值为 true。
  • start_rental() -> bool:如果车辆不可用,则返回 false;否则将车辆设为不可用并返回 true。
  • end_rental() 会让车辆重新变为可用。
  • _to_string() 返回 MAKE MODEL (VIN: VIN) - Available,或者在末尾返回 - Rented。

car.gd 中的 Car 和 motorcycle.gd 中的 Motorcycle 都继承 Vehicle。它们的构造函数接收车辆的四个值,以及 seats(汽车)或 engine_size(摩托车)。它们的 _to_string() 会在父类的文本基础上构建:Car: + 车辆文本 + - 5 seats,以及 Motorcycle: + 车辆文本 + - 600cc。

Rental 位于 rental.gd 中:

  • 构造函数接收 rental_id、vehicle 对象、customer_name 和 days;is_active 的初始值为 true。
  • calculate_cost() -> int:日租金乘以租赁天数。
  • end_rental() -> bool:如果租赁已经结束,则返回 false;否则结束租赁、结束车辆的租赁并返回 true。
  • _to_string():Rental ID: MAKE MODEL for CUSTOMER, D days, $COST - Active,或者 - Completed。

RentalAgency 位于 rental_agency.gd 中:

  • 构造函数接收 agency_name。vehicles 是一个从 VIN 映射到车辆的字典,rentals 是一个从租赁 ID 映射到租赁记录的字典,next_rental_id 的初始值为 1。
  • add_vehicle(vehicle) 会将车辆按其 VIN 保存。
  • rent_vehicle(vin, customer_name, days) -> String:如果 VIN 未知、天数少于 1 天,或者车辆不可用,则返回 ""。否则开始车辆租赁,创建 ID 为 R1、R2……的 Rental(只有租赁成功时计数器才会递增),保存该租赁并返回 ID。
  • return_vehicle(rental_id) -> bool:如果 ID 未知,则返回 false;否则返回该租赁的 end_rental() 所返回的值。
  • available_vehicles() -> Array[Vehicle]:按添加顺序返回可用车辆。
  • total_revenue() -> int:所有租赁费用的总和,包括进行中和已完成的租赁。

租赁记录会保存对应的车辆,但车辆不会保存对应的租赁,因此不会有两个对象互相指向。对于以下输入:

Speedy Rentals
car C1|Toyota|Camry|50|5
moto M1|Honda|CBR|40|600
rent C1|Ana|3
rent C1|Ben|2
available
kind M1
rentals
revenue

输出为:

Rented C1 as R1: $150
Cannot rent C1
Available at Speedy Rentals:
- Motorcycle: Honda CBR (VIN: M1) - Available - 600cc
M1: Vehicle true, Car false, Motorcycle true
Rental R1: Toyota Camry for Ana, 3 days, $150 - Active
Revenue: $150

将代码写在 vehicle.gd、car.gd、motorcycle.gd、rental.gd 和 rental_agency.gd 中。main.gd 包含提供的输入/输出代码,不能修改。

亲手试试

extends Node

func _ready():
	# 提供的输入/输出代码:保持原样。

	var agency := RentalAgency.new(OS.read_string_from_stdin())

	var line := OS.read_string_from_stdin()
	while line != "":
		var parts := line.split(" ", true, 1)
		var f: PackedStringArray = parts[1].split("|") if parts.size() > 1 else PackedStringArray()
		match parts[0]:
			"vehicle":
				agency.add_vehicle(Vehicle.new(f[0], f[1], f[2], int(f[3])))
			"car":
				agency.add_vehicle(Car.new(f[0], f[1], f[2], int(f[3]), int(f[4])))
			"moto":
				agency.add_vehicle(Motorcycle.new(f[0], f[1], f[2], int(f[3]), int(f[4])))
			"rent":
				var rental_id: String = agency.rent_vehicle(f[0], f[1], int(f[2]))
				if rental_id == "":
					print("Cannot rent ", f[0])
				else:
					var rental: Rental = agency.rentals[rental_id]
					print("Rented %s as %s: $%d" % [f[0], rental_id, rental.calculate_cost()])
			"return":
				print("Return ", f[0], ": ", agency.return_vehicle(f[0]))
			"available":
				print("Available at ", agency.agency_name, ":")
				for vehicle in agency.available_vehicles():
					print("- ", vehicle)
			"fleet":
				for vin in agency.vehicles:
					print(agency.vehicles[vin])
			"kind":
				var vehicle: Vehicle = agency.vehicles[f[0]]
				print("%s: Vehicle %s, Car %s, Motorcycle %s" % [f[0], vehicle is Vehicle, vehicle is Car, vehicle is Motorcycle])
			"rentals":
				for rental_id in agency.rentals:
					print(agency.rentals[rental_id])
			"revenue":
				print("Revenue: $", agency.total_revenue())

		line = OS.read_string_from_stdin()

面向对象编程中的所有课

自己练习: GDScript 在线编译器