Created
December 25, 2017 14:28
-
-
Save trickre/13bb7bae2eb95251f7440a2f03a0a2a2 to your computer and use it in GitHub Desktop.
lifegame's code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Threading.Tasks; | |
using Windows.UI.Xaml; | |
using Windows.UI.Xaml.Controls; | |
using Windows.UI.Xaml.Media; | |
using Windows.UI.Xaml.Shapes; | |
namespace LifeSim | |
{ | |
public sealed partial class MainPage : Page | |
{ | |
List<Windows.UI.Xaml.Shapes.Rectangle> list_rect; | |
StatusLife[,] field; | |
int N_x = 30; | |
int N_y = 20; | |
int cell_width = 25; | |
int cell_height = 25; | |
SolidColorBrush color_live = new SolidColorBrush(Windows.UI.Colors.Green); | |
SolidColorBrush color_dead = new SolidColorBrush(Windows.UI.Colors.Black); | |
bool is_run_game = false;//true is run | |
public MainPage() | |
{ | |
this.InitializeComponent(); | |
list_rect = new List<Windows.UI.Xaml.Shapes.Rectangle>(); | |
field = new StatusLife[N_x, N_y]; | |
LaidCell(N_x, N_y); | |
} | |
private async void button_Click(object sender, RoutedEventArgs e) | |
{ | |
Task task = new Task(async () => | |
{ | |
await Task.Delay(1000); | |
foreach (Rectangle r in list_rect) | |
{ | |
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => | |
{ | |
r.Fill = new SolidColorBrush(Windows.UI.Colors.Red); | |
}); | |
} | |
await Task.Delay(1000); | |
foreach (Rectangle r in list_rect) | |
{//ここにawaitがあると順次更新される | |
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => | |
{ | |
r.Fill = new SolidColorBrush(Windows.UI.Colors.Blue); | |
}); | |
} | |
await Task.Delay(1000); | |
foreach (Rectangle r in list_rect) | |
{//ここにawaitがないと一気に更新される こちらの方がよい | |
Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => | |
{ | |
r.Fill = new SolidColorBrush(Windows.UI.Colors.Yellow); | |
}); | |
} | |
}); | |
task.Start(); | |
} | |
private void button1_Click(object sender, RoutedEventArgs e) | |
{ | |
} | |
private void LaidCell(int size_x, int size_y) | |
{ | |
int N_x = size_x; | |
int N_y = size_y; | |
//このmarginで箱の位置を制御する | |
int margin_x = 0; | |
int margin_y = 0; | |
for (int c_y = N_y; c_y > 0; c_y--) | |
{ | |
margin_x = 0; | |
for (int c_x = N_x; c_x > 0; c_x--) | |
{ | |
Windows.UI.Xaml.Shapes.Rectangle rect_add = new Windows.UI.Xaml.Shapes.Rectangle(); | |
rect_add.Width = cell_width - 1; | |
rect_add.Height = cell_height - 1; | |
rect_add.Fill = new SolidColorBrush(Windows.UI.Colors.Green); | |
rect_add.Margin = new Thickness(margin_x, margin_y, 0, 0); | |
rect_add.HorizontalAlignment = HorizontalAlignment.Left; | |
rect_add.VerticalAlignment = VerticalAlignment.Top; | |
list_rect.Add(rect_add); | |
grid_rect.Children.Add(rect_add); | |
margin_x += cell_width; | |
} | |
margin_y += cell_height; | |
} | |
} | |
//フィールドにランダムを与える | |
private StatusLife[,] set_random(StatusLife[,] field, int size_x, int size_y) | |
{ | |
StatusLife[,] f = field; | |
Random rn = new Random(); | |
for (int y = 0; y < size_y; y++) | |
{ | |
for (int x = 0; x < size_x; x++) | |
{ | |
if (rn.NextDouble() < 0.5) | |
{ | |
f[x, y] = StatusLife.Live; | |
} | |
else { f[x, y] = StatusLife.Dead; } | |
} | |
} | |
return f; | |
} | |
//fieldから計算フィールドへうつす。端はつながってる形である | |
private StatusLife[,] FieldToFieldCalc(StatusLife[,] field, int size_x, int size_y) | |
{ | |
StatusLife[,] f_calc = new StatusLife[size_x + 2, size_y + 2]; | |
//真ん中 | |
for (int y = 0; y < size_y; y++) | |
{ | |
for (int x = 0; x < size_x; x++) | |
{ | |
f_calc[x + 1, y + 1] = field[x, y]; | |
} | |
} | |
//4隅 | |
f_calc[0, 0] = field[size_x - 1, size_y - 1]; //左上 | |
f_calc[size_x + 1, 0] = field[0, size_y - 1]; //右上 | |
f_calc[size_x + 1, size_y + 1] = field[0, 0]; //右下 | |
f_calc[0, size_y + 1] = field[size_x - 1, 0]; //左下 | |
//外枠直線 | |
//上下 | |
for (int x = 0; x < size_x; x++) | |
{ | |
f_calc[x, 0] = field[x, size_y - 1]; | |
f_calc[x, size_y + 1] = field[x, 0]; | |
} | |
//左右 | |
for (int y = 0; y < size_y; y++) | |
{ | |
f_calc[0, y] = field[size_x - 1, y]; | |
f_calc[size_x + 1, y] = field[0, y]; | |
} | |
return f_calc; | |
} | |
//UIに反映させる | |
private void ArrayToCell(List<Windows.UI.Xaml.Shapes.Rectangle> list_rect, StatusLife[,] field, int size_x, int size_y) | |
{ | |
int X = size_x; | |
int index = 0; | |
for (int y = 0; y < size_y; y++) | |
{ | |
for (int x = 0; x < size_x; x++) | |
{ | |
index = X * y + x; | |
if (field[x, y] == StatusLife.Dead) | |
{ | |
list_rect[index].Fill = color_dead; | |
} | |
else if (field[x, y] == StatusLife.Live) | |
{ | |
list_rect[index].Fill = color_live; | |
} | |
} | |
} | |
} | |
//外周1マスは端をつなげるための領域である | |
//return:field[size_x,size_y] | |
private StatusLife[,] calc_cell_1step(StatusLife[,] field, int size_x, int size_y) | |
{ | |
StatusLife[,] f_calc = FieldToFieldCalc(field, size_x, size_y); | |
StatusLife[,] result = new StatusLife[size_x, size_y]; | |
int sum = 0; | |
int x = 1, y = 1; | |
for (y = 1; y < size_y + 1; y++) | |
{ | |
for (x = 1; x < size_x + 1; x++) | |
{ | |
sum = (int)f_calc[x - 1, y - 1] + (int)f_calc[x, y - 1] + (int)f_calc[x + 1, y - 1] + (int)f_calc[x + 1, y] + (int)f_calc[x - 1, y] + (int)f_calc[x + 1, y + 1] + (int)f_calc[x, y + 1] + (int)f_calc[x - 1, y + 1]; | |
result[x - 1, y - 1] = LiveLife(f_calc[x, y], sum); | |
} | |
} | |
return result; | |
} | |
//生死の判定 | |
private StatusLife LiveLife(StatusLife cell, int input_sum) | |
{ | |
StatusLife result_live = 0; | |
switch (cell) | |
{ | |
case StatusLife.Live: | |
if (input_sum == 2 || input_sum == 3) | |
{ | |
result_live = StatusLife.Live; | |
} | |
break; | |
case StatusLife.Dead: | |
if (input_sum == 3) | |
{ | |
result_live = StatusLife.Live; | |
} | |
else { result_live = StatusLife.Dead; } | |
break; | |
} | |
return result_live; | |
} | |
enum StatusLife : int { Dead, Live }; | |
private void btn_step_Click(object sender, RoutedEventArgs e) | |
{ | |
if (is_run_game == false) | |
{ | |
field = calc_cell_1step(field, N_x, N_y); | |
ArrayToCell(list_rect, field, N_x, N_y); | |
} | |
} | |
private void btn_start_Click(object sender, RoutedEventArgs e) | |
{ | |
if (is_run_game == true) | |
{ | |
is_run_game = false; | |
} | |
else | |
{ | |
is_run_game = true; | |
Task task = new Task(async () => | |
{ | |
while (is_run_game) | |
{ | |
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => | |
{ | |
field = calc_cell_1step(field, N_x, N_y); | |
ArrayToCell(list_rect, field, N_x, N_y); | |
}); | |
await Task.Delay(100); | |
} | |
}); | |
task.Start(); | |
} | |
} | |
private void page_root_SizeChanged(object sender, SizeChangedEventArgs e) | |
{ | |
page_root.Width = 728; | |
grid_rect.Background = new SolidColorBrush(Windows.UI.Colors.Black); | |
} | |
private void btn_rnd_Click(object sender, RoutedEventArgs e) | |
{ | |
set_random(field, N_x, N_y); | |
ArrayToCell(list_rect, field, N_x, N_y); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment