【Silverlight】汉诺塔游戏,带AI
生活随笔
收集整理的這篇文章主要介紹了
【Silverlight】汉诺塔游戏,带AI
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先看效果
?
?
完整代碼在此下載/Aimeast/SLAnyHanoi.zip
?
簡單的把設計說明一下
ViewModel 和 Model 的設計如下:
?
用到了其中的動畫效果用的是自己實現的行為(Behavior)。
using System; using System.Windows; using System.Windows.Interactivity; using System.Windows.Media.Animation;namespace AnyHanoi {public class DiscFluidMoveBehavior : Behavior<FrameworkElement>{public Point Translate{get { return (Point)GetValue(TranslateProperty); }set { SetValue(TranslateProperty, value); }}// Using a DependencyProperty as the backing store for Translate. This enables animation, styling, binding, etc...public static readonly DependencyProperty TranslateProperty =DependencyProperty.Register("Translate", typeof(Point), typeof(DiscFluidMoveBehavior), new PropertyMetadata(Translate_PropertyChangedCallback));private static void Translate_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e){Point p = (Point)e.NewValue;DiscFluidMoveBehavior b = (DiscFluidMoveBehavior)d;try{b.Update(p);}catch { }}private void Update(Point p){Storyboard storyboard = new Storyboard();DoubleAnimation x = new DoubleAnimation();DoubleAnimation y = new DoubleAnimation();x.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateX)"));y.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateY)"));x.Duration = this.Duration;y.Duration = this.Duration;x.To = p.X;y.To = p.Y;Storyboard.SetTarget(x, base.AssociatedObject);Storyboard.SetTarget(y, base.AssociatedObject);storyboard.Children.Add(x);storyboard.Children.Add(y);storyboard.Begin();}public Duration Duration{get { return (Duration)GetValue(DurationProperty); }set { SetValue(DurationProperty, value); }}// Using a DependencyProperty as the backing store for Duration. This enables animation, styling, binding, etc...public static readonly DependencyProperty DurationProperty =DependencyProperty.Register("Duration", typeof(Duration), typeof(DiscFluidMoveBehavior), new PropertyMetadata(new Duration(TimeSpan.FromSeconds(0.1))));} }需要事先引用 Expression 的 System.Windows.Interactivity 程序集。
把這個行為應用到每個Items。
?
AI的設計如下:
?
方法是遞歸求解。
基本思想和標準狀態的思想是一樣的。把最大的盤子移動到某個目標柱子,需要找到一個暫存柱子。然后按照這一思想進行遞歸求解。直到剩下最后一個盤子,就可以直接移動。
?
遞歸求解的核心代碼如下
private void RecSolve(Puzzle puzzle){int max = 0;Peg maxPeg = null;//找出當前狀態下最大盤子所在的柱子foreach (Peg peg in puzzle.PegCollection){if (peg.Count > 0 && max < peg.Buttom){max = peg.Buttom;maxPeg = peg;}}//當前狀態只有一個盤子,直接移動if (puzzle.PegA.Count + puzzle.PegB.Count + puzzle.PegC.Count == 1){if (maxPeg.PegID != puzzle.DestPeg)Move(maxPeg, puzzle.GetPeg(puzzle.DestPeg));return;}//當前狀態有多個盤子if (maxPeg.PegID == puzzle.DestPeg) //最大的盤子就在目標柱子上,不需要移動{RecSolve(puzzle.NewLevelPuzzle(maxPeg.PegID, puzzle.DestPeg));}else //最大的盤子不在目標柱子上,需要移動{//找出臨時柱子,即 不是 目標柱子 也不是 最大盤子所在的柱子Pegs tempPagID = Pegs.A;if (tempPagID == maxPeg.PegID || tempPagID == puzzle.DestPeg) tempPagID = Pegs.B;if (tempPagID == maxPeg.PegID || tempPagID == puzzle.DestPeg) tempPagID = Pegs.C;//把當前狀態 去掉最大盤子以后的新狀態 繼續遞歸處理//這一步把所有盤子都移動到臨時柱子上RecSolve(puzzle.NewLevelPuzzle(maxPeg.PegID, tempPagID));//把當前最大盤子移動到目標柱子上Move(maxPeg, puzzle.GetPeg(puzzle.DestPeg));//把上一步處理好的狀態 去掉最大的盤子以后的狀態//即 所有盤子都在臨時柱子 的 狀態移動到目標狀態RecSolve(puzzle.NewLevelPuzzle(puzzle.DestPeg, puzzle.DestPeg));}}?
歡迎大家的評論!
轉載于:https://www.cnblogs.com/Aimeast/archive/2011/04/02/2003917.html
總結
以上是生活随笔為你收集整理的【Silverlight】汉诺塔游戏,带AI的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Load Runner测试脚本(tuxe
- 下一篇: Visual C++ 菜单