//ライフゲーム
using System;
using System.Collections .Generic ;
using System.ComponentModel ;
using System.Data ;
using System.Drawing ;
using System.Linq ;
using System.Text ;
using System.Windows .Forms ;
using System.Threading .Tasks ;
using System.Threading ;
namespace LifeGame
{
public partial class Form1 : Form
{
Random rnd = new Random( ) ;
public Bitmap bmp { get; set; }
public Graphics g { get; set; }
public int [ , ] lifes { get; set; }
public int [ , ] next { get; set; }
const int MX = 300 ;
const int SZ = 3 ;
Task taskMain;
bool isUpdate = false ;
IEnumerable< Point> xy = from x in Enumerable.Range ( 0 , MX)
from y in Enumerable.Range ( 0 , MX)
select new Point( x, y) ;
public Form1( )
{
InitializeComponent( ) ;
SetStyle( ControlStyles.OptimizedDoubleBuffer , true ) ;
SetStyle( ControlStyles.UserPaint , true ) ;
SetStyle( ControlStyles.AllPaintingInWmPaint , true ) ;
bmp = new Bitmap( MX * SZ, MX * SZ) ;
this.ClientSize = bmp.Size ;
g = Graphics.FromImage ( bmp) ;
lifes = new int [ MX, MX] ;
next = new int [ MX, MX] ;
for ( int i = 0 ; i < 20000 ; i++ )
{
lifes[ rnd.Next ( MX) , rnd.Next ( MX) ] = 1 ;
}
isUpdate = true ;
taskMain = Task.Factory .StartNew ( GameMain) ;
}
private void GameMain( )
{
MessageBox.Show ( "Start" ) ;
bool isContinue = true ;
while ( isContinue)
{
Thread.Sleep ( 1000 / 60 ) ;
if ( ! isUpdate) continue ;
//次世代ライフをクリア
next = new int [ MX, MX] ;
//自分以外の周囲8のlifeの数を知る
isContinue = false ;
for ( int x = 0 ; x < MX ; x++ )
{
for ( int y = 0 ; y < MX; y++ )
{
int roundLifes = GetRoundLifes( x, y) ;
if ( ( lifes[ x, y] == 0 && roundLifes == 3 )
||
( lifes[ x, y] == 1 && ( 2 <= roundLifes && roundLifes <= 3 ) ) )
{
isContinue = true ;
next[ x, y] = 1 ;
}
else
{
next[ x, y] = 0 ;
}
}
}
for ( int x = 0 ; x < MX; x++ )
{
for ( int y = 0 ; y < MX; y++ )
{
lifes[ x, y] = next[ x, y] ;
}
}
Invalidate( ) ;
}
MessageBox.Show ( "End" ) ;
}
private int GetRoundLifes( int x, int y)
{
int result = 0 ;
Func< int , int , int> getLife = ( x1, y1) =>
{
if ( ( x1 < 0 ) || ( y1 < 0 ) || ( x1 >= MX) || ( y1 >= MX) )
{
return 0 ;
}
return lifes[ x1, y1] ;
} ;
result += getLife( x - 1 , y - 1 ) ;
result += getLife( x - 0 , y - 1 ) ;
result += getLife( x + 1 , y - 1 ) ;
result += getLife( x - 1 , y - 0 ) ;
result += getLife( x + 1 , y - 0 ) ;
result += getLife( x - 1 , y + 1 ) ;
result += getLife( x - 0 , y + 1 ) ;
result += getLife( x + 1 , y + 1 ) ;
return result;
}
protected override void OnPaint( PaintEventArgs e)
{
if ( ! isUpdate) return ;
g.Clear ( Color.Black ) ;
for ( int x = 0 ; x < MX; x++ )
{
for ( int y = 0 ; y < MX; y++ )
{
if ( lifes[ x, y] == 1 ) g.DrawRectangle ( Pens.Aqua , x * SZ, y * SZ, SZ, SZ) ;
}
}
e.Graphics .DrawImage ( bmp, Point.Empty ) ;
}
/// <summary>
/// 押された場所に5x5のライフを作る
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_MouseDown( object sender, MouseEventArgs e)
{
int x = e.X / SZ;
int y = e.Y / SZ;
isUpdate = false ;
for ( int xx = 0 ; xx < 5 ; xx++ )
{
for ( int yy = 0 ; yy < 5 ; yy++ )
{
int nx = xx + x;
int ny = yy + y;
if ( nx < 0 || nx >= MX || ny < 0 || ny >= MX) continue ;
lifes[ nx, ny] = 1 ;
}
}
isUpdate = true ;
}
}
}
Ly/jg6njgqTjg5XjgrLjg7zjg6AKCnVzaW5nIFN5c3RlbTsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIFN5c3RlbS5Db21wb25lbnRNb2RlbDsKdXNpbmcgU3lzdGVtLkRhdGE7CnVzaW5nIFN5c3RlbS5EcmF3aW5nOwp1c2luZyBTeXN0ZW0uTGlucTsKdXNpbmcgU3lzdGVtLlRleHQ7CnVzaW5nIFN5c3RlbS5XaW5kb3dzLkZvcm1zOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nOwoKbmFtZXNwYWNlIExpZmVHYW1lCnsKICAgIHB1YmxpYyBwYXJ0aWFsIGNsYXNzIEZvcm0xIDogRm9ybQogICAgewoKICAgICAgICBSYW5kb20gcm5kID0gbmV3IFJhbmRvbSgpOwogICAgICAgIHB1YmxpYyBCaXRtYXAgYm1wIHsgZ2V0OyBzZXQ7IH0KICAgICAgICBwdWJsaWMgR3JhcGhpY3MgZyB7IGdldDsgc2V0OyB9CiAgICAgICAgcHVibGljIGludFssXSBsaWZlcyB7IGdldDsgc2V0OyB9CiAgICAgICAgcHVibGljIGludFssXSBuZXh0IHsgZ2V0OyBzZXQ7IH0KICAgICAgICBjb25zdCBpbnQgTVggPSAzMDA7CiAgICAgICAgY29uc3QgaW50IFNaID0gMzsKICAgICAgICBUYXNrIHRhc2tNYWluOwogICAgICAgIGJvb2wgaXNVcGRhdGUgPSBmYWxzZTsKCiAgICAgICAgSUVudW1lcmFibGU8UG9pbnQ+IHh5ID0gZnJvbSB4IGluIEVudW1lcmFibGUuUmFuZ2UoMCwgTVgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tIHkgaW4gRW51bWVyYWJsZS5SYW5nZSgwLCBNWCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QgbmV3IFBvaW50KHgsIHkpOwoKICAgICAgICBwdWJsaWMgRm9ybTEoKQogICAgICAgIHsKICAgICAgICAgICAgSW5pdGlhbGl6ZUNvbXBvbmVudCgpOwoKICAgICAgICAgICAgU2V0U3R5bGUoQ29udHJvbFN0eWxlcy5PcHRpbWl6ZWREb3VibGVCdWZmZXIsIHRydWUpOwogICAgICAgICAgICBTZXRTdHlsZShDb250cm9sU3R5bGVzLlVzZXJQYWludCwgdHJ1ZSk7CiAgICAgICAgICAgIFNldFN0eWxlKENvbnRyb2xTdHlsZXMuQWxsUGFpbnRpbmdJbldtUGFpbnQsIHRydWUpOwoKCiAgICAgICAgICAgIGJtcCA9IG5ldyBCaXRtYXAoTVggKiBTWiwgTVggKiBTWik7CiAgICAgICAgICAgIHRoaXMuQ2xpZW50U2l6ZSA9IGJtcC5TaXplOwogICAgICAgICAgICBnID0gR3JhcGhpY3MuRnJvbUltYWdlKGJtcCk7CiAgICAgICAgICAgIGxpZmVzID0gbmV3IGludFtNWCwgTVhdOwogICAgICAgICAgICBuZXh0ID0gbmV3IGludFtNWCwgTVhdOwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDIwMDAwOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGxpZmVzW3JuZC5OZXh0KE1YKSwgcm5kLk5leHQoTVgpXSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaXNVcGRhdGUgPSB0cnVlOwogICAgICAgICAgICB0YXNrTWFpbiA9IFRhc2suRmFjdG9yeS5TdGFydE5ldyhHYW1lTWFpbik7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSB2b2lkIEdhbWVNYWluKCkKICAgICAgICB7CiAgICAgICAgICAgIE1lc3NhZ2VCb3guU2hvdygiU3RhcnQiKTsKCiAgICAgICAgICAgIGJvb2wgaXNDb250aW51ZSA9IHRydWU7CiAgICAgICAgICAgIHdoaWxlIChpc0NvbnRpbnVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUaHJlYWQuU2xlZXAoMTAwMCAvIDYwKTsKCiAgICAgICAgICAgICAgICBpZiAoIWlzVXBkYXRlKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIC8v5qyh5LiW5Luj44Op44Kk44OV44KS44Kv44Oq44KiCiAgICAgICAgICAgICAgICBuZXh0ID0gbmV3IGludFtNWCwgTVhdOwoKICAgICAgICAgICAgICAgIC8v6Ieq5YiG5Lul5aSW44Gu5ZGo5ZuyOOOBrmxpZmXjga7mlbDjgpLnn6XjgosKICAgICAgICAgICAgICAgIGlzQ29udGludWUgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGZvcihpbnQgeCA9IDAgOyB4IDxNWCA7IHgrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGludCB5ID0gMDsgeSA8IE1YOyB5KyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBpbnQgcm91bmRMaWZlcyA9IEdldFJvdW5kTGlmZXMoeCx5KTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChsaWZlc1t4LCB5XSA9PSAwICYmIHJvdW5kTGlmZXMgPT0gMykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGlmZXNbeCwgeV0gPT0gMSAmJiAoMiA8PSByb3VuZExpZmVzICYmIHJvdW5kTGlmZXMgPD0gMykpKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0NvbnRpbnVlID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRbeCwgeV0gPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFt4LCB5XSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yIChpbnQgeCA9IDA7IHggPCBNWDsgeCsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgTVg7IHkrKykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGxpZmVzW3gsIHldID0gbmV4dFt4LCB5XTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSW52YWxpZGF0ZSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIE1lc3NhZ2VCb3guU2hvdygiRW5kIik7CgogICAgICAgIH0KCiAgICAgICAgcHJpdmF0ZSBpbnQgR2V0Um91bmRMaWZlcyhpbnQgeCxpbnQgeSkKICAgICAgICB7CiAgICAgICAgICAgIGludCByZXN1bHQgPSAwOwogICAgICAgICAgICBGdW5jPGludCwgaW50LCBpbnQ+IGdldExpZmUgPSAoeDEsIHkxKSA9PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoKHgxIDwgMCkgfHwgKHkxIDwgMCkgfHwgKHgxID49IE1YKSB8fCAoeTEgPj0gTVgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIGxpZmVzW3gxLCB5MV07CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggLSAxLCB5IC0gMSk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggLSAwLCB5IC0gMSk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggKyAxLCB5IC0gMSk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggLSAxLCB5IC0gMCk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggKyAxLCB5IC0gMCk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggLSAxLCB5ICsgMSk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggLSAwLCB5ICsgMSk7CiAgICAgICAgICAgIHJlc3VsdCArPSBnZXRMaWZlKHggKyAxLCB5ICsgMSk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CgogICAgICAgIH0KCiAgICAgICAgcHJvdGVjdGVkIG92ZXJyaWRlIHZvaWQgT25QYWludChQYWludEV2ZW50QXJncyBlKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCFpc1VwZGF0ZSkgcmV0dXJuOwoKICAgICAgICAgICAgZy5DbGVhcihDb2xvci5CbGFjayk7CgogICAgICAgICAgICBmb3IgKGludCB4ID0gMDsgeCA8IE1YOyB4KyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvciAoaW50IHkgPSAwOyB5IDwgTVg7IHkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAobGlmZXNbeCwgeV0gPT0gMSkgZy5EcmF3UmVjdGFuZ2xlKFBlbnMuQXF1YSwgeCAqIFNaLCB5ICpTWiwgU1osIFNaKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlLkdyYXBoaWNzLkRyYXdJbWFnZShibXAsUG9pbnQuRW1wdHkpOwogICAgICAgIH0KCiAgICAgICAgLy8vIDxzdW1tYXJ5PgogICAgICAgIC8vLyDmirzjgZXjgozjgZ/loLTmiYDjgavvvJXvvZjvvJXjga7jg6njgqTjg5XjgpLkvZzjgosKICAgICAgICAvLy8gPC9zdW1tYXJ5PgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0ic2VuZGVyIj48L3BhcmFtPgogICAgICAgIC8vLyA8cGFyYW0gbmFtZT0iZSI+PC9wYXJhbT4KICAgICAgICBwcml2YXRlIHZvaWQgRm9ybTFfTW91c2VEb3duKG9iamVjdCBzZW5kZXIsIE1vdXNlRXZlbnRBcmdzIGUpCiAgICAgICAgewogICAgICAgICAgICBpbnQgeCA9IGUuWCAvIFNaOwogICAgICAgICAgICBpbnQgeSA9IGUuWSAvIFNaOwoKICAgICAgICAgICAgaXNVcGRhdGUgPSBmYWxzZTsKCiAgICAgICAgICAgIGZvciAoaW50IHh4ID0gMDsgeHggPCA1OyB4eCsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmb3IgKGludCB5eSA9IDA7IHl5IDwgNTsgeXkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnQgbnggPSB4eCArIHg7CiAgICAgICAgICAgICAgICAgICAgaW50IG55ID0geXkgKyB5OwogICAgICAgICAgICAgICAgICAgIGlmIChueCA8IDAgfHwgbnggPj0gTVggfHwgbnkgPCAwIHx8IG55ID49IE1YKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAgICAgbGlmZXNbbngsbnldID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpc1VwZGF0ZSA9IHRydWU7CgoKICAgICAgICB9CgogICAgfQp9Cg==