X3

RedSky

导航

生命模拟

界面:

<DockPanel Background="#EEEEEE">
    <WrapPanel DockPanel.Dock="Top">
        <Border Background="Green" Width="20" Height="20" VerticalAlignment="Center"/>
        <TextBlock Text="新生" VerticalAlignment="Center"/>
        <Border Background="DarkGreen" Width="20" Height="20" VerticalAlignment="Center"/>
        <TextBlock Text="不变" VerticalAlignment="Center"/>
        <Border Background="Gray" Width="20"  Height="20" VerticalAlignment="Center"/>
        <TextBlock Text="低密度死亡" VerticalAlignment="Center"/>
        <Border Background="DarkGray" Width="20" Height="20" VerticalAlignment="Center"/>
        <TextBlock Text="高密度死亡" VerticalAlignment="Center"/>
        <Border Width="50"/>
        <TextBlock Text="行数:"/>
        <TextBox x:Name="txtRow" Text="90" Width="50"/>
        <TextBlock Text="列数:"/>
        <TextBox x:Name="txtCell" Text="150" Width="50"/>
        <Button Content="初始化" Click="InitLifWorld"/>
        <TextBlock Text="周期(ms):"/>
        <TextBox x:Name="txtEllips" Text="300" Width="50"/>
        <Button x:Name="btnLifStart" Content="开始" Click="BtnStartLifeWorld"/>
        <Button x:Name="btnLifStop" Content="停止" Click="BtnStopLifeWorld" IsEnabled="False"/>
        <TextBlock x:Name="txtStatu" Text="已停止"/>
    </WrapPanel>
    <Grid>
        <UniformGrid x:Name="LifeWorld" HorizontalAlignment="Center" VerticalAlignment="Center">

        </UniformGrid>
    </Grid>
</DockPanel> 

 

代码:

private void BtnStartLifeWorld(object sender, RoutedEventArgs e)
{
    try
    {
        ellipes = Convert.ToInt32(this.txtEllips.Text);
        StartLifeWorld();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private void InitLifWorld(object sender, RoutedEventArgs e)
{
    try
    {
        maxRow = Convert.ToInt32(this.txtRow.Text);
        maxCell = Convert.ToInt32(this.txtCell.Text);
        this.LifeWorld.Rows = maxRow;
        this.LifeWorld.Columns = maxCell;
        this.LifeWorld.Children.Clear();
        bodys = new Body[maxRow, maxCell];

        for (int r = 0; r < maxRow; r++)
        {
            for (int c = 0; c < maxCell; c++)
            {
                bodys[r, c] = new Body(r, c, LifeStatu.Old);
                bodys[r, c].Background = Brushes.Black;
                this.LifeWorld.Children.Add(bodys[r, c]);
            }
        }
    }catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private void BtnStopLifeWorld(object sender, RoutedEventArgs e)
{
    Stop();
}

int ellipes = 300;
int maxRow = 100;
int maxCell = 150;
Body[,] bodys = null;
List<Body> editItems = null;
bool isStop = false;
public void StartLifeWorld()
{
    this.txtStatu.Text = "正进行";
    this.btnLifStart.IsEnabled = false;
    this.btnLifStop.IsEnabled = true;
    Task.Run(() =>
             {
                 try
                 {
                     isStop = false;
                     while (!isStop)
                     {
                         Thread.Sleep(ellipes);
                         Dispatcher.Invoke(() => ElliseTime());
                     }
                 }
                 catch(Exception ex)
                 {
                     MessageBox.Show(ex.ToString());
                 }
             });
}

public void ElliseTime()
{
    editItems = new List<Body>();
    for (int r = 0; r < maxRow; r++)
    {
        for (int c = 0; c < maxCell; c++)
        {
            var roundItems = GetRoundItems(bodys[r,c]);
            int whiteCount = roundItems.Count(f => f.Statu == LifeStatu.Born || f.Statu == LifeStatu.Live);
            var statu = GetStatu(whiteCount, bodys[r,c].Statu);
            var b = bodys[r, c];
            if(statu != b.Statu)
                editItems.Add(new Body(b.Row, b.Cell, statu));
        }
    }
    if(editItems.Count <= 0)
    {
        Stop();
        return;
    }
    foreach (var item in editItems)
    {
        bodys[item.Row, item.Cell].ChangeStatu(item.Statu);
    }
}

void Stop()
{
    isStop = true;
    this.txtStatu.Text = "已停止";
    this.btnLifStart.IsEnabled = true;
    this.btnLifStop.IsEnabled = false;
}

/// <summary>
/// 获取当前个体周围所有相邻个体
/// </summary>
/// <param name="body"></param>
/// <returns></returns>
public List<Body> GetRoundItems(Body body)
{
    var items = new List<Body>();
    int row = body.Row;
    int cell = body.Cell;
    //从左到右,从上到下
    ////靠上边
    if (row == 0)
    {
        //靠左上角
        if (cell == 0)
        {
            items.Add(new Body(1, 0, bodys[1,0].Statu));
            items.Add(new Body(1, 1, bodys[1,1].Statu));
            items.Add(new Body(0, 1, bodys[0,1].Statu));
        }
        ////靠上边
        else if (cell > 0 && cell < maxCell - 1)
        {
            int r = row;
            int c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
        //右上角
        else if (cell == maxCell - 1)
        {
            int r = 0;
            int c = maxCell - 2;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = 1;
            c = maxCell - 2;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = 1;
            c = maxCell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
    }
    //靠下方
    else if (row == maxRow - 1)
    {
        //靠右下角
        if (cell == maxCell - 1)
        {
            int r = maxRow - 2;
            int c = maxCell - 2;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = maxRow - 1;
            c = maxCell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = maxRow - 1;
            c = maxCell - 2;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
        ////左下角
        else if (cell == 0)
        {
            int r = row - 1;
            int c = 0;
            items.Add(new Body(r, c, bodys[r, c].Statu));
            r = row - 1;
            c = 1;
            items.Add(new Body(r, c, bodys[r, c].Statu));
            r = row;
            c = 1;
            items.Add(new Body(r, c, bodys[r, c].Statu));
        }
        //下方
        else if (cell < maxCell - 1)
        {
            int r = row - 1;
            int c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
    }
    else
    {
        ////靠左边
        if (cell == 0)
        {
            int r = row - 1;
            int c = 0;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = 0;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
        ////靠右边
        else if (cell == maxCell - 1)
        {
            int r = row - 1;
            int c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
        else
        {
            //上
            int r = row - 1;
            int c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row - 1;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));

            //中
            r = row;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));

            //下
            r = row + 1;
            c = cell - 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell;
            items.Add(new Body(r, c, bodys[r,c].Statu));
            r = row + 1;
            c = cell + 1;
            items.Add(new Body(r, c, bodys[r,c].Statu));
        }
    }
    return items;
}


public LifeStatu GetStatu(int whiteCount, LifeStatu statu)
{
    int a = 3;
    if (whiteCount == a)
    {
        if (statu == LifeStatu.Old || statu == LifeStatu.Young)
            return LifeStatu.Born;
        else
            return LifeStatu.Live;
    }
    else if (whiteCount == a - 1)
    {
        if (statu == LifeStatu.Live || statu == LifeStatu.Born)
            return LifeStatu.Live;
    }
    else if (whiteCount < a - 1)
    {
        if (statu == LifeStatu.Live || statu == LifeStatu.Born)
            return LifeStatu.Young;
    }
    else if (whiteCount > a)
    {
        if (statu == LifeStatu.Live || statu == LifeStatu.Born)
            return LifeStatu.Old;
    }
    return statu;
    //黑格当周围有2个,则变白
    //当周围超过3个则变黑
    //当周围少于2个或有3个则不变

    //if (whiteCount > 3)
    //    return LifeStatu.Old;
    //if (whiteCount == 3)
    //{
    //    if (statu == LifeStatu.Old || statu == LifeStatu.Young)
    //        return LifeStatu.Born;
    //}

    //switch (statu)
    //{
    //    case LifeStatu.Born: return LifeStatu.Live;
    //    case LifeStatu.Live: 
    //    case LifeStatu.Young:
    //    case LifeStatu.Old:
    //    default:
    //        return LifeStatu.Old;
    //}

}

}
//
public enum LifeStatu
    {
        /// <summary>
        /// 诞生
        /// </summary>
        Born,
        /// <summary>
        /// 活着
        /// </summary>
        Live,
        /// <summary>
        /// 低密度而亡
        /// </summary>
        Young,
        /// <summary>
        /// 高密度而亡
        /// </summary>
        Old
    }
    public class Body : Button
    {
        public LifeStatu Statu { get; set; }
        public int Row { get; set; }
        public int Cell { get; set; }

        public Body(int row, int cell, LifeStatu statu)
        {
            this.Width = 10;
            this.Height = 10;
            this.Style = null;
            this.BorderThickness = new Thickness(0);
            this.Click += (s, e) => ChangeStatu((int)Statu >= 0 ? (Statu == LifeStatu.Old ? LifeStatu.Born :(LifeStatu)((int)Statu + 1)) : LifeStatu.Born);

            this.Row = row;
            this.Cell = cell;
            ChangeStatu(statu);
        }

        public void ChangeStatu(LifeStatu statu)
        {
            Dispatcher.Invoke(() =>
            {
                this.Statu = statu;
                switch (statu)
                {
                    case LifeStatu.Born:
                        this.Background = Brushes.White;
                        break;
                    case LifeStatu.Live:
                        this.Background = Brushes.White;
                        break;
                    case LifeStatu.Young:
                        this.Background = Brushes.Black;
                        break;
                    case LifeStatu.Old:
                        this.Background = Brushes.Black;
                        break;
                    default:
                        break;
                }
            });
        }
    }

 

posted on 2024-10-21 17:32  HotSky  阅读(1)  评论(0编辑  收藏  举报