欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

生命游戲介紹

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

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

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

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

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

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

一、效果展示

1.初始界面

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

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; // 每個細(xì)胞的像素大小
    private static final int GENERATIONS = 1000; // 演化代數(shù)
    private int[][] grid = new int[GRID_SIZE][GRID_SIZE]; // 當(dāng)前代棋盤
    private int[][] nextGrid = new int[GRID_SIZE][GRID_SIZE]; // 下一代棋盤
    private Pane pane = new Pane();
    private AnimationTimer timer;
    private boolean isRunning = false; // 運行狀態(tài)標(biāo)志

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

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

        // 創(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)建按鈕,便于停止觀察當(dāng)前棋盤狀態(tài) 
        Button startButton = new Button("運行");
        Button pauseButton = new Button("暫停");

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

        // 設(shè)置按鈕位置
        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(); // 結(jié)束動畫
                }
            }
        };
    }

    // 隨機(jī)初始化棋盤
    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); // 隨機(jī)生成0或1
            }
        }
    }

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

    // 暫停
    private void pauseGame() {
        isRunning = false; // 設(shè)置為暫停狀態(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) { // 當(dāng)前細(xì)胞是活的
                    nextGrid[i][j] = (liveNeighbors == 2 || liveNeighbors == 3) ? 1 : 0;
                } else { // 當(dāng)前細(xì)胞是死的
                    nextGrid[i][j] = (liveNeighbors == 3) ? 1 : 0;
                }
            }
        }
        copyNextGridToCurrent();
    }

    // 計算鄰居活細(xì)胞數(shù)量
    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復(fù)制到grid
    private void copyNextGridToCurrent() {
        for (int i = 0; i < GRID_SIZE; i++) {
            System.arraycopy(nextGrid[i], 0, grid[i], 0, GRID_SIZE);
        }
    }

    // 繪制當(dāng)前棋盤狀態(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); // 黑色表示活細(xì)胞,白色表示死細(xì)胞
                cell.setStroke(Color.GRAY); //細(xì)胞之間的邊框
                pane.getChildren().add(cell); // 將細(xì)胞添加到面板
            }
        }
    }
}

三、代碼解釋

1.常量設(shè)置

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

GRID_SIZE: 定義了棋盤的大小,當(dāng)前設(shè)置為 100。即棋盤是一個 100 x 100 的格子。

CELL_SIZE: 定義了每個細(xì)胞的像素大小,當(dāng)前設(shè)置為 10。因此,每個細(xì)胞在界面上將顯示為一個 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(); // 結(jié)束動畫
            }
        }
    };
}

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

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

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

//根據(jù)規(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) { // 當(dāng)前細(xì)胞是活的
                nextGrid[i][j] = (liveNeighbors == 2 || liveNeighbors == 3) ? 1 : 0;
            } else { // 當(dāng)前細(xì)胞是死的
                nextGrid[i][j] = (liveNeighbors == 3) ? 1 : 0;
            }
        }
    }
    copyNextGridToCurrent();
}

// 計算鄰居活細(xì)胞數(shù)量
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)來遍歷整個棋盤的細(xì)胞,得到其鄰居的數(shù)量用于判斷下一次迭代的狀態(tài)。

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

四、結(jié)語

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

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

相關(guān)文章

  • mybatisplus邏輯刪除基本實現(xiàn)和坑點解決

    mybatisplus邏輯刪除基本實現(xiàn)和坑點解決

    這篇文章主要介紹了mybatisplus邏輯刪除基本實現(xiàn)和坑點解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • JAVA NIO實現(xiàn)簡單聊天室功能

    JAVA NIO實現(xiàn)簡單聊天室功能

    這篇文章主要為大家詳細(xì)介紹了JAVA NIO實現(xiàn)簡單聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • SpringBoot整合ElasticSearch的示例代碼

    SpringBoot整合ElasticSearch的示例代碼

    本篇文章主要介紹了SpringBoot整合ElasticSearch的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 基于SpringBoot和Vue3的博客平臺發(fā)布、編輯、刪除文章功能實現(xiàn)

    基于SpringBoot和Vue3的博客平臺發(fā)布、編輯、刪除文章功能實現(xiàn)

    在上一個教程中,我們已經(jīng)實現(xiàn)了基于Spring?Boot和Vue3的用戶注冊與登錄功能。本教程將繼續(xù)引導(dǎo)您實現(xiàn)博客平臺的發(fā)布、編輯、刪除文章功能,需要的朋友參考一下
    2023-04-04
  • java注解處理器學(xué)習(xí)在編譯期修改語法樹教程

    java注解處理器學(xué)習(xí)在編譯期修改語法樹教程

    這篇文章主要為大家介紹了java注解處理器學(xué)習(xí)在編譯期修改語法樹教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 淺析Spring?Cloud?Gateway中的令牌桶限流算法

    淺析Spring?Cloud?Gateway中的令牌桶限流算法

    這篇文章主要為大家淺析了Spring?Cloud?Gateway中的令牌桶限流算法原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02
  • SpringBoot參數(shù)校驗Validator框架詳解

    SpringBoot參數(shù)校驗Validator框架詳解

    Validator框架就是為了解決開發(fā)人員在開發(fā)的時候少寫代碼,提升開發(fā)效率,Validator專門用來進(jìn)行接口參數(shù)校驗,今天通過本文給大家介紹SpringBoot參數(shù)校驗Validator框架,感興趣的朋友一起看看吧
    2022-06-06
  • Java多線程之synchronized關(guān)鍵字的使用

    Java多線程之synchronized關(guān)鍵字的使用

    這篇文章主要介紹了Java多線程之synchronized關(guān)鍵字的使用,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • springcloud實現(xiàn)注冊中心Eureka

    springcloud實現(xiàn)注冊中心Eureka

    這篇文章主要介紹了springcloud實現(xiàn)注冊中心Eureka,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Java?中的?clone(?)?和?new哪個效率更高

    Java?中的?clone(?)?和?new哪個效率更高

    很多朋友不太清楚clone()和new那個更快?針對這個問題我百度了好多資料,最終小編總結(jié)下關(guān)于Java?中的?clone(?)?和?new哪個效率更高的問題,感興趣的朋友跟隨小編一起看看吧
    2021-12-12

最新評論