ラングトンの蟻 [Processing]

Processingでラングトンの蟻のシミュレーションを行った.

ラングトンの蟻とは

ラングトンのアリ - Wikipediaより引用.

平面が格子状に構成され、各マスが白または黒で塗られる。ここで、1つのマスを「アリ」とする。アリは各ステップで上下左右のいずれかのマスに移動することができる。アリは以下の規則に従って移動する。

  • 黒いマスにアリがいた場合、90°右に方向転換し、そのマスの色を反転させ、1マス前進する。

  • 白いマスにアリがいた場合、90°左に方向転換し、そのマスの色を反転させ、1マス前進する。

この単純な規則で驚くほど複雑な動作をする。当初でたらめな動作をしているが、アリはいずれ例外なく10000歩ほどうろついた後に真っ直ぐな「道」を作る動作に入る。これは初期のパターンがどうであろうと殆ど関係ない。このことは、この「道」(highway)が、ラングトンのアリのアトラクタであることを示唆している。

ソースコード

int CELL_NUM = 100;
int CELL_SIZE = 5;

boolean[][] cells = new boolean[CELL_NUM][CELL_NUM];

int ant_x;
int ant_y;
int ant_direction; // 0=up, 1=right, 2=bottom, 3=left

void setup(){
  size(CELL_NUM * CELL_SIZE, CELL_NUM * CELL_SIZE);
  
  // initialize cells, 0: all white, 1: all black, 2: put black rectangle
  initialize_cells(0);
  
  // initialize ant position
  ant_x = ant_y = int(CELL_NUM / 2);
  ant_direction = 0;
}

void draw(){
  // clear screen
  fill(255);
  rect(0, 0, width, height);
  
   // draw cells
   noStroke();
   fill(30);
   for(int w = 0; w < CELL_NUM; w++){
     for(int h = 0; h < CELL_NUM; h++){
       if(cells[w][h] == true){
         rect(w * CELL_SIZE, h * CELL_SIZE, CELL_SIZE, CELL_SIZE);
       }
     }
   }
  
  // draw lines
  stroke(128);
  strokeWeight(1);
  for(int i = 0; i < CELL_NUM; i++){
    line(i * CELL_SIZE, 0, i * CELL_SIZE, height);
    line(0, i * CELL_SIZE, width, i * CELL_SIZE);
  }
   
   // draw ant
   fill(255, 0, 0);
   rect(ant_x * CELL_SIZE, ant_y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
   
   //act ant
   act_ant();
}

void act_ant(){
  if(cells[ant_x][ant_y] == true){
    turn_left();
  } else {
    turn_right();
  }
  cells[ant_x][ant_y] = !cells[ant_x][ant_y];
  forward_ant();
}

void turn_left(){
  ant_direction -= 1;
  if(ant_direction == -1){
    ant_direction = 3;
  }
}

void turn_right(){
  ant_direction += 1;
  if(ant_direction == 4){
    ant_direction = 0;
  }
}

void forward_ant(){
  switch(ant_direction){
    case 0:
      ant_y = (ant_y != 0 ? ant_y - 1 : CELL_NUM - 1);
      break;
    case 1:
      ant_x = (ant_x != CELL_NUM - 1 ? ant_x + 1 : 0);
      break;
    case 2:
      ant_y = (ant_y != CELL_NUM - 1 ? ant_y + 1 : 0);
      break;
    case 3:
      ant_x = (ant_x != 0 ? ant_x - 1 : CELL_NUM - 1);
      break;
  }
}

void initialize_cells(int method){
  switch(method){
    case 0: // all white
      for(int w = 0; w < CELL_NUM; w++){
        for(int h = 0; h < CELL_NUM; h++){
          cells[w][h] = false;
        }
      }
      break;
      
    case 1: // all black
      for(int w = 0; w < CELL_NUM; w++){
        for(int h = 0; h < CELL_NUM; h++){
          cells[w][h] = true;
        }
      }
      break;
    
    case 2: // put black rectangle 
      for(int w = 0; w < CELL_NUM; w++){
        for(int h = 0; h < CELL_NUM; h++){
          cells[w][h] = false;
        }
      }
      int rect_x = 40;
      int rect_y = 20;
      for(int w = (CELL_NUM / 2) - int(rect_x / 2); w < (CELL_NUM / 2) + int(rect_x / 2); w++){
        for(int h = (CELL_NUM / 2) - int(rect_y / 2); h < (CELL_NUM / 2) + int(rect_y / 2); h++){
          cells[w][h] = true;
        }        
      }
  }
}

シミュレーション

動画1

真っ白の空間からスタートさせたもの.

ランダムな動きをするが,およそ10000ステップ後に道作りに入っている.

aa-debdeb : Langton’s Ant

動画2

真ん中に黒い直方体を置いてスタートさせたもの.

黒い長方形を壊したり,壁を作ったりしながら,こちらも10000ステップ後に道作りに入っている,

aa-debdeb : Langton’s Ant

processing.jsを用いて,Webブラウザからも見れるようにしておいた.

http://aa-debdeb.com/processing_drawing/LangtonAnt.html

さくらVPSの初期設定

VPSにアクセス

以下のコマンドでVPSにアクセスする.

$ ssh root@IPaddress

rootのパスワードを変更する.

# passwd #新しいパスワードを入力

ポート番号の変更

ポート番号を22(デフォルト)から10022に変更をする.

# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org #オリジナルをバックアップ
# vim /etc/ssh/sshd_config

以下のように編集.

#Port 22
Port 10022

sshを再起動.

# service sshd restart 

これで次からは以下のようにポート番号を指定してログインする.

$ ssh -p 10022 root@IPaddress

ユーザの作成

ユーザの作成とパスワードの変更をする.

# useradd username #ユーザの追加
# passwd username #追加したユーザのパスワードを変更

ユーザをwheelグループに所属させて,sudoとsuコマンドが使えるようにする.

# usermod -G wheel username
# visudo

以下のように変更する.

## Allows people in group wheel to run all commands
%wheel        ALL=(ALL)       ALL

ここからは次のように,rootではなく,作成したユーザを用いてアクセスする.

$ ssh -p 10022 username@IPaddress

鍵認証の設定

クライアント側で秘密鍵と公開鍵を生成する.

$ ssh-keygen -t rsa -C "email@example.com" #パスワードを入力.

~/.ssh秘密鍵id_rsaと公開鍵id_rsa.pubが作成される.

作成した公開鍵をVPSに転送する.

$ scp -P 10022 ~/.ssh/id_rsa.pub username@IPaddress:~/

VPS側で~/.ssh以下にauthorized_keysという名前で置く.

$ mkdir .ssh
$ mv id_rsa.pub .ssh/authorized_keys

パーミッションの変更をする.

$ chmod 700 .ssh
$ chmod 600 .ssh/authorized_keys

これで,以下のコマンドでログインしてもパスワードを聞かれない.

$ ssh -p 10022 aa_debdeb@160.16.55.217

ログインの制限

セキュリティのために鍵認証のみを用いるようにする. またrootでログイン出来ないようにする.

$ sudo vim /etc/ssh/sshd_config
# PasswordAuthentification yes
PasswordAuthentification no #パスワードではログインできなくする
# PermitRootLogin yes
PermitRootLogin no #rootではログインできなくなる

sshを再起動する.

$ sudo servide sshd restart

パッケージのアップデート

パッケージを最新版にアップデートする.

$ sudo yum update

Firewallの設定

iptablesを使って,ファイアーウォールの設定をする

$ sudo vim /etc/sysconfig/iptables

以下の内容を記述する.

*filter
:INPUT   ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT  ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]

-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 10022  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited

COMMIT

iptablesを起動して,確認する.

$ sudo service iptables start #起動
$ sudo iptables -L #設定の確認

以上で初期設定完了.

参考

macのGoogle Chormeでローカルファイルを参照する方法

Google Chromeでは,セキュリティのためにローカルファイルを読み込めないようになっている. しかし,自分の開発したものをローカルで確かめたいときなどに不便である.

以下のコマンドでターミナルからChromeを立ち上げると,この問題は発生しなくなる.

$ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files

参考 http://qiita.com/marukun/items/02f62fc0cabccdfb1262

他の方法も見つかったが,これではなぜか上手くいかなかった. http://dev.classmethod.jp/etc/chrome-localfile-security/