Tech commitの課題で、面白そうなテーマだったので、挑戦してみました。
https://github.com/takishita2nd/battle_rpg
- 勇者と魔王が交互に攻撃する
- 一定確率で攻撃を回避する
- 一定確率でクリティカルヒット(ダメージ1.5倍)になる
- どっちが勝利したかを表示する
using System;
namespace battle_rpg
{
public static class Common
{
public static bool roleJudge(int rate)
{
bool judge = false;
Random r = new Random();
int value = r.Next(0, 100);
if(value < rate) {
judge = true;
}
return judge;
}
}
}
これは乱数を使って、命中やクリティカル判定などの確率判定を行うメソッドです。
引数に確率(%)を受け取り、乱数を0〜100の範囲で発生させて、その値が確率以下ならばtrueを返します。
using System;
namespace battle_rpg
{
public class Charactor
{
private const String Statusformat = "{0}:HP{1} 攻撃力{2}";
private const String AttackFormat = "{0}の攻撃!{1}に{2}のダメージ";
private const String CriticalAttackFormat = "{0}の攻撃!クリティカルヒット!{1}に{2}のダメージ";
private const String EvasionFormat = "{0}の攻撃!{1}は攻撃をかわした";
public string Name {get;}
public int Hp {get; set;}
public int Attack {get;}
public int evasionRate { get;}
public int criticalRate { get;}
public Charactor(string _name, int _hp, int _attack)
{
this.Name = _name;
this.Hp = _hp;
this.Attack = _attack;
this.evasionRate = 5;
this.criticalRate = 5;
}
/**
* ターゲットを攻撃
* <param> _target 攻撃対象
* <return> 与えたダメージ
*/
public String doAttack(Charactor _target)
{
String message = String.Empty;
if(isHit(_target)) {
int damage = this.Attack;
if(isCritical()) {
damage = (int)(damage * 1.5);
message = String.Format(CriticalAttackFormat, this.Name, _target.Name, damage);
} else {
message = String.Format(AttackFormat, this.Name, _target.Name, damage);
}
_target.Hp -= damage;
} else {
message = String.Format(EvasionFormat, this.Name, _target.Name);
}
return message;
}
/**
* 命中判定
* <param> _target 攻撃対象
* <return> true:命中
*/
private bool isHit(Charactor _target)
{
bool hit = true;
if(Common.roleJudge(_target.evasionRate)) {
hit = false;
}
return hit;
}
/**
* クリティカル判定
* <return> true:クリティカル
*/
private bool isCritical()
{
bool critical = false;
if(Common.roleJudge(this.criticalRate)) {
critical = true;
}
return critical;
}
/**
* 死亡判定
* <return> true:死亡
*/
public bool isDie()
{
bool die = false;
if(this.Hp <= 0) {
die = true;
}
return die;
}
public String showStatus()
{
return String.Format(Statusformat, this.Name, this.Hp, this.Attack);
}
}
}
勇者や魔王を扱うクラスです。
このクラスの中でHPや攻撃力などを保持します。
メインはdoAttack()メソッド。この中で命中判定やクリティカル判定をおこない、攻撃対象(引数)のHPを減らしていきます。
using System;
namespace battle_rpg
{
public class Battle
{
private Charactor yusha;
private Charactor maou;
private const String DieFormat = "{0}は倒れた。";
public Battle()
{
yusha = new Charactor("勇者", 300, 15);
maou = new Charactor("魔王", 400, 9);
}
public void execute()
{
bool nowBattle = true;
while(nowBattle) {
// HP表示
Console.WriteLine(yusha.showStatus());
Console.WriteLine(maou.showStatus());
Console.WriteLine();
// 勇者の攻撃
Console.WriteLine(yusha.doAttack(maou));
// 魔王死亡判定
if(maou.isDie()) {
Console.WriteLine();
Console.WriteLine(DieFormat, maou.Name);
nowBattle = false;
Console.WriteLine("世界に平和が訪れた。");
}
if(nowBattle == false) {
return;
}
// 魔王の攻撃
Console.WriteLine(maou.doAttack(yusha));
// 勇者死亡判定
if(yusha.isDie()) {
Console.WriteLine();
Console.WriteLine(DieFormat, yusha.Name);
nowBattle = false;
Console.WriteLine("世界は征服された。");
}
Console.WriteLine();
}
}
}
}
実際にバトルを行うクラスです。
コンストラクタで勇者と魔王のステータスを設定、execute()でどちらかが負けるまでループを行います。
using System;
namespace battle_rpg
{
class Program
{
static void Main(string[] args)
{
Battle battle = new Battle();
battle.execute();
}
}
}
メイン関数。Battleクラスをインスタンス化してexecute()を実行しているだけです。
とりあえず、こんな感じで要求されている処理はできました。
カスタマイズすれば色々と拡張できそうですね。