2

わかりました、これは一種の一般的なプログラムです。ユーザーがコンピューター プレイヤーとやり取りできるポーカー プログラムを作成しようとしています。ただし、単純化するために、2 人のプレーヤーがコンピューターから数字を推測しようとする、はるかに単純なプログラムでテストしています。1 つは人間のプレーヤーで、もう 1 つはコンピューターのプレーヤーです。

ゲームでは、プレイヤーは順番に、プログラムによって設定された数字を推測します。コンピューター プレーヤーは数字をランダム化するだけで、ユーザーは数字を入力して推測ボタンを押す必要があります (または終了するオプションがあります)。

私の問題は、プレイヤーが行動するのが人間の場合、人間がボタンを押したりテキストを入力したりして応答するために、ゲームの実行を一時停止するにはどうすればよいですか?

タイマーを使用して開始し、スレッドが終了するのを待ってみましたが、それでもGUIがフリーズするようです。

また、バックグラウンド ワーカー スレッドからメッセージを送信して GUI を更新しようとしましたが、別のスレッドから GUI 要素にアクセスできないというエラーが表示されます。

これを実装する方法について何か提案はありますか?

これは完全なプログラムではないことに注意してください。これは、実行中に GUI と対話する方法を理解するために作成したものです。

数推測クラス:

public class NumberGuesser {

    public Player HumanPlayer { get; private set; }

    public Player ComputerPlayer { get; private set;}

    private Player[] _players = new Player[2];

    private int _maxNumber = 20;

    private bool _done = false;

    private Random random;

    public NumberGuesser() {

        HumanPlayer = new HumanPlayer("Me");

        ComputerPlayer = new ComputerPlayer("HAL9000");

        _players[0] = HumanPlayer;
        _players[1] = ComputerPlayer;

        random = new Random((int) DateTime.Now.Ticks);

    }

    public void Play() {

        var myNumber = random.Next(_maxNumber);
        var index = 0;
        while (!_done) {

            var currentPlayer = _players[index];

            var guess = currentPlayer.Act(_maxNumber);
            if (guess == myNumber) {
                currentPlayer.Score++;
            }

            index = (1 + index)%2;
        }

    }
}

コンピューター プレーヤー:

public class ComputerPlayer : Player {

    private readonly Random _random = new Random((int)DateTime.Now.Ticks);

    public ComputerPlayer(string name) : base(name) {
    }

    public override int Act(int max) {

        return _random.Next(max);

    }
}

人間のプレイヤー:

public class HumanPlayer : Player {

    public HumanPlayer(string name) : base(name) {

    }

    public override int Act(int max) {

        return UserGuess();

    }

    private int UserGuess() {


        return 0;

    }
}

プレイヤークラス:

public class Player {
    public string Name { get; private set; }
    public int Score { get; set; }

    public Player(string name) {
        Name = name;
    }


    public virtual int Act(int max) {
        // How should the human enter the guess here???
        return 0;
    }
}

私のメインウィンドウ:

<Window x:Class="GuessMyNumber.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="395" Width="728">
<Grid>
    <Label Content="Guess my number!" Height="28" HorizontalAlignment="Left" Margin="122,58,0,0" Name="label1" VerticalAlignment="Top" />
    <Grid Height="174" HorizontalAlignment="Left" Margin="31,170,0,0" Name="grid1" VerticalAlignment="Top" Width="272" DataContext="{Binding Path=HumanPlayer}">
        <Label Content="Human player" Height="28" HorizontalAlignment="Left" Margin="6,6,0,0" Name="label2" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="55,92,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" 
                 Text="{Binding Path=HumanGuess, UpdateSourceTrigger=PropertyChanged}"/>
        <Button Content="Guess" Height="23" HorizontalAlignment="Left" Margin="79,130,0,0" Name="button1" VerticalAlignment="Top" Width="75"
                Command="{Binding Path=GuessCommand}"/>
        <Label Content="{Binding Path=Name}" Height="28" HorizontalAlignment="Left" Margin="96,6,0,0" Name="label3" VerticalAlignment="Top" />
        <Label Content="Score" Height="28" HorizontalAlignment="Left" Margin="6,40,0,0" Name="label4" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="55,42,0,0" Name="textBox2" VerticalAlignment="Top" Width="75" Text="{Binding Path=Score, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
        <Button Content="Quit" Height="23" HorizontalAlignment="Left" Margin="182,130,0,0" Name="buttonQuit" VerticalAlignment="Top" Width="75" Command="{Binding Path=QuitCommand}" />
    </Grid>
    <Grid Height="174" HorizontalAlignment="Left" Margin="328,170,0,0" Name="grid2" VerticalAlignment="Top" Width="270" DataContext="{Binding Path=ComputerPlayer}" >

        <Label Content="Computer player" Height="28" HorizontalAlignment="Left" Margin="6,6,0,0"  VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="55,92,0,0"  VerticalAlignment="Top" Width="120" Text="{Binding Path=HumanGuess, UpdateSourceTrigger=PropertyChanged}"/>

        <Label Content="{Binding Path=Name}" Height="28" HorizontalAlignment="Left" Margin="111,6,0,0" VerticalAlignment="Top" />
        <Label Content="Score" Height="28" HorizontalAlignment="Left" Margin="6,40,0,0" VerticalAlignment="Top" />
        <TextBox Height="23" HorizontalAlignment="Left" Margin="55,42,0,0"  VerticalAlignment="Top" Width="75" Text="{Binding Path=Score, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
    </Grid>
    <Button Content="Start Playing" Height="23" HorizontalAlignment="Left" Margin="254,59,0,0" Name="buttonStartPlay" VerticalAlignment="Top" Width="75" Click="buttonStartPlay_Click" />
</Grid>

そして背後にあるコード:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {

    private readonly NumberGuesser _numberGuesser;

    public MainWindow() {
        InitializeComponent();
        _numberGuesser = new NumberGuesser();
        DataContext = _numberGuesser;

    }

    private void buttonStartPlay_Click(object sender, RoutedEventArgs e) {

        _numberGuesser.Play();

    }

}
4

2 に答える 2

1

その While ループを使用してゲームをプレイすることはありません。私はこのようなことをします:

private int numberToGuess = 0;

private void buttonStartPlay_Click(object sender, RoutedEventArgs e) 
{        
    numberToGuess = //Create Random Int;
}  

private void buttonHumanGuess_Click(object sender, RoutedEventArgs e) 
{        
    if(IsAnswerCorrect(//HumanGuess))
         //Human Wins
    else
        ComputerGuess();
        //Or
        MoveToNextPlayer();
}  

private void MoveToNextPlayer()
{
    //Do something to figure out who the next player is
}

private int ComputerGuess()
{
    //Do something to get computer answer
    if(IsAnswerCorrect(//ComputerGuess))
         //Computer Wins
}

private bool IsAnswerCorrect(int answer)
{
    if(answer == numberToGuess)
        return true;
    else
        return false;
}

これは非常に一般的ですが、アイデアはユーザーが何かを入力してから推測ボタンをクリックすることです。答えを処理した後、コンピューターの推測を実行します。

編集: @ティムs。ソリューションは、より高度な方法を処理します。タイマーがスコアリングの一部であるかどうかによっては、スレッドも使用する必要がある場合があります。これらはあなたの出発点になるはずです。

于 2012-05-14T21:46:12.983 に答える