Skip to content

Instantly share code, notes, and snippets.

@poyoppo
Created October 10, 2020 01:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save poyoppo/904ec3acca61b0ded405563010696a7c to your computer and use it in GitHub Desktop.
Save poyoppo/904ec3acca61b0ded405563010696a7c to your computer and use it in GitHub Desktop.
プレイヤーのHPを表すクラスと、そのテストクラス
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Representation of player's HP.
/// </summary>
public class PlayerHp
{
#region Private Fields
private int maxHp = 4;
private int currentHp = 4;
private int piecePossession = 0;
#endregion
#region Public Properties
public int MaxHp { get { return maxHp; } }
public int CurrentHp { get { return currentHp; } }
public int PiecePossession { get { return piecePossession; } }
public bool IsFull { get { return CurrentHp == MaxHp; } }
public bool IsDead { get { return CurrentHp == 0; } }
#endregion
/// <summary>
/// One heart is made from 4 pieces of heart.
/// </summary>
private const int PIEACE_AMOUNT = 4;
#region Constractor
/// <summary>
/// Representation of player's HP.
/// </summary>
/// <param name="initialHeartCount">Initial value of the number of hearts.Should be a positive value.</param>
public PlayerHp(int initialHeartCount)
{
if (initialHeartCount <= 0)
{
throw new TypeInitializationException(typeof(PlayerHp).FullName,
new ArgumentOutOfRangeException());
}
int initHp = initialHeartCount * PIEACE_AMOUNT;
maxHp = initHp;
currentHp = initHp;
}
#endregion
#region Public Mathods
/// <summary>
/// Recover HP.
/// </summary>
/// <param name="healPoint">Recovery amount. Should be a positive value.</param>
public void Heal(int healPoint)
{
if(healPoint < 0)
{
throw new ArgumentOutOfRangeException();
}
// 既にフルHPだったらリターン
if (IsFull) return;
currentHp += healPoint;
if(currentHp > maxHp)
{
currentHp = maxHp;
}
}
/// <summary>
/// Damages HP.
/// </summary>
/// <param name="damagePoint">Damage amount. Should be a positive value.</param>
public void Damage(int damagePoint)
{
if(damagePoint < 0)
{
throw new ArgumentOutOfRangeException();
}
currentHp -= damagePoint;
if(currentHp < 0)
{
currentHp = 0;
}
}
/// <summary>
/// Increase max HP by amount of one heart.
/// </summary>
/// <param name="fullHp">Whether to fully recover HP at the same time. default is true.</param>
public void MaxHpUp(bool fullHp = true)
{
maxHp += PIEACE_AMOUNT;
if (fullHp)
{
currentHp = maxHp;
}
}
/// <summary>
/// Increase piece of hearts possession. If have four, increase max HP by amount of one heart.
/// </summary>
/// <param name="fullHp">Whether to fully recover HP at the same time. default is true.</param>
public void GetPieceOfHeart(bool fullHp = true)
{
piecePossession++;
// 4つ集まっていたら1up.
if(piecePossession == PIEACE_AMOUNT)
{
MaxHpUp(fullHp);
piecePossession = 0;
return;
}
if (fullHp)
{
currentHp = maxHp;
}
}
#endregion
}
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace Tests
{
/// <summary>
/// PlayerHp class's test.
/// </summary>
public class PlayerHpTest
{
#region Constractor Tests
[TestCase(1), TestCase(2), TestCase(3)]
public void A_コンストラクタテスト(int initialHeartCount)
{
var playerHp = new PlayerHp(initialHeartCount);
// playerHp が存在する
Assert.That(playerHp, Is.Not.Null);
//Assert.That(playerHp, Is.Not.Null, message: "playerHpが存在しない");
// 最大HP, 現在のHPの初期値は initialHearCount の4倍である
Assert.That(playerHp.MaxHp, Is.EqualTo(initialHeartCount * 4));
Assert.That(playerHp.CurrentHp, Is.EqualTo(initialHeartCount * 4));
// ハートのかけらなんて持ってません。
Assert.That(playerHp.PiecePossession, Is.EqualTo(0));
}
[TestCase(0), TestCase(-1)]
public void A_コンストラクタの引数に0以下を渡すと例外が発生する(int initialHeartCount)
{
TypeInitializationException ex = Assert.Throws<TypeInitializationException>(() => new PlayerHp(initialHeartCount));
Assert.AreEqual(ex.TypeName, typeof(PlayerHp).FullName);
Assert.That(ex.InnerException, Is.TypeOf<ArgumentOutOfRangeException>());
}
#endregion
#region Property Tests
[Test]
public void D_IsFullプロパティテスト()
{
var playerHp = new PlayerHp(3);
  // ダメージを受けていなければ IsFull = true
Assert.That(playerHp.IsFull, Is.True);
// ダメージ
playerHp.Damage(3);
// ダメージを受けていればフルHPではないので IsFull = false
Assert.That(playerHp.IsFull, Is.False);
}
[Test]
public void D_IsDeadプロパティテスト()
{
var playerHp = new PlayerHp(1);
// まだ生きているので IsDead = false
Assert.That(playerHp.IsDead, Is.False);
// korosu
playerHp.Damage(100);
// おまえはもうしんでいぬ。
Assert.That(playerHp.IsDead, Is.True);
}
#endregion
#region Heal Method Tests
[Test]
public void G_回復メソッドテスト()
{
var playerHp = new PlayerHp(3);
var heal = 3;
// HPを減らしておく
playerHp.Damage(8);
// 回復前のHP
var beforeHp = playerHp.CurrentHp;
// 回復
playerHp.Heal(heal);
// 回復後のHP
var afterHp = playerHp.CurrentHp;
Assert.That(afterHp, Is.GreaterThan(beforeHp));
Assert.That(afterHp, Is.EqualTo(beforeHp + heal));
//Debug.LogFormat("【回復量 : {2}】前 : {0}, 後 : {1}, {0} + {2} = {1}", beforeHp, afterHp, heal);
}
[Test]
public void G_HPは最大HPを超えない()
{
var playerHp = new PlayerHp(3);
// HPフル回復のままさらに回復を試みる
playerHp.Heal(3);
// だけど最大HPのまま
Assert.That(playerHp.CurrentHp, Is.EqualTo(playerHp.MaxHp));
// ダメージを受ける(12 - 3 = 9)
playerHp.Damage(3);
// 受けたダメージ以上を回復(9 + 5 = 14 → 12 : MaxHp)
playerHp.Heal(5);
Assert.That(playerHp.CurrentHp, Is.EqualTo(playerHp.MaxHp));
}
[Test]
public void G_回復メソッドの引数に負の値を指定すると例外が発生する()
{
var playerHp = new PlayerHp(3);
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => playerHp.Heal(-10));
}
#endregion
#region Damage Method Tests
[Test]
public void H_ダメージメソッドテスト()
{
var playerHp = new PlayerHp(3);
var dmg = 3;
// ダメージ前のHP
var beforeHp = playerHp.CurrentHp;
playerHp.Damage(dmg);
// ダメージ後のHP
var afterHp = playerHp.CurrentHp;
Assert.That(afterHp, Is.LessThan(beforeHp));
Assert.That(afterHp, Is.EqualTo(beforeHp - dmg));
//Debug.LogFormat("【ダメージ : {2}】前 : {0}, 後 : {1}, {0} - {2} = {1}", beforeHp, afterHp, dmg);
}
[Test]
public void H_HPは負の値にならない()
{
var playerHp = new PlayerHp(1);
// 大ダメージを受ける
playerHp.Damage(100);
// どんなに大きいダメージを受けても負の値にはならず、0で留まる
Assert.That(playerHp.CurrentHp, Is.EqualTo(0));
}
[Test]
public void H_ダメージメソッドの引数に負の値を指定すると例外が発生する()
{
var playerHp = new PlayerHp(3);
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => playerHp.Damage(-10));
}
#endregion
#region MaxHpUp Method Tests
[Test]
public void I_最大HP増加テスト()
{
var playerHp = new PlayerHp(3);
// 最大HPアップ前
var before = playerHp.MaxHp;
// 最大HPアップ。同時に全回復もする
playerHp.MaxHpUp();
// 最大HPアップ後
var after = playerHp.MaxHp;
Assert.That(after, Is.EqualTo(before + 4));
Assert.That(playerHp.CurrentHp, Is.EqualTo(playerHp.MaxHp));
}
[Test]
public void I_最大HP増加時に同時に全回復しないときのテスト()
{
var playerHp = new PlayerHp(3);
// 一応ダメージを与えておく
playerHp.Damage(5);
// 最大HPアップ前の現在のHP
var before = playerHp.CurrentHp;
// 最大HPアップ。同時に全回復はしない
playerHp.MaxHpUp(fullHp: false);
// 最大HPアップ後の現在のHP
var after = playerHp.CurrentHp;
Assert.That(after, Is.EqualTo(before));
}
#endregion
#region GetPieceOfHeart Method Tests
[Test]
public void J_ハートのかけら4つ集まったら1アップテスト()
{
var playerHp = new PlayerHp(3);
Assert.That(playerHp.PiecePossession, Is.EqualTo(0));
var before = playerHp.MaxHp;
// ハートのかけらを手に入れる
playerHp.GetPieceOfHeart();
playerHp.GetPieceOfHeart();
playerHp.GetPieceOfHeart();
playerHp.GetPieceOfHeart(); // 一気に4つも手に入れちゃったぜ
Assert.That(playerHp.PiecePossession, Is.EqualTo(0));
var after = playerHp.MaxHp;
Assert.That(after, Is.EqualTo(before + 4));
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment