最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Java實現(xiàn)生命游戲串行代碼示例

 更新時間:2024年10月28日 10:57:28   作者:chashangcha  
生命游戲是一種二維細胞自動機,由英國數學家在1970年發(fā)明,在游戲的過程中,細胞會形成各種有規(guī)律的結構,展現(xiàn)出生命的復雜性和多樣性,本文通過java和JavaFX實現(xiàn)了一個簡單的生命游戲,可以直觀的觀察到細胞的迭代過程,需要的朋友可以參考下

生命游戲介紹

生命游戲,是英國數學家約翰·何頓·康威在1970年發(fā)明的細胞自動機。

一個方格游戲棋盤上,每個方格中都可放置一個生命細胞,每個生命細胞只有兩種狀態(tài):“生”或“死”(狀態(tài)往往隨機決定)。然后細胞根據某些規(guī)則,計算出下一代每個細胞的狀態(tài),并且不停迭代。

在游戲的進行中,雜亂無序的細胞會逐漸演化出各種精致、有形的結構;這些結構往往有很好的對稱性,而且每一代都在變化形狀。一些形狀已經鎖定,不會逐代變化。有時,一些已經成形的結構會因為一些無序細胞的“入侵”而被破壞。但是形狀和秩序經常能從雜亂中產生出來。

現(xiàn)設定其規(guī)則是:

  • 如果一個細胞周圍有3個細胞為生(一個細胞周圍共有8個細胞),則該細胞為生(即該細胞若原先為死,則轉為生,若原先為生,則保持不變) 。
  •  如果一個細胞周圍有2個細胞為生,則該細胞的生死狀態(tài)保持不變;
  •  在其它情況下,該細胞為死(即該細胞若原先為生,則轉為死,若原先為死,則保持不變)

下面就此規(guī)則,使用java來編寫100*100的棋盤,并使用簡單的JavaFX來實現(xiàn)簡易圖形化來觀察游戲的迭代過程。

一、效果展示

1.初始界面

100*100的棋盤上隨機生成“生”和“死”細胞(黑為生,白為死)。底部有“運行”和“暫停”按鈕。

2.啟動游戲

二、代碼實現(xiàn)

package com.itheima.gameOfLife;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import java.util.Random;

public class GameOfLife extends Application {
    private static final int GRID_SIZE = 100; 
    private static final int CELL_SIZE = 10; // 每個細胞的像素大小
    private static final int GENERATIONS = 1000; // 演化代數
    private int[][] grid = new int[GRID_SIZE][GRID_SIZE]; // 當前代棋盤
    private int[][] nextGrid = new int[GRID_SIZE][GRID_SIZE]; // 下一代棋盤
    private Pane pane = new Pane();
    private AnimationTimer timer;
    private boolean isRunning = false; // 運行狀態(tài)標志

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        initializeGrid(); // 隨機初始化棋盤

        // 創(chuàng)建JavaFX界面
        BorderPane root = new BorderPane();
        Scene scene = new Scene(root, GRID_SIZE * CELL_SIZE, GRID_SIZE * CELL_SIZE + 50);
        primaryStage.setTitle("生命游戲");
        primaryStage.setScene(scene);

        // 創(chuàng)建按鈕,便于停止觀察當前棋盤狀態(tài) 
        Button startButton = new Button("運行");
        Button pauseButton = new Button("暫停");

        startButton.setOnAction(e -> startGame());
        pauseButton.setOnAction(e -> pauseGame());

        // 設置按鈕位置
        root.setBottom(new Pane(startButton, pauseButton));
        Pane buttonPane = new Pane();
        buttonPane.getChildren().addAll(startButton, pauseButton);
        buttonPane.setPrefSize(GRID_SIZE * CELL_SIZE, 50);
        buttonPane.setLayoutY(GRID_SIZE * CELL_SIZE);
        startButton.setLayoutX(20);
        pauseButton.setLayoutX(80);
        root.setCenter(pane);
        root.setBottom(buttonPane);

        primaryStage.show();

        drawGrid(); // 繪制初始棋盤

        // 使用AnimationTimer更新棋盤
        timer = new AnimationTimer() {
            private int generationCount = 0;

            @Override
            public void handle(long now) {
                if (isRunning && generationCount < GENERATIONS) {
                    runGeneration(); // 運行一代
                    drawGrid(); // 更新繪制
                    generationCount++;
                } else if (generationCount >= GENERATIONS) {
                    stop(); // 結束動畫
                }
            }
        };
    }

    // 隨機初始化棋盤
    private void initializeGrid() {
        Random random = new Random();
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                grid[i][j] = random.nextInt(2); // 隨機生成0或1
            }
        }
    }

    // 啟動
    private void startGame() {
        if (!isRunning) {
            isRunning = true; // 設置為運行狀態(tài)
            timer.start(); // 啟動計時器
        }
    }

    // 暫停
    private void pauseGame() {
        isRunning = false; // 設置為暫停狀態(tài)
        timer.stop(); // 停止計時器
    }

    // 運行一代
    private void runGeneration() {
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                int liveNeighbors = countLiveNeighbors(i, j);
                if (grid[i][j] == 1) { // 當前細胞是活的
                    nextGrid[i][j] = (liveNeighbors == 2 || liveNeighbors == 3) ? 1 : 0;
                } else { // 當前細胞是死的
                    nextGrid[i][j] = (liveNeighbors == 3) ? 1 : 0;
                }
            }
        }
        copyNextGridToCurrent();
    }

    // 計算鄰居活細胞數量
    private int countLiveNeighbors(int row, int col) {
        int liveNeighbors = 0;
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                if (i == 0 && j == 0) continue; // 跳過自身
                int newRow = (row + i + GRID_SIZE) % GRID_SIZE; // 考慮邊界
                int newCol = (col + j + GRID_SIZE) % GRID_SIZE;
                liveNeighbors += grid[newRow][newCol];
            }
        }
        return liveNeighbors;
    }

    // 將nextGrid復制到grid
    private void copyNextGridToCurrent() {
        for (int i = 0; i < GRID_SIZE; i++) {
            System.arraycopy(nextGrid[i], 0, grid[i], 0, GRID_SIZE);
        }
    }

    // 繪制當前棋盤狀態(tài)
    private void drawGrid() {
        pane.getChildren().clear(); // 清除舊的圖形
        for (int i = 0; i < GRID_SIZE; i++) {
            for (int j = 0; j < GRID_SIZE; j++) {
                Rectangle cell = new Rectangle(j * CELL_SIZE, i * CELL_SIZE, CELL_SIZE, CELL_SIZE);
                cell.setFill(grid[i][j] == 1 ? Color.BLACK : Color.WHITE); // 黑色表示活細胞,白色表示死細胞
                cell.setStroke(Color.GRAY); //細胞之間的邊框
                pane.getChildren().add(cell); // 將細胞添加到面板
            }
        }
    }
}

三、代碼解釋

1.常量設置

private static final int GRID_SIZE = 100; 
private static final int CELL_SIZE = 10; // 每個細胞的像素大小
private static final int GENERATIONS = 1000; // 演化代數
private int[][] grid = new int[GRID_SIZE][GRID_SIZE]; // 當前代棋盤
private int[][] nextGrid = new int[GRID_SIZE][GRID_SIZE]; // 下一代棋盤
private Pane pane = new Pane();
private AnimationTimer timer;
private boolean isRunning = false; // 運行狀態(tài)標志

GRID_SIZE: 定義了棋盤的大小,當前設置為 100。即棋盤是一個 100 x 100 的格子。

CELL_SIZE: 定義了每個細胞的像素大小,當前設置為 10。因此,每個細胞在界面上將顯示為一個 10 x 10 像素的正方形。

棋盤總大小: 因此,整個棋盤的實際像素大小為:

  • 寬度: GRID_SIZE * CELL_SIZE = 100 * 10 = 1000 像素
  • 高度: GRID_SIZE * CELL_SIZE = 100 * 10 = 1000 像素

2.圖形化

// 創(chuàng)建JavaFX界面
    BorderPane root = new BorderPane();
    Scene scene = new Scene(root, GRID_SIZE * CELL_SIZE, GRID_SIZE * CELL_SIZE + 50);
    primaryStage.setTitle("生命游戲");
    primaryStage.setScene(scene);

    // 創(chuàng)建按鈕
    Button startButton = new Button("運行");
    Button pauseButton = new Button("暫停");

    startButton.setOnAction(e -> startGame());
    pauseButton.setOnAction(e -> pauseGame());

    // 將按鈕放置在界面底部
    root.setBottom(new Pane(startButton, pauseButton));
    Pane buttonPane = new Pane();
    buttonPane.getChildren().addAll(startButton, pauseButton);
    buttonPane.setPrefSize(GRID_SIZE * CELL_SIZE, 50);
    buttonPane.setLayoutY(GRID_SIZE * CELL_SIZE);
    startButton.setLayoutX(20);
    pauseButton.setLayoutX(80);
    root.setCenter(pane);
    root.setBottom(buttonPane);

    primaryStage.show();

    drawGrid(); // 繪制初始棋盤

    // 使用AnimationTimer更新棋盤
    timer = new AnimationTimer() {
        private int generationCount = 0;

        @Override
        public void handle(long now) {
            if (isRunning && generationCount < GENERATIONS) {
                runGeneration(); // 運行一代
                drawGrid(); // 更新繪制
                generationCount++;
            } else if (generationCount >= GENERATIONS) {
                stop(); // 結束動畫
            }
        }
    };
}

上面這段代碼是JavaFX的核心部分,創(chuàng)建棋盤界面和處理游戲邏輯。部分解釋已經在代碼中注釋出來。

在“使用AnimationTimer更新棋盤”這部分中,創(chuàng)建了一個 AnimationTimer 對象,并重寫其handle方法,用于定時更新棋盤狀態(tài)。

3.計算“生死”情況與統(tǒng)計鄰居細胞數量

//根據規(guī)則判斷生死
private void runGeneration() {
    for (int i = 0; i < GRID_SIZE; i++) {
        for (int j = 0; j < GRID_SIZE; j++) {
            int liveNeighbors = countLiveNeighbors(i, j);
            if (grid[i][j] == 1) { // 當前細胞是活的
                nextGrid[i][j] = (liveNeighbors == 2 || liveNeighbors == 3) ? 1 : 0;
            } else { // 當前細胞是死的
                nextGrid[i][j] = (liveNeighbors == 3) ? 1 : 0;
            }
        }
    }
    copyNextGridToCurrent();
}

// 計算鄰居活細胞數量
private int countLiveNeighbors(int row, int col) {
    int liveNeighbors = 0;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            if (i == 0 && j == 0) continue; // 跳過自身
            int newRow = (row + i + GRID_SIZE) % GRID_SIZE; // 考慮邊界
            int newCol = (col + j + GRID_SIZE) % GRID_SIZE;
            liveNeighbors += grid[newRow][newCol];
        }
    }
    return liveNeighbors;
}

比較簡單的代碼,使用最基本的雙重循環(huán)來遍歷整個棋盤的細胞,得到其鄰居的數量用于判斷下一次迭代的狀態(tài)。

在“計算鄰居活細胞數量”中,用取模運算來處理邊界情況,使得棋盤具有環(huán)繞效果。例如,如果當前細胞在第一行,且要檢查上方的細胞,則通過取模確保索引循環(huán)回到棋盤的底部。

四、結語

以上主要淺顯的實現(xiàn)了生命游戲的基本邏輯,并用簡單的圖形可視化來創(chuàng)建一個直觀的界面來觀察細胞的迭代,更直接的觀察到由簡單規(guī)則產生的復雜動態(tài)行為。在這個串行的生命游戲基礎上,后續(xù)可以改寫為多線程的生命游戲,并通過一些方法來比對串行與并行代碼的效率。

到此這篇關于使用Java實現(xiàn)生命游戲串行的文章就介紹到這了,更多相關Java生命游戲串行代碼內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • JavaEE之SpringBoot配置文件的使用及說明

    JavaEE之SpringBoot配置文件的使用及說明

    本文主要介紹了Spring Boot中配置文件的使用,包括application.properties和application.yml兩種格式的配置文件的語法、讀取方式以及優(yōu)缺點,同時,還通過一個驗證碼案例練習,展示了如何使用Spring Boot和hutool工具類包實現(xiàn)驗證碼功能
    2026-01-01
  • 啟動Tomcat報錯Unsupported major.minor version xxx的解決方法

    啟動Tomcat報錯Unsupported major.minor version xxx的解決方法

    這篇文章主要為大家詳細介紹了啟動Tomcat報錯Unsupported major.minor version xxx的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Java?@Scheduled定時器用法解析

    Java?@Scheduled定時器用法解析

    這篇文章主要介紹了Java?@Scheduled定時器用法解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Android入門簡單實例

    Android入門簡單實例

    這篇文章主要介紹了Android入門簡單實例,對于初學Android的朋友有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • Java使用ANTLR4對Lua腳本語法校驗詳解

    Java使用ANTLR4對Lua腳本語法校驗詳解

    ANTLR是一個強大的解析器生成器,用于讀取、處理、執(zhí)行或翻譯結構化文本或二進制文件,下面就跟隨小編一起看看Java如何使用ANTLR4對Lua腳本語法校驗吧
    2025-04-04
  • SpringCloud中的Consul詳解

    SpringCloud中的Consul詳解

    這篇文章主要介紹了SpringCloud中的Consul知識,本文使用的是docker-compose方式管理consul服務,直接啟動即可,需要的朋友可以參考下
    2022-03-03
  • 通過Java與Hadoop和Spark結合進行大數據處理

    通過Java與Hadoop和Spark結合進行大數據處理

    隨著大數據技術的迅猛發(fā)展,數據處理框架已經不再局限于單一機器或傳統(tǒng)數據庫的處理方式,而是轉向分布式計算,Hadoop和Spark作為最廣泛使用的大數據處理框架,為我們提供了高效處理海量數據的能力,本文將深入探討如何使用Java與Hadoop和Spark結合進行大數據處理
    2025-09-09
  • Java?SpringAOP技術之注解方式詳解

    Java?SpringAOP技術之注解方式詳解

    這篇文章主要為大家詳細介紹了Java?SpringAOP技術之注解方式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • 關于Mybatis的mapper接口函數重載問題

    關于Mybatis的mapper接口函數重載問題

    這篇文章主要介紹了關于Mybatis的mapper接口函數重載問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Spring MVC 自定義數據轉換器的思路案例詳解

    Spring MVC 自定義數據轉換器的思路案例詳解

    本文通過兩個案例來介紹下Spring MVC 自定義數據轉換器的相關知識,每種方法通過實例圖文相結合給大家介紹的非常詳細,需要的朋友可以參考下
    2021-09-09

最新評論

曲麻莱县| 阿拉善右旗| 和硕县| 兴安县| 来宾市| 凤翔县| 虎林市| 荣昌县| 万州区| 武山县| 大兴区| 格尔木市| 布尔津县| 新源县| 互助| 大名县| 牡丹江市| 临江市| 五家渠市| 二手房| 大厂| 雷州市| 莆田市| 大化| 越西县| 耒阳市| 大城县| 富宁县| 铜鼓县| 股票| 高密市| 安远县| 迁安市| 盐亭县| 土默特右旗| 余庆县| 湖南省| 泰州市| 隆昌县| 阳原县| 栾川县|