• windows phone 小应用与随机算法的感悟


    最近一直想自己写点windows phone 上的应用,但是一直都在纠结主题和素材。最终决定了先做点什么出来,不管是不是很foolish。

    我想写个小游戏,可以锻炼大家短暂记忆力的那种,目前在很多平台上都有类似的。大概思路如下:

    默认会有n*m张牌倒扣着,只能看到背面。当点击某两张时,对比是否相同,如果相同则消掉,给予相对应的分数奖励,否则这两张牌都重新显示背面(用短暂记忆去记住牌色),直到全部消掉。

    原始核心思路:

    牌的属性:

    1. 颜色。(如果是高级难度的,可以加张png图片,同时比较颜色和图片是否相同)

    2. 位置。(是在第几列第几行)。

    1. 生成随机List<Color>,List<Card>。listColor中的元素个数需要是listCard个数的一半,因为每种颜色需要在两张牌上显示。

    2. 实例化n*m张牌,用List<Color>中的颜色填充牌,每个颜色填充两张

    (n*m必须是偶数)

    for(i=0; i<n*m/2;i++)

    {

      Card c1 = new Card();

      Card c2 = new Card();

      c1.Color = list[i];

      c2.Color = list[i];

         listCard.Add(c1); 

         listCard.Add(c2);

    }

    3.for循环把listCard中的每张牌放到不同的位置上。

    想到这里,自己感觉这样做很棘手,for循环嵌套最好不用,并且第三步比较复杂,位置是不能重复的,也就是说这里再用简单的random无法达到我的目的。

    于是我需要一个简单的算法,摒弃这些繁琐的操作。

    经过与同事的交流,我们把随机做了一次,就只是一次而已,就搞定了一切……

    1. 扔掉listCard,只需要吧原来的listColor*2 形成一个新的List

    2. 然后把这个大的list随机排布

    3. 再for循环这个随机list,把每种颜色分别付给新的Card

    4. 然后这些Card顺序摆放就OK了。

    后续工作:

    5. 如果点击某两张牌,则对比颜色,如果一样则消失(如果全消掉了,就提示胜利,返回主页),否则再次显示背面。

            private Card tempCard_1;
    private Card tempCard_2;
    private const int CARD_WIDTH=70;
    private const int CARD_HEIGHT=70;
    private const int CARD_MARGIN = 5;
    private const int ROWS_COUNT = 2;
    private const int COLUMNS_COUNT = 2;
    private List<Color> listColor;
    private List<BitmapImage> listImage;
    public ContentPage()
    {
    InitializeComponent();
    this.Loaded += new RoutedEventHandler(ContentPage_Loaded);
    }

    void ContentPage_Loaded(object sender, RoutedEventArgs e)
    {
    int multiply = ROWS_COUNT * COLUMNS_COUNT;
    if (multiply / 2 != multiply / 2.0)
    MessageBox.Show("Error,please update the row number or collumn number.");

    InitializeGrid(ROWS_COUNT,COLUMNS_COUNT);

    listColor = new List<Color>();
    Random r = new Random();
    for (int i = 0; i < ROWS_COUNT * COLUMNS_COUNT / 2; i++)
    {
    Color c = Color.FromArgb(255, (byte)r.Next(256), (byte)r.Next(256), (byte)r.Next(256));
    listColor.Add(c);
    listColor.Add(c);
    }

    //add image to list

    listColor = RandomSortList(listColor);

    for (int i = 0; i < listColor.Count;i++ )
    {
    Card card = new Card(listColor[i], null);
    card.Width = CARD_WIDTH;
    card.Height = CARD_HEIGHT;
    card.Margin = new Thickness(CARD_MARGIN);
    Grid.SetRow(card, i / COLUMNS_COUNT);
    Grid.SetColumn(card, i % COLUMNS_COUNT);
    LayoutRoot.Children.Add(card);
    card.Tap += new EventHandler<System.Windows.Input.GestureEventArgs>(Card_Tap);
    }
    }

    private void InitializeGrid(int rows,int collumns)
    {
    for (int i = 0; i < rows; i++)
    {
    RowDefinition r = new RowDefinition();
    r.Height = new GridLength(CARD_HEIGHT + CARD_MARGIN*2);
    LayoutRoot.RowDefinitions.Add(r);
    }
    for (int i = 0; i < collumns; i++)
    {
    ColumnDefinition c = new ColumnDefinition();
    c.Width = new GridLength(CARD_WIDTH + CARD_MARGIN * 2);
    LayoutRoot.ColumnDefinitions.Add(c);
    }
    }

    void Card_Tap(object sender, System.Windows.Input.GestureEventArgs e)
    {
    //当tempCard_2还未清除时,不响应新的事件
    if (tempCard_2 != null)
    return;
    //当tempCard_1为null时,把当前对象赋给tempCard_1,旋转显示tempCard_1
    if (tempCard_1 == null)
    {
    tempCard_1 = sender as Card;
    tempCard_1.Transform();
    }
    else
    {//当tempCard_1不为null,而tempCard_2为null时,给tempCard_2赋值当前对象,并旋转显示。
    //旋转StoryBoard结束后(sb_Completed),对比两张卡片并进行后续处理
    tempCard_2 = sender as Card;
    tempCard_2.Event += new EventHandler<EventArgs>(sb_Completed);
    tempCard_2.Transform();
    }
    }

    void sb_Completed(object sender, EventArgs e)
    {
    //这里必须先取消sb_Completed事件,避免多次注册事件
    tempCard_2.Event -= new EventHandler<EventArgs>(sb_Completed);
    if (tempCard_1.BgColor == tempCard_2.BgColor)
    {//如果颜色相同则消失
    tempCard_1.Break();
    tempCard_2.Break();
    LayoutRoot.Children.Remove(tempCard_1);
    LayoutRoot.Children.Remove(tempCard_2);
    if (LayoutRoot.Children.Count <= 0)
    {
    MessageBox.Show("You win, click button to return Mainpage.");
    NavigationService.Navigate(new Uri("/MainPage.xaml",UriKind.Relative));
    }
    }
    else
    {//否则旋转回去,继续显示背面(在Transform中会有判断,继而决定是转向背面还是前面)
    tempCard_1.Transform();
    tempCard_2.Transform();
    }
    tempCard_1 = null;
    tempCard_2 = null;
    }
    ///<summary>
    /// 随机排列List
    ///</summary>
    ///<typeparam name="T"></typeparam>
    ///<param name="list"></param>
    ///<returns></returns>
    public List<T> RandomSortList<T>(List<T> list)
    {
    Random r = new Random();
    List<T> tempList = new List<T>();
    int listCount = list.Count;
    for (int i = 0; i < listCount; i++)
    {
    int tempInt = r.Next(list.Count);
    tempList.Add(list[tempInt]);
    list.RemoveAt(tempInt);
    }
    return tempList;
    }



    为什么一次就行,为什么Card顺序摆放而不是随机呢??

    多个随机算法与一个随机算法没有差别,可以简单的随机一次,达到你想要的目的。

     源代码:https://files.cnblogs.com/lihaiyin/ScottApp.rar


     

  • 相关阅读:
    NOI2021游记-记最后一段日子
    7.20 ZROI-Day7模拟赛
    7.19 ZROI-Day6模拟赛
    7.18 ZROI-Day5模拟赛
    7.17 ZROI-Day4模拟赛
    7.16 ZROI-DAY3 模拟赛
    7.15 ZROI-DAY2 模拟赛
    7.13 ZROI-DAY1赛后总结
    7.9模拟赛赛后总结
    7.7模拟赛赛后总结
  • 原文地址:https://www.cnblogs.com/lihaiyin/p/2231554.html
Copyright © 2020-2023  润新知