質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.37%

  • Java

    15109questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    244questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

ライフゲームのルール部分が上手く動作をしない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 151

Alpa

score 24

現在ライフゲームを作成しているのですが、
ライフゲームのルール部分のプログラムで思っていた動作をしないので、
質問させていただきました。

具体的にはcellUpdateメソッドの動作がWikipediaに載っていたルールに
沿って作ったと思っていたのですが、
Wikipediaのまま置いたセルが書いてある動作とは違う動作をしました。

何回もルールのチェックを行ったり、
プログラム内で実行順序の変更なども行ったのですが、
自分には解決できませんでした。
なので解決策を教えていただけると幸いです。

import javax.swing.*;
import javax.swing.Timer;
import javax.imageio.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;

public class life extends JFrame implements ActionListener, KeyListener
{
    int player_x = 20;
    int player_y = 40;

    boolean key_up = false;
    boolean key_down = false;
    boolean key_right = false;
    boolean key_left = false;

    boolean init = false;

    boolean running = false;

    Timer keyTimer = new Timer(50, this);
    Timer timer = new Timer(500, this);

    ArrayList<Cell> cells = new ArrayList<Cell>();

    Random rand = new Random();

    BufferedImage buff = new BufferedImage(500, 700, BufferedImage.TYPE_4BYTE_ABGR_PRE);
    Graphics2D g2 = buff.createGraphics();

    public static void main(String[] args)
    {
        life frame = new life();
        frame.setTitle("ライフゲーム");
        frame.setSize(500, 700);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setAlwaysOnTop(false);
        frame.setVisible(true);
    }

    life()
    {
        JPanel panel = new JPanel();
        panel.setLayout(null);

        keyTimer.setActionCommand("キー");
        timer.setActionCommand("更新");

        addKeyListener(this);

        getContentPane().add(panel, BorderLayout.CENTER);
    }

    public void actionPerformed(ActionEvent e)
    {
        String cmd = e.getActionCommand();

        switch(cmd){
            case "キー":{
                if(!running){
                    if(key_up){
                        if(player_y >= 50){
                            player_y -= 10;
                        }
                    }

                    if(key_down){
                        if(player_y <= 460){
                            player_y += 10;
                        }
                    }

                    if(key_right){
                        if(player_x <= 460){
                            player_x += 10;
                        }
                    }

                    if(key_left){
                        if(player_x >= 30){
                            player_x -= 10;
                        }
                    }

                    if(key_up || key_down || key_right || key_left) clear();
                }
            }break;

            case "更新":{
                cellUpdate();
            }break;
        }
    }

    public void paint(Graphics g)
    {
        if(!init){
            g.setColor(Color.white);
            g.fillRect(0, 0, 500, 700);

            setData();
            keyTimer.start();
            init = true;
        }

        buff = new BufferedImage(500, 700, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        g2 = buff.createGraphics();

        g2.setColor(Color.black);
        g2.drawRect(20, 40, 460, 440);

        for(int i = 0; i < cells.size(); i++){
            if(cells.get(i).status == 0){
                g2.setColor(Color.black);
            }else if(cells.get(i).status == 1){
                g2.setColor(Color.green);
            }

            g2.fillRect(cells.get(i).x, cells.get(i).y, 10, 10);

            g2.setColor(new Color(30, 30, 30));
            g2.drawRect(cells.get(i).x, cells.get(i).y, 10, 10);
        }

        if(!running){
            drawPlayer();
        }

        drawImage(buff, 0, 0);

        g2.dispose();
    }

    public void keyReleased(KeyEvent e)
    {
        switch(e.getKeyText(e.getKeyCode())){
            case "上": key_up = false; break;
            case "下": key_down = false; break;
            case "右": key_right = false; break;
            case "左": key_left = false; break;
            case "スペース":{
                for(int i = 0; i < cells.size(); i++){
                    if(cells.get(i).x == player_x && cells.get(i).y == player_y){
                        if(cells.get(i).status == 0){
                            cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 1));
                        }else if(cells.get(i).status == 1){
                            cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 0));
                        }
                    }
                }
            }break;

            case "S":{
                if(timer.isRunning()){
                    running = false;
                    timer.stop();
                    debug("STOP");
                }else{
                    running = true;
                    timer.start();
                    debug("START");
                }

                clear();
            }break;

            case "C":{
                cells.clear();
                setData();
                clear();
            }

            case "Enter": cellUpdate(); break;
        }
    }

    public void keyPressed(KeyEvent e)
    {
        switch(e.getKeyText(e.getKeyCode())){
            case "上": key_up = true; break;
            case "下": key_down = true; break;
            case "右": key_right = true; break;
            case "左": key_left = true; break;
        }
    }

    public void keyTyped(KeyEvent e){}

    void drawPlayer()
    {
        g2.setColor(Color.red);
        g2.fillRect(player_x, player_y, 10, 10);
    }

    void drawImage(BufferedImage Img, int x, int y)
    {
        Graphics g = getGraphics();
        g.drawImage(Img, x, y, this);
        g.dispose();
    }

    void clear()
    {
        g2.setColor(Color.white);
        g2.fillRect(0, 0, 500, 700);
        repaint();
    }

    void setData()
    {
        for(int i = 0; i < 46; i++){
            for(int j = 0; j < 44; j++){
                cells.add(new Cell((i + 1) * 10 + 10, (j + 1) * 10 + 30, 0));
            }
        }
    }

    void cellUpdate()
    {
        int alive = 0;

        for(int i = 0; i < cells.size(); i++){
            for(int j = 0; j < cells.size(); j++){
                if(cells.get(j).x == cells.get(i).x - 10 && cells.get(j).y == cells.get(i).y - 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x && cells.get(j).y == cells.get(i).y - 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x + 10 && cells.get(j).y == cells.get(i).y - 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x - 10 && cells.get(j).y == cells.get(i).y){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x + 10 && cells.get(j).y == cells.get(i).y){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x - 10 && cells.get(j).y == cells.get(i).y + 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x && cells.get(j).y == cells.get(i).y + 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }

                if(cells.get(j).x == cells.get(i).x + 10 && cells.get(j).y == cells.get(i).y + 10){
                    if(cells.get(j).status == 1){
                        alive++;
                    }
                }
            }

            if(alive <= 1){
                cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 0));
            }else if(alive == 2 || alive == 3 && cells.get(i).status == 1){
                cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 1));
            }else if(alive >= 4){
                cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 0));
            }else if(alive == 3 && cells.get(i).status == 0){
                cells.set(i, new Cell(cells.get(i).x, cells.get(i).y, 1));
            }

            alive = 0;
            clear();
        }
    }

    void debug(Object obj)
    {
        System.out.println(obj);
    }

    int random(int r)
    {
        return rand.nextInt(r);
    }
}

class Cell
{
    int x = 0;
    int y = 0;
    int status = 1;

    public Cell(int x, int y, int status)
    {
        this.x = x;
        this.y = y;
        this.status = status;
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mts10806

    2018/09/02 22:03

    「違う動きをした」とはどう動いたのでしょうか。「具体的には」という割にはどうなったか書かれていません。

    キャンセル

  • Alpa

    2018/09/02 22:06

    同じ動作をループするはずのセルのパターンが繁殖しました

    キャンセル

回答 1

checkベストアンサー

+1

面を一面しか持ってないように見えますが?
今の面と、次の時点の面の、2面は最低必要ですよ。

追記

Rubyですが、書いてみました。

data = <<EOF
++++++++++
++++++++++
+++OOOO+++
++++++++++
++++++++++
EOF

board = data.split(/\n/).map{|x| x.split(//)}

Y = board.size
X = board[0].size

def alive(board,y,x)
  return 0 if x<0 or x>=X or y<0 or y>=Y
  board[y][x] == "O" ? 1 : 0
end

def update(t0, t1)
  (0...Y).each do |i|
    (0...X).each do |j|
      life = alive(t0,i-1,j-1)+alive(t0,i-1,j)+alive(t0,i-1,j+1)+
             alive(t0,i  ,j-1)+                alive(t0,i  ,j+1)+
             alive(t0,i+1,j-1)+alive(t0,i+1,j)+alive(t0,i+1,j+1)
      t1[i][j] =
        case life
        when 2 then t0[i][j]
        when 3 then "O"
        else        "+"
        end
    end
  end
end

while gets == "\n"
  puts board.map{|x| x.join}
  next_board = Array.new(Y){Array.new(X)}
  update(board, next_board)
  board = next_board
end

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/02 22:07

    そうなんですか!
    2面必要なのは何故か教えて頂きたいです。

    キャンセル

  • 2018/09/02 22:14

    次の面の各点の生死は、今の面の各点の状態から、全箇所同時に判断する必要があります。

    キャンセル

  • 2018/09/02 22:18

    すいません
    具体的にコードを教えて頂きたいのですが無理ですか?
    コードの方が理解しやすいので

    キャンセル

  • 2018/09/02 22:23

    あなたのコードがよく理解できないので、無理です。
    2面作れば解決するのかどうかもよく分かりません。

    面を2面作って、今の面を見ながら、次の面を更新して、全部について終わったら入れ替えてください。

    キャンセル

  • 2018/09/02 22:38

    わかりました。
    すいませんありがとうございました!

    キャンセル

  • 2018/09/03 05:22

    わざわざありがとうございます!
    やっと出来ました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    15109questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    244questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。