3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ライフゲームをモダンな書き方で・Rust接触編

Last updated at Posted at 2025-12-09

はじめに

(Rust言語の記事は)初投稿です。

古来より伝わる「ライフゲーム」をモダンな言語で実装するチャレンジ実施中です。

今回は今までのSwiftから心機一転、Rust言語です。

開発環境

  • MacStudio2023(M2 Max)
  • macOS Tahoe(26.1)
  • cargo 1.91.1

ライフゲームとは

概要は先駆者様の解説に委ねます。

コーディングに必要なルールは以下となります。

  • 2次元グリッド上で展開され、各セルは「生」または「死」の2つの状態を持つ
  • 各世代で、「隣接(上下左右と斜め4方向の計8方向にある)」セルを以下のルールに従って状態が更新される
    • 誕生:死んでいるセルに隣接する生きたセルがちょうど3つあれば、次の世代で誕生する
    • 生存:生きているセルに隣接する生きたセルが2つまたは3つならば、次の世代でも生存する
    • 過疎:生きているセルに隣接する生きたセルが1つ以下ならば、過疎により死滅する
    • 過密::生きているセルに隣接する生きたセルが4つ以上ならば、過密により死滅する
  • 端は常に死んでいるとみなす(固定境界)

実装コードと気付き

初めてのRustでの実装なので、自分なりの気づきを書きつけてみました。

モジュール指定

すでにC++の片鱗を見せている感じです。

  • 並列処理をやりたかったのでrayonを宣言
use rayon::prelude::*; // cargo add rayon
use std::fmt;
use std::thread;
use std::time::Duration;

アトリビュート指定

これは開発向けの設定なんですかね?

#[derive(Copy, Clone, Debug, Eq, PartialEq)]

セル状態

列挙型は他言語と同じほぼ同じ書き方ですね。

// セル状態を表す列挙型
enum Cell {
    Dead = 0,
    Alive = 1,
}

世界を表現する構造体

クラスが存在しないのはモダン言語には珍しい設計思想だと感じます。それと配列は番号よりVec型が一般的?ここもC++のstd::vector型を思わせます。

// ワールドを表す構造体
struct World {
    width: u32,
    height: u32,
    cells: Vec<Cell>,
    generation: u32,
}

ゲームコントローラー部分

メソッドは構造体に別途追加する仕様が、公式でも「Rustはオブジェクト指向ではない」と明言しているところの真骨頂だと感じます。

  • 各セルの処理には並列処理を行っている、ただ使いたかっただけで
impl World {
    // ワールド生成
    fn new(width: u32, height: u32) -> World {
        // 並列処理で実行
        let cells = (0..width * height)
            .into_par_iter()
            .map(|i| World::initialize_dead_or_alive(i))
            .collect();

        // World構造体を返す
        World {
            width,
            height,
            cells,
            generation: 0,
        }
    }

    // 初期状態を設定
    fn initialize_dead_or_alive(i: u32) -> Cell {
        // 疑似乱数
        if i % 5 == 0 || i % 11 == 0 {
            Cell::Alive
        } else {
            Cell::Dead
        }
    }

    // 指定された位置のインデックスを取得する
    fn get_index(&self, row: u32, col: u32) -> usize {
        (row * self.width + col) as usize
    }

    // 指定された位置のセルの生存している隣接数
    fn live_neighbor_count(&self, row: u32, col: u32) -> u8 {
        let mut count = 0;
        // 行ループ
        for delta_row in [self.height - 1, 0, 1].iter().cloned() {
            // 列ループ
            for delta_col in [self.width - 1, 0, 1].iter().cloned() {
                // 自身を除く
                if delta_row == 0 && delta_col == 0 {
                    continue;
                }
                // 隣接するセルの位置を計算
                let neighbor_row = ((row + delta_row) % self.height) as i32;
                let neighbor_col = ((col + delta_col) % self.width) as i32;
                if neighbor_row < 0
                    || neighbor_row >= self.height as i32
                    || neighbor_col < 0
                    || neighbor_col >= self.width as i32
                {
                    continue;
                }
                // 隣接するセルのインデックスを取得
                let idx = self.get_index(neighbor_row as u32, neighbor_col as u32);
                // 隣接するセルの生存状態をカウント
                count += self.cells[idx] as u8;
            }
        }
        count
    }

    // 次世代を計算する
    fn next_generation(&mut self) {
        let cell_count = self.cells.len();
        // 並列処理で実行
        let next = (0..cell_count)
            .into_par_iter()
            .map(|index| {
                let cell = self.cells[index];
                // 行と列を算出
                let row = (index as u32) / self.width;
                let col = (index as u32) % self.width;
                // 隣接するセルの生存数
                let live_neighbors = self.live_neighbor_count(row, col);
                // 次世代のセル状態
                let next_cell = match (cell, live_neighbors) {
                    // 過疎: 生きているセルで、隣接数が2未満なら死
                    (Cell::Alive, x) if x < 2 => Cell::Dead,
                    // 生存: 生きているセルで、隣接数が2か3なら生
                    (Cell::Alive, 2) | (Cell::Alive, 3) => Cell::Alive,
                    // 過密: 生きているセルで、隣接数が3より多ければ死
                    (Cell::Alive, x) if x > 3 => Cell::Dead,
                    // 誕生: 死んでいるセルで、隣接数がちょうど3なら生
                    (Cell::Dead, 3) => Cell::Alive,
                    // 上記以外は状態維持
                    (otherwise, _) => otherwise,
                };
                next_cell
            })
            .collect();
        self.cells = next;
        self.generation += 1;
    }
}

結果出力

ポリモーフィズムを「トレイト」という仕組みで実現する、まず「トレイト」という言葉が初耳でした。

// DisplayトレイトをWorldに実装
impl fmt::Display for World {
    // 結果表示
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // 1行ごとに表示
        for line in self.cells.as_slice().chunks(self.width as usize) {
            // 1行内の各セルを表示
            for &cell in line {
                let symbol = if cell == Cell::Dead { '◻' } else { '◼' };
                write!(f, " {}", symbol)?;
            }
            write!(f, "\n")?;
        }
        Ok(())
    }
}

実行部

main()から始まるのはまさに古来からの定理、なんですね。

fn main() {
    let mut world = World::new(17, 11);
    let loop_count = 10;
    for _ in 0..loop_count {
        // \x1B[2J: 画面全体をクリア
        // \x1B[1;1H: カーソルを1行1列目に移動
        println!("\x1B[2J\x1B[1;1H");
        // 世代表示
        let mut description = "";
        if world.generation == 0 {
            description = "(初期状態)";
        }
        println!("世代: {} {}", world.generation, description);
        println!("{}", world);
        // 次世代へ進める
        world.next_generation();
        // ミリ秒待機
        thread::sleep(Duration::from_millis(1000));
    }
}

実行結果例

世代: 0 (初期状態)
 ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻
 ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼
 ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼
 ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻
 ◼ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻
 ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼
 ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻
 ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻
 ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻

世代: 1 
 ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◼ ◼
 ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◼
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◻ ◻ ◻ ◼ ◻
 ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◼ ◻ ◻ ◼
 ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻
 ◼ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◼
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻
 ◼ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻
 ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻

世代: 2 
 ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻
 ◼ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻
 ◼ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◻
 ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◼ ◼
 ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻
 ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◼ ◻ ◻
 ◼ ◼ ◻ ◻ ◼ ◼ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◼ ◼ ◻ ◻ ◼ ◼ ◻ ◼ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼

世代: 3 
 ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◼ ◼
 ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◼
 ◻ ◼ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻
 ◻ ◼ ◼ ◼ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◼ ◼
 ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻
 ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼
 ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◻ ◼ ◼ ◻
 ◼ ◼ ◼ ◼ ◼ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼
 ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻

世代: 4 
 ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◼
 ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◻
 ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◼
 ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼
 ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◻

世代: 5 
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻
 ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◼ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻

世代: 6 
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◼ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◼ ◻

世代: 7 
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◼ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◼ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◼ ◼ ◻

世代: 8 
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◻ ◼ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻

世代: 9 
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◻ ◻ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻ ◼ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◼ ◼ ◼ ◻ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◼ ◻ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻ ◻ ◻
 ◻ ◻ ◼ ◼ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◼ ◻
 ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◻ ◼ ◻ ◻

実行して判った事

  • 最近はC++から疎遠だったが、Rustの記述がかなり似ているところから、過去の苦労や達成感を思い出した
  • 並列処理の恩恵はともかく、単純な書き方で実行できるのは魅力的に感じた
  • やはりライフゲームは言語学習にはもってこいだと強く感じた

今後の展開予定

  • グラフィカルなプラットフォーム(ブラウザ?)でリアルタイムに可視化
  • 他の言語でのチャレンジ

おわりに

ここまで読んでいただきありがとうございます。

今後も思いつくままに記事投稿を続けて行きたい所存であります。

太陽あれ!

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?