Created
July 3, 2025 08:06
-
-
Save PhoenixGameDevelopment/422de6c1c3686983ec7bebdb39611557 to your computer and use it in GitHub Desktop.
A Simple AI-Generated Program to Generate Conway's "Game of Life"
This file contains hidden or 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.Drawing; | |
using System.Windows.Forms; | |
class GameOfLife : Form | |
{ | |
const int CellSize = 10; //10 | |
int[,] cells, nextCells; | |
int width, height; | |
bool isRunning; | |
Timer timer; | |
// UI Controls | |
Button startBtn, clearBtn, randomBtn; | |
TrackBar speedTrack; | |
Label genLabel; | |
int generation; | |
public GameOfLife() | |
{ | |
// And ensure ClientSize accounts for controls at top: | |
ClientSize = new Size(600, 600); | |
height = (ClientSize.Height - 50) / CellSize; // Subtract space for controls | |
Text = "Conway's Game of Life"; | |
width = 600;// ClientSize.Width / CellSize; | |
height = 600;// ClientSize.Height / CellSize; | |
width = ClientSize.Width / CellSize; | |
height = ClientSize.Height / CellSize; | |
cells = new int[width, height]; | |
nextCells = new int[width, height]; | |
InitializeControls(); | |
InitializeTimer(); | |
Paint += (s, e) => DrawGrid(e.Graphics); | |
MouseDown += (s, e) => ToggleCell(e.X / CellSize, e.Y / CellSize); | |
// Add this to initialize some living cells (simple glider pattern): | |
//cells[5, 5] = 1; | |
//cells[6, 6] = 1; | |
//cells[7, 4] = 1; | |
//cells[7, 5] = 1; | |
//cells[7, 6] = 1; | |
// Auto-randomize (comment out if unwanted) | |
RandomizeGrid(0.3); // 30% initial density | |
} | |
void InitializeControls() | |
{ | |
// Start/Pause Button | |
startBtn = new Button | |
{ | |
Text = "Start", | |
Location = new Point(10, 10) | |
}; | |
startBtn.Click += (s, e) => | |
{ | |
isRunning = !isRunning; | |
startBtn.Text = isRunning ? "Pause" : "Start"; | |
}; | |
randomBtn = new Button | |
{ | |
Text = "Randomize", | |
Location = new Point(10, 40) | |
}; | |
// Clear Button | |
clearBtn = new Button | |
{ | |
Text = "Clear", | |
Location = new Point(100, 10) | |
}; | |
clearBtn.Click += (s, e) => ClearGrid(); | |
// Speed Control | |
speedTrack = new TrackBar | |
{ | |
Minimum = 1, | |
Maximum = 20, | |
Value = 10, | |
Location = new Point(190, 10), | |
Width = 150 | |
}; | |
// Generation Counter | |
genLabel = new Label | |
{ | |
Location = new Point(350, 15), | |
AutoSize = true | |
}; | |
Controls.AddRange(new Control[] { startBtn, clearBtn, speedTrack, genLabel }); | |
/* | |
0.1: Sparse, tends to die out | |
0.3: Balanced, interesting patterns | |
0.5: Chaotic, volatile interactions | |
0.7: Dense, forms solid blocks" | |
*/ | |
randomBtn.Click += (s, e) => RandomizeGrid(0.2); // 20% density | |
Controls.Add(randomBtn); | |
} | |
// Add this method to your class: | |
void RandomizeGrid(double density) | |
{ | |
Random rand = new Random(); | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = 0; y < height; y++) | |
{ | |
cells[x, y] = rand.NextDouble() < density ? 1 : 0; | |
} | |
} | |
generation = 0; | |
Invalidate(); | |
} | |
void InitializeTimer() | |
{ | |
timer = new Timer { Interval = 100 }; | |
timer.Tick += (s, e) => | |
{ | |
if (isRunning) | |
{ | |
ComputeNextGeneration(); | |
generation++; | |
genLabel.Text = $"Generation: {generation}"; | |
Invalidate(); | |
} | |
timer.Interval = 110 - speedTrack.Value * 5; | |
}; | |
timer.Start(); | |
} | |
void ToggleCell(int x, int y) | |
{ | |
if (x >= 0 && y >= 0 && x < width && y < height) | |
{ | |
cells[x, y] = cells[x, y] == 0 ? 1 : 0; | |
Invalidate(); | |
} | |
} | |
void ClearGrid() | |
{ | |
cells = new int[width, height]; | |
generation = 0; | |
genLabel.Text = "Generation: 0"; | |
Invalidate(); | |
} | |
void ComputeNextGeneration() | |
{ | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = 0; y < height; y++) | |
{ | |
int neighbors = CountLiveNeighbors(x, y); | |
// Apply Conway's rules | |
nextCells[x, y] = (cells[x, y] == 1) | |
? (neighbors == 2 || neighbors == 3) ? cells[x, y] + 1 : 0 | |
: (neighbors == 3) ? 1 : 0; | |
} | |
} | |
// Swap buffers | |
var temp = cells; | |
cells = nextCells; | |
nextCells = temp; | |
} | |
int CountLiveNeighbors(int x, int y) | |
{ | |
int count = 0; | |
for (int i = -1; i <= 1; i++) | |
{ | |
for (int j = -1; j <= 1; j++) | |
{ | |
if (i == 0 && j == 0) continue; | |
int nx = (x + i + width) % width; | |
int ny = (y + j + height) % height; | |
if (cells[nx, ny] > 0) count++; | |
} | |
} | |
return count; | |
} | |
void DrawGrid(Graphics g) | |
{ | |
// Add background first | |
g.Clear(Color.Black); | |
/* | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = 0; y < height; y++) | |
{ | |
Rectangle cellRect = new Rectangle( | |
x * CellSize, | |
y * CellSize + 50, // Account for control panel | |
CellSize, | |
CellSize | |
); | |
if (cells[x, y] > 0) | |
{ | |
// Keep color logic but draw with border | |
int age = Math.Min(cells[x, y], 10); | |
Color cellColor = Color.FromArgb(255, 255 - age * 25, 255 - age * 25); | |
g.FillRectangle(new SolidBrush(cellColor), cellRect); | |
g.DrawRectangle(Pens.White, cellRect); | |
} | |
else | |
{ | |
g.DrawRectangle(Pens.Gray, cellRect); // Show empty cells | |
} | |
} | |
} | |
*/ | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = 0; y < height; y++) | |
{ | |
if (cells[x, y] > 0) | |
{ | |
// Older cells get darker | |
int age = Math.Min(cells[x, y], 10); | |
Color cellColor = Color.FromArgb( | |
255, | |
255 - age * 25, | |
255 - age * 25 | |
); | |
g.FillRectangle(new SolidBrush(cellColor), | |
x * CellSize, y * CellSize, | |
CellSize - 1, CellSize - 1); | |
} | |
} | |
} | |
} | |
/* | |
static void Main() | |
{ | |
Application.Run(new GameOfLife()); | |
} | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment