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


 

原文地址:https://www.cnblogs.com/lihaiyin/p/2231554.html