Menu
CoddyTech

銀行システム

CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 63/65。

challenge icon

チャレンジ

難しい

2 種類の口座を持つ銀行を作成します。各操作は結果を表す辞書 {"ok": bool, "message": String} を返します。提供されているコードはこれを OK: MESSAGE または Failed: MESSAGE として出力します。すべての金額は float で、メッセージ内の金額はすべて $ の後に小数点以下2桁で表示されます。

transaction.gd の Transaction:コンストラクターは kind("deposit"、"withdrawal"、または "interest")と amount を受け取ります。_to_string() は、種類の先頭文字を大文字にしてから金額を返します:Deposit - $200.00。トランザクションは口座を保持しません。

account.gd の Account は @abstract クラスです:

  • コンストラクターは account_number、owner_name、initial_balance を受け取ります。金額はプライベートな _balance に保持されます。balance は読み取り専用プロパティで、ゲッターは _balance を返します。_history は Array[Transaction] で、get_history() はこれを返します。
  • 抽象メソッドは2つあります:account_type() -> String と withdrawal_error(amount: float) -> String です。後者は出金が拒否された理由、または "" を返します。
  • deposit(amount):金額が 0 以下の場合は Deposit amount must be positive を返して失敗します。それ以外の場合は金額を加算し、deposit トランザクションを記録して、Deposited $A. New balance: $B を返します。
  • withdraw(amount):金額が 0 以下の場合は Withdrawal amount must be positive を返して失敗します。withdrawal_error() が空でない文字列を返した場合は、その文字列を返して失敗します。それ以外の場合は金額を差し引き、withdrawal を記録して、Withdrew $A. New balance: $B を返します。残高が 0 未満になった場合は、その後に (Overdraft) が続きます。
  • _to_string() は TYPE NUMBER (OWNER): $BALANCE を返します。

savings_account.gd の SavingsAccount は Account を継承し、定数 INTEREST_RATE = 0.02 と MIN_BALANCE = 100.0 を持ちます。口座の種類は Savings です。出金後の残高が MIN_BALANCE 未満になる場合は、Cannot withdraw below minimum balance of $100.00 を返して拒否されます。apply_interest() は balance * INTEREST_RATE を加算し、interest トランザクションを記録して、Applied interest: $I. New balance: $B を返します。

checking_account.gd の CheckingAccount は Account を継承し、定数 OVERDRAFT_LIMIT = 200.0 を持ちます。口座の種類は Checking です。残高は -200.00 まで下げることができます。それより低くなる出金は、Cannot exceed overdraft limit of $200.00 を返して拒否されます。

bank.gd の Bank は、口座番号をキーにしたプライベートな辞書に口座を保持します:

  • コンストラクターは bank_name を受け取ります。
  • create_account(kind, account_number, owner_name, initial_balance) はファクトリーです。kind は大文字・小文字を問わず savings または checking です。Account number already exists または Invalid account type を返して失敗します。それ以外の場合は Savings account created successfully(または Checking)を返します。
  • get_account(account_number) -> Account は口座、または null を返します。
  • transfer(from_number, to_number, amount):One or both accounts not found を返して失敗します。最初の口座から出金し、それが失敗した場合は、Transfer failed: に出金のメッセージを続けて返します。それ以外の場合は2番目の口座に入金し、Transferred $A from FROM to TO を返します。
  • total_holdings() -> float はすべての残高の合計を返します。

提供されているコードは銀行名を読み取り、その後コマンドを読み取ります。次の入力に対して:

First Bank
open savings|S1|Alice|1000
open checking|C1|Bob|50
withdraw S1|950
transfer S1|C1|300
withdraw C1|400
history C1
total

出力は次のとおりです:

OK: Savings account created successfully
OK: Checking account created successfully
Failed: Cannot withdraw below minimum balance of $100.00
OK: Transferred $300.00 from S1 to C1
OK: Withdrew $400.00. New balance: $-50.00 (Overdraft)
History of C1:
1. Deposit - $300.00
2. Withdrawal - $400.00
Total held by First Bank: $650.00

コードは transaction.gd、account.gd、savings_account.gd、checking_account.gd、bank.gd に記述します。main.gd には提供されている入出力コードが含まれており、編集できません。

自分で試してみよう

extends Node

func _ready():
	# 提供された入出力コード: そのままにしてください

	var bank := Bank.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]:
			"open":
				show_result(bank.create_account(f[0], f[1], f[2], float(f[3])))
			"deposit":
				show_result(bank.get_account(f[0]).deposit(float(f[1])))
			"withdraw":
				show_result(bank.get_account(f[0]).withdraw(float(f[1])))
			"interest":
				var account: Account = bank.get_account(f[0])
				if account is SavingsAccount:
					var savings := account as SavingsAccount
					show_result(savings.apply_interest())
				else:
					print("Failed: ", f[0], " is not a savings account")
			"transfer":
				show_result(bank.transfer(f[0], f[1], float(f[2])))
			"history":
				var history: Array = bank.get_account(f[0]).get_history()
				print("History of ", f[0], ":")
				for i in history.size():
					print(i + 1, ". ", history[i])
			"account":
				print(bank.get_account(f[0]))
			"total":
				print("Total held by %s: $%.2f" % [bank.bank_name, bank.total_holdings()])

		line = OS.read_string_from_stdin()

func show_result(result: Dictionary) -> void:
	print(("OK: " if result["ok"] else "Failed: ") + result["message"])

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: GDScriptオンラインコンパイラ