RPGキャラクター
CoddyのCジャーニー「Object Oriented Programming」セクションの一部 — レッスン 58/61。
チャレンジ
簡単構造体、メソッド、コンストラクタ、そしてオブジェクト間の相互作用を、クリーンでモジュール化された設計でまとめる古典的な例である、RPGキャラクターの戦闘システムを構築しましょう。
コードは以下の3つのファイルに分けて構成します:
character.h: 2つの整数フィールドhealthとdamageを持つCharacter構造体を定義します。キャラクターの作成、攻撃の実行、生存確認、およびステータスの表示を行うための関数プロトタイプを宣言します。character.c: キャラクターシステムを実装します:create_character— 初期体力とダメージ値を受け取り、ヒープ上に Character を割り当て、そのフィールドを初期化して、ポインタを返します。attack— 2つの Character ポインタ(攻撃者とターゲット)を受け取り、ターゲットの体力を攻撃者のダメージ分だけ減らします。is_alive— const Character ポインタを受け取り、体力が0より大きい場合は1を、そうでなければ0を返します。print_status— const Character ポインタを受け取り、キャラクターの体力をHealth: Xという形式で表示します。free_character— 割り当てられたメモリを解放します。
main.c: 戦闘シミュレーションを作成します!ヒーローの体力、ヒーローのダメージ、敵の体力、敵のダメージを表す4つの整数を読み取ります。コンストラクタを使用して両方のキャラクターを作成します。次に、戦闘ラウンドをシミュレートします。ヒーローが最初に攻撃し、次に敵が(まだ生きている場合)攻撃します。どちらかのキャラクターが倒れるまで続けます。各ラウンドの後、両方のキャラクターのステータスを表示します(ヒーローが先、次に敵)。戦闘が終了したら、生き残った方に応じてHero wins!またはEnemy wins!のいずれかを表示します。両方のキャラクターを解放することを忘れないでください。
プログラムは4つの入力を受け取ります:
- ヒーローの初期体力
- ヒーローの1攻撃あたりのダメージ
- 敵の初期体力
- 敵の1攻撃あたりのダメージ
入力が 50, 20, 30, 15 の場合の出力例:
Health: 35
Health: 10
Health: 20
Health: -10
Hero wins!入力が 20, 5, 100, 25 の場合の出力例:
Health: -5
Health: 95
Enemy wins!ヘッダーファイルではインクルードガードを使用することを忘れないでください。attack 関数は、あるオブジェクトが別のオブジェクトの内部状態をどのように変更できるかを示す、オブジェクト指向設計における重要な概念です。データを読み取るだけの関数には、適切に const ポインタを使用してください。
自分で試してみよう
#include <stdio.h>
#include "character.h"
int main() {
// 入力値を読み込む
int hero_health, hero_damage, enemy_health, enemy_damage;
scanf("%d", &hero_health);
scanf("%d", &hero_damage);
scanf("%d", &enemy_health);
scanf("%d", &enemy_damage);
// TODO: create_character を使用してヒーローと敵のキャラクターを作成する
// TODO: 戦闘ラウンドをシミュレートする
// - ヒーローが先に攻撃する
// - 敵がまだ生きている場合は攻撃する
// - 各ラウンドの後に両方のキャラクターのステータスを表示する(ヒーローが先、次に敵)
// - どちらかのキャラクターが倒れるまで継続する
// TODO: 勝者を表示する ("Hero wins!" または "Enemy wins!")
// TODO: 両方のキャラクターを解放する
return 0;
}