Jason Down の提案は賢明で、新しいGuessingGame
クラスを作成してプロジェクトに追加します。「グローバル変数」 (誰もが絶対に必要でない限り絶対に使用しないように学校で教えられている) について心配していることは知っていますが、設計仕様について少し考えてみてください。
ただし、「Guess」ボタンのイベント ハンドラーが複数回呼び出される場合は、数値をフォームのインスタンス変数として格納する必要があります。確かに大したことではありませんが、数値は Form ではなく、現在のゲームを指示するメソッドのプロパティであるべきだと思います。
GuessingGame
別の方法として、クラスのインスタンスをフォームに保存します。これはグローバル変数ではありません! あなたは自分で言った、ゲームのポイントは、推測を追跡し、「再生」をクリックするたびに推測する新しい数字を生成することです。ゲームのインスタンスをフォームに保存してから別のフォーム (ヘルプやバージョン情報ボックスなど) を開くと、ゲームのインスタンスは利用できなくなります (つまり、グローバルではありません)。
オブジェクトは次のGuessingGame
ようになります。
public class GuessingGame
{
private static Random _RNG = new Random();
private bool _GameRunning;
private bool _GameWon;
private int _Number;
private int _GuessesRemaining;
public int GuessesRemaining
{
get { return _GuessesRemaining; }
}
public bool GameEnded
{
get { return !_GameRunning; }
}
public bool GameWon
{
get { return _GameWon; }
}
public GuessingGame()
{
_GameRunning = false;
_GameWon = false;
}
public void StartNewGame(int numberOfGuesses, int max)
{
if (max <= 0)
throw new ArgumentOutOfRangeException("max", "Must be > 0");
if (max == int.MaxValue)
_Number = _RNG.Next();
else
_Number = _RNG.Next(0, max + 1);
_GuessesRemaining = numberOfGuesses;
_GameRunning = true;
}
public bool MakeGuess(int guess)
{
if (_GameRunning)
{
_GuessesRemaining--;
if (_GuessesRemaining <= 0)
{
_GameRunning = false;
_GameWon = false;
return false;
}
if (guess == _Number)
{
_GameWon = true;
return true;
}
else
{
return false;
}
}
else
{
throw new Exception("The game is not running. Call StartNewGame() before making a guess.");
}
}
}
このようにして、ゲームに関連するすべてのデータがクラス内にカプセル化されます。イベントの接続は、フォームのコード ビハインドで簡単です。
GuessingGame game = new GuessingGame();
private void btnPlay_Click(object sender, EventArgs e)
{
int numberOfGuesses = Convert.ToInt32(txtNumberOfGuesses.Text);
int max = Convert.ToInt32(txtMax.Text);
game.StartNewGame(numberOfGuesses, max);
}
private void btnGuess_Click(object sender, EventArgs e)
{
int guess = Convert.ToInt32(txtGuess.Text);
bool correct = game.MakeGuess(guess);
if (correct)
lblWin.Visible = true;
if (game.GameEnded)
{
// disable guess button, show loss label
}
}