Skip to content

Instantly share code, notes, and snippets.

@odashi
Last active June 6, 2017 21:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odashi/1aacd8d64b4a46aee4d45e7b8393b8e9 to your computer and use it in GitHub Desktop.
Save odashi/1aacd8d64b4a46aee4d45e7b8393b8e9 to your computer and use it in GitHub Desktop.
Game of life on X11
#include <chrono>
#include <cstdlib>
#include <iostream>
#include <random>
#include <thread>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
int main() {
::Display *display = ::XOpenDisplay(nullptr);
if (!display) {
cout << "Error." << endl;
exit(1);
}
const int ww = 1024;
const int wh = 1024;
const int k = 4;
const int w = ww / k;
const int h = wh / k;
unsigned c[4] {
0x00ffffff,
0x00ffddee,
0x004455ff,
0x002233ff,
};
::Window window = XCreateSimpleWindow(
display, ::XDefaultRootWindow(display), 0, 0, ww, wh, 1,
::XBlackPixel(display, 0), ::XWhitePixel(display, 0));
::XSelectInput(display, window, ButtonPressMask | ExposureMask);
::GC gc = ::XCreateGC(display, window, 0, 0);
::XSetGraphicsExposures(display, gc, false);
::XMapWindow(display, window);
::XFlush(display);
random_device rd;
mt19937 rng(rd());
bernoulli_distribution dist(0.5);
::Visual *visual = ::XDefaultVisual(display, ::XDefaultScreen(display));
unsigned *data = reinterpret_cast<unsigned *>(malloc(4 * ww * wh));
::XImage *image = ::XCreateImage(
display, visual, 24, ZPixmap, 0,
reinterpret_cast<char *>(data), ww, wh, 8, 0);
vector<vector<int>> cells(w, vector<int>(h));
auto reset = [&]() {
for (int x = 0; x < w; ++x) {
for (int y = 0; y < h; ++y) cells[x][y] = dist(rng);
}
};
reset();
::XEvent event;
bool loop = true;
unsigned time = 0;
while (loop) {
if (::XPending(display) > 0) {
::XNextEvent(display, &event);
switch (event.type) {
case ButtonPress:
loop = false;
break;
case Expose:
::XPutImage(display, window, gc, image, 0, 0, 0, 0, ww, wh);
break;
}
} else {
for (int x = 0; x < w; ++x) {
for (int y = 0; y < h; ++y) {
int n = 0;
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
n += cells[(x + i + w) % w][(y + j + h) % h] & 1;
}
}
if (n == 3 || (n == 4 && (cells[x][y] & 1))) cells[x][y] |= 2;
}
}
for (int x = 0; x < w; ++x) {
for (int y = 0; y < h; ++y) {
for (int i = 0; i < k; ++i) {
for (int j = 0; j < k; ++j) {
data[x * k + i + (y * k + j) * ww] = c[cells[x][y] & 3];
}
}
cells[x][y] >>= 1;
}
}
::XPutImage(display, window, gc, image, 0, 0, 0, 0, ww, wh);
::XFlush(display);
this_thread::sleep_for(chrono::microseconds(100000));
if (++time == 500) {
reset();
time = 0;
}
}
}
::XCloseDisplay(display);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment