我是C#中的线程新手,尽管我读了很多关于线程的理论,但在实践中对我并没有太大的帮助。
我想编写一个跳棋游戏的AI函数(minmax alphabeta),并在一个不同的线程中执行它。
有4种选择:常规踏面,线程池,异步委托,BackgroundWorker。
对我来说,BackgroundWorker似乎是最理想的,它有完成任务的委托,这样我就可以运行"makemove“函数,它实际上将在板上进行计算的移动,并更新进度条。
我对此有三个问题:
case?
任何帮助都将不胜感激。
发布于 2011-12-18 21:01:46
1)所有这些解决方案都会奏效;您只需使用一些不同的逻辑来处理每个解决方案。
2)当您有一组可以在多个线程上执行的东西时,ThreadPool也是有用的(例如,在中国车臣游戏中,您可以通过ThreadPool运行5种不同的人工智能模拟,它将在一台有两个核的计算机上运行,而使用线程会由于上下文切换而减慢进程)。它当然适用于您的情况--您只需排队等待第二个AIEvaluation或其他什么东西,它就会尽快开始执行。
3)嗯,不完全是这样。计算机在运行alphabeta (大概有一定的截止深度:P)之后才能真正采取行动,所以AI线程无论如何都要完成它的工作。您只需每次使用ThreadPool/Back基即可。
关于BackgroundWorker的一些一般信息:当您有“额外”的CPU时间时,它就会运行,所以如果您的主线程由于某种原因占用CPU,它将不会做很多事情。使用正常的ThreadPool可能更好。
假设您的程序在AI打开主线程时调用AIAct()。另外,让timerTick成为一个存在于Windows中的定时器。此外,让我们来看看AIState和GameBoard类,它们封装了alpha-beta所需的功能。
using System.Threading;
const int CUTOFF_DEPTH = 6;//Maximum plys for alpha-beta
AIState state;
void AIAct()
{
state = new AIState( this.GameBoard.GetState() );
ThreadPool.QueueUserWorkItem(RunMinimax, state);
//assume that timerTick is a Timer (Windows Forms Timer) that ticks every 100 ms
timerTick.Enabled = true;
}
void timerTick_Tick(object sender, EventArgs e)
{
if (state.IsComplete)
{
ExecuteAction(state.Result);
timerTick.Enabled = false;
//whatever else you need to do
}
}
private static void RunMinimax(object args)
{
AIState state = args as AIState;
if (state == null)
{
//error handling of some sort
Thread.CurrentThread.Abort();
}
//run your minimax function up to max depth of CUTOFF_DEPTH
state.Result = Minimax( /* */ );
state.IsComplete = true;
}
private class AIState
{
public AIState(GameBoard board)
{
this.Board = board;
}
public readonly GameBoard Board;
public AIAction Result;
public volatile bool IsComplete;
}https://stackoverflow.com/questions/8554643
复制相似问题