0

GUI を使用して単純な数当てゲームを作成しています。ユーザーがテキストボックスに数字を入力して「OK」を押すのを待っているループを待つ必要があります。ループ内でイベントを待機するにはどうすればよいですか?

注: メッセージ ボックスは必要ありません。これはメイン ウィンドウで行われるため、入力を待つ必要があります。

編集:私は自分自身をもっとよく説明すべきでした。GUI 内にループがあることはわかっています。私が欲しいのは、メソッド内の別のループです。たぶん、これを行うためのより良い方法があります。考えてみると、ボタンのイベント ハンドラー内にコードを記述できます。グローバル変数が必要ですが。いずれにせよ、私はそれについて考えますが、私の質問が今より明確になることを願っています.

EDIT 2:私の質問が明確ではなく、編集があまり役に立たなかったことを申し訳ありません。まず、コードが大きすぎてここに掲載できません。おそらく GUI のスクリーンショットを投稿する必要があるので、あまり役に立ちません。基本的に、「最大数」と「許容される推測の数」の 2 つのフィールドがあります。ユーザーはこの2つを入力して「再生」をクリックします。テキストボックスと「推測」ボタンを備えた新しいパネルが利用可能になります。ユーザーが推測を入力すると、プログラムはそれが正しいかどうかを確認します。

2 番目の無限ループの目的は、グローバル変数を回避することです。ユーザーが「再生」をクリックするたびに、ゲームは正しい推測として新しい乱数を生成する必要があります。すべてがメソッド内で行われる場合、問題はありません。ただし、「Guess」ボタンのイベント ハンドラーが複数回呼び出される場合は、数値をフォームのインスタンス変数として格納する必要があります。確かに大したことではありませんが、数値は Form ではなく、現在のゲームを指示するメソッドのプロパティであるべきだと思います。

また、メソッドの外で推測の残りの数を追跡する必要があります。繰り返しますが、大したことではありません。可能であれば、グローバルを避けたいだけです。

繰り返しますが、私の質問が明確ではなく、申し訳ありません。ちょっと疲れていて、あまり書く気になれませんでした。これでもはっきりしない場合は、気にしないでください。何か考えてみます。

4

5 に答える 5

5

C# は、フォームが閉じられるまでイベントを待機して自動的に無限にループします。ボタンクリックイベントに応答するだけです。

于 2009-06-17T03:50:39.560 に答える
3

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
    }
}
于 2009-06-17T05:12:01.810 に答える
1

実際に Windows プログラミングを学ぶには、おそらく本を探す必要があります。

非常に基本的なこと:

1)Windowsコードのどこかにすでに無限ループが深くあります。Windows プログラムは常にループして入力をスキャンしています。

2) 入力が見つかると、このループはイベントを発生させます。

3) あなたの使命は、それを受け入れることを選択した場合、それらのイベントを処理するイベント ハンドラーを作成することです。

于 2009-06-17T03:52:18.920 に答える
1

すでに指摘されているように、間違っている可能性が高いですが、これを使用できます

Application.DoEvents();

実際のループにいるときにイベントを処理する

正しい方法で行うには - ループを使用しないでください - 入力に編集ボックスを使用してからボタンを使用します - ボタンの onclick イベントを実装します

于 2009-06-17T03:56:15.113 に答える
1

はい、音声イベントを待っている場合、関数の実行中にいつでもイベントが発生する可能性があります。関数を再帰的に呼び出さずに処理する必要があります

于 2009-11-23T15:17:56.633 に答える