继"一题比较刁的面试题" - 其实也不过如此。 sliverlight 实现

继 上次的随笔  一题比较***的面试题 

大致内容------------------------------------------------------------------------------------------------------------

昨天晚上看到群里在聊面试题,回想最近几个月的面试经历,很是感慨。

10月底从昆山回到苏州。直到11月底才找到工作,跑到哪都是有没有工作经验,没有。。。好吧,回去等通知吧。

 

2009年11月19日来到苏州热线面试(苏州比较大的门户网站)

面试结束后带回去了一个题、

 

要求:

1.任何语言 任何形式(web,winform,flash,flex,silverlight)等等。。

2.实现内容

a.初始化一个面板,面板内随机分布着一些按钮  按钮上有一些随机的数字。

b.有一个按钮 名字叫“新增节点” 点击 该按钮后 可以向面板内随机添加新的 按钮。

c.任意顺序点击面板内的按钮。按顺序将所点按钮用线条连接。并且将按钮的 数值进行累加 显示到 文本框。

d.回放 功能。 有一个名叫 “回放的按钮” 点击该按钮后 将所有操作慢动作回放。

   包括增加节点 和 连接 的一切操作。完整再现。

 

这题拿回家做了3个班小时。水平不行啊。。花了很长时间在想用什么技术好。结果用了 JavaScript (jQuery)

 

在中间遇到了一些难点。

1.画线问题。一开始想到的是 vml 但是由于浏览器兼容问题。最后在网上找啊找。

使用了别人写的一个函数 用JavaScript 画线 主要思路是 利用三角函数 画出该线的每一个像素点(非常占资源)

2.记录和回放问题。如何记录下每一个操作并回放,这个问题也想了很久

记录:最后是这样的。在全局存放一个对象,该对象是一个 button 的 dom 。用来保存上一次点击的按钮对象。

当点击一个按钮时。首先将该按钮存放到一个array(存放Button对象)中,再将判断上一次是否存在点击。如果存在,则将这两个按钮连接。

当添加按钮时 首先将随机产生的按钮添加至 array 中 。

回放:当点击回放时 首先是要初始化板面中的按钮和线条等。 策略是:线条全部删除。中途添加的按钮 全部隐藏。

回放的过程实际是 一个 array 的遍历过程。

判断 array 中 Button的 状态。当Button 为显示时。调用 Button的 click 方法。否则 将Button设置为可见。

------------------------------------------------------------------------------------------------------------------------------

上回采用JavaScript实现 ,今天用sliverlight实习了该功能,发现也就如此,没啥难度。最近公司没事 开始学习sliverlight了(为了混饭吃)。

实现思路和上次基本上是一样的

主要还是一个链表,记录每一步操作的Button

其中 button的操作有两种   1.点击 2.新增加

回放时用一个定时器遍历链表 判断需要的操作 被隐藏则显示 否则执行button的click 方法 click 方法时回进行一系列的操作 如 值累加、与上一个按钮连接等操作。

 

全部代码----------------------------------------------------------------------------

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace ConnectionButton
{

    public partial class MainPage : UserControl
    {

        /// <summary>
        /// 按钮容器框的宽度
        /// </summary>
        private readonly double canvas4btnsWidth;

        /// <summary>
        /// 按钮容器框的高度
        /// </summary>
        private readonly double canvas4btnsHeight;

        /// <summary>
        /// 最大按钮值
        /// </summary>
        private readonly int maxBtnValue = 100;


        /// <summary>
        /// 最后被点击的按钮
        /// </summary>
        private XButton LastClickButton = null;

        /// <summary>
        /// 初始化时的按钮
        /// </summary>
        private IList<XButton> InitButtonsList = new List<XButton>();

        /// <summary>
        /// 增加的按钮
        /// </summary>
        private IList<XButton> AddedButtonsList = new List<XButton>();

        private List<object> MyList = new List<object>();

        bool IsPlaying = false;

        DispatcherTimer playTimer = new DispatcherTimer() { Interval = new TimeSpan(4000000) };

        int LIndex = 0;

        public MainPage()
        {
            InitializeComponent();

            canvas4btnsWidth = canvas4btns.ActualWidth;
            canvas4btnsHeight = canvas4btns.ActualHeight;

            //初始化按钮
            InitButtons();

            //定时器的Tick事件
            playTimer.Tick += (s, e) =>
            {
                if (MyList.Count == 0 || LIndex + 1 > MyList.Count)
                {
                    playTimer.Stop();
                    LIndex = 0;
                    IsPlaying = false;
                }
                else
                {
                    object item = MyList[LIndex];
                    if (item is XButton)
                    {
                        XButton btn = item as XButton;
                        if (btn.IsHide())
                        {
                            btn.Show();
                        }
                        else
                        {
                            //点击
                            ButtonClick(item);
                        }
                    }
                    LIndex++;
                }
            };
        }

        /// <summary>
        /// 产生随机数
        /// </summary>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        private int GetRandomNumber(int min, int max)
        {
            long tick = DateTime.Now.Ticks;
            Random r = new Random(Guid.NewGuid().GetHashCode());
            if (min == -1 && max == -1)
            {
                return r.Next();
            }
            if (min == -1 && max != -1)
            {
                return r.Next(max);
            }
            return r.Next(min, max);
        }


        /// <summary>
        /// 初始化面板
        /// </summary>
        private void InitButtons()
        {
            int max = GetRandomNumber(5, 10);
            for (int i = 0; i < max; i++)
            {
                XButton btn = CreateButton();
                InitButtonsList.Add(btn);
                canvas4btns.Children.Add(btn);
            }
        }


        /// <summary>
        /// 产生随机位置的按钮
        /// </summary>
        /// <returns></returns>
        private XButton CreateButton()
        {
            double canvasLeft = GetRandomNumber(50, Convert.ToInt32(canvas4btnsWidth - 50));
            double canvasTop = GetRandomNumber(50, Convert.ToInt32(canvas4btnsHeight - 50));

            XButton btn = new XButton()
            {
                Height = 40,
                Width = 40,
                Content = GetRandomNumber(1, maxBtnValue).ToString(),
                Background = new SolidColorBrush() { Color = Colors.Blue }
            };

            btn.SetValue(Canvas.LeftProperty, canvasLeft);
            btn.SetValue(Canvas.TopProperty, canvasTop);


            btn.Click += (button, e) =>
            {
                if (!IsPlaying)
                {
                    ButtonClick(button);
                }
            };

            return btn;
        }

        /// <summary>
        /// 按钮点击
        /// </summary>
        /// <param name="button"></param>
        public void ButtonClick(object button)
        {
            XButton nowBtn = button as XButton;
            nowBtn.IsEnabled = false;
            nowBtn.Background = new SolidColorBrush() { Color = Colors.Red };

            txtCount.Text = (int.Parse(nowBtn.Content.ToString()) + int.Parse(txtCount.Text)).ToString();

            if (LastClickButton != null)
            {
                DrawLine(LastClickButton.Position(), nowBtn.Position());
            }

            //设置最后被点击的按钮
            LastClickButton = nowBtn;

            if (!LastClickButton.Clicked)
            {
                MyList.Add(LastClickButton);
                LastClickButton.Clicked = true;
            }
        }


        /// <summary>
        /// 增加节点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            if (!IsPlaying)
            {
                XButton btn = CreateButton();
                AddedButtonsList.Add(btn);
                MyList.Add(btn);
                canvas4btns.Children.Add(btn);
            }

        }

        /// <summary>
        /// 画线
        /// </summary>
        /// <param name="startPoint"></param>
        /// <param name="endPoint"></param>
        private void DrawLine(Point startPoint, Point endPoint)
        {
            Line l = new Line() { X1 = startPoint.X, X2 = endPoint.X, Y1 = startPoint.Y, Y2 = endPoint.Y, StrokeThickness = 2 };
            l.Stroke = new SolidColorBrush() { Color = Color.FromArgb(255, 41, 57, 85) };
            canvas4btns.Children.Add(l);
        }



        /// <summary>
        /// 回放
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRePlay_Click(object sender, RoutedEventArgs e)
        {
            if (!IsPlaying)
            {
                ///回到最初
                BackToTheBeginning();

                Paly();
            }
        }

        /// <summary>
        /// 播放
        /// </summary>
        private void Paly()
        {
            IsPlaying = true;
            playTimer.Start();
        }

        /// <summary>
        /// 回到最初
        /// </summary>
        private void BackToTheBeginning()
        {
            txtCount.Text = "0";

            LastClickButton = null;

            //将后来添加的按钮移除
            foreach (XButton btn in AddedButtonsList)
            {
                btn.Init();
                btn.Hide();
            }

            foreach (XButton btn in InitButtonsList)
            {
                btn.Init();
            }

            //移除所有连线

            var lineElements = canvas4btns.Children.Where(c => c is Line);
            foreach (Line line in lineElements)
            {
                line.Hide();
            }


            //while (canvas4btns.Children.Where(c => c is Line).Count() != 0)
            //{
            //    for (int i = 0; i < canvas4btns.Children.Count; i++)
            //    {
            //        if (canvas4btns.Children[i] is Line)
            //        {
            //            canvas4btns.Children.RemoveAt(i);
            //            break;
            //        }
            //    }
            //}


        }

    }


    /// <summary>
    /// 扩展类
    /// </summary>
    public static class Extension
    {
        /// <summary>
        /// 获取按钮的位置 仅相对于Canvas布局
        /// </summary>
        /// <param name="btn"></param>
        /// <returns></returns>
        public static Point Position(this XButton btn)
        {
            return new Point()
            {
                X = Convert.ToDouble(btn.GetValue(Canvas.LeftProperty)) + btn.ActualWidth / 2,
                Y = Convert.ToDouble(btn.GetValue(Canvas.TopProperty)) + btn.ActualHeight / 2,
            };
        }

        public static void Init(this XButton btn)
        {
            btn.BeBlue();
            btn.Visibility = Visibility.Visible;
            btn.IsEnabled = true;
        }

        public static int Value(this XButton btn)
        {
            return int.Parse(btn.Content.ToString());
        }

        public static void BeRed(this XButton btn)
        {
            btn.Background = new SolidColorBrush() { Color = Colors.Red };
        }

        public static void BeBlue(this XButton btn)
        {
            btn.Background = new SolidColorBrush() { Color = Colors.Blue };
        }

        public static bool IsHide(this XButton btn)
        {
            return btn.Visibility == Visibility.Collapsed;
        }

        public static void Show(this XButton btn)
        {
            btn.Visibility = Visibility.Visible;
        }

        public static void Hide(this XButton btn)
        {
            btn.Visibility = Visibility.Collapsed;
        }

        public static void Hide(this Line line)
        {
            line.Visibility = Visibility.Collapsed;
        }

        public static void Click(this XButton btn)
        {
            btn.Visibility = Visibility.Collapsed;
        }
    }

    public class XButton : Button
    {
        public bool Clicked { get; set; }
    }
}

效果图----------------------------------------------------------------------------------------------------------------

 

 

够简单吧。。。。

去年10月到现在时间也不短了,还把这道面试题找出来,看来我还是对那次面试耿耿于怀啊。。。此处不留爷,自有留爷处。

那家公司从家道那边要1个多小时,幸亏没去,不然就亏大了。

 

全部代码下载 /tandly/ConnectionButton.rar

苏州    很恶心的雨

汤晓华 QQ 1881597 MSN tension1990@hotmail.com

2010 04 14

posted @ 2010-04-14 19:48  tandly  阅读(2232)  评论(10编辑  收藏  举报