好的,所以这是一种通用程序。我正在尝试编写一个扑克程序,用户可以在其中与计算机玩家互动。但是,为了简化它,我正在使用一个更简单的程序进行测试,其中两个玩家试图从计算机中猜测一个数字。一个是人类玩家,另一个是电脑玩家。
在游戏中,玩家轮流猜测程序设置的蜜蜂数量。电脑播放器只是随机化数字,用户应该输入一个数字并按下猜测按钮(或者可以选择退出)。
我的问题是,当人类玩家轮流行动时,我如何暂停游戏的执行,以便人类通过按下按钮或输入文本来做出响应?
我尝试过使用 Timer 并启动它并等待线程结束,但似乎它仍然冻结了 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();
}
}