Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Gra w życie :F


Gość povskill

Rekomendowane odpowiedzi

Opublikowano

2013-10-28_19-38-17.png

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JApplet;

/**
 *
 * @author PolishCivil
 */
public class LifeGame extends JApplet {
    
    public enum Direction {

        NORTHEAST(1, -1),
        NORTHWEST(-1, -1),
        NORTH(0, -1),
        SOUTHEAST(1, 1),
        SOUTHWEST(-1, 1),
        SOUTH(0, 1),
        EAST(1, 0),
        WEST(-1, 0);

        private final int horizontal;
        private final int vertical;

        private Direction(int horizontal, int vertical) {
            this.horizontal = horizontal;
            this.vertical = vertical;
        }

        public int getOffsetX() {
            return horizontal;
        }

        public int getOffsetY() {
            return vertical;
        }
    }
    private static final int ENTITY_SIZE = 10, MAX_ENTITIES = 500;
    /**
     * Rendering related fields
     */
    private float scale = 2.0f;
    private final Canvas canvas;

    /**
     * Generation related fields
     */
    private int[][] currentGeneration = new int[MAX_ENTITIES][MAX_ENTITIES], previousGeneration = new int[MAX_ENTITIES][MAX_ENTITIES];
    private int currentGenerationNumber = 0, previousGenerationNumber = 0;
    private AtomicBoolean automatic = new AtomicBoolean(false);

    /**
     * Input related fields
     */
    private boolean leftButton, rightButton;
    private AtomicBoolean inputLock = new AtomicBoolean(false);
    private long lastKeyPress = 0l;

    public LifeGame() throws HeadlessException {
        this.canvas = new Canvas();
        this.canvas.requestFocus();
        setPreferredSize(new Dimension(800, 600));
        this.canvas.addMouseWheelListener(new MouseWheelListener() {

            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                if (scale + e.getWheelRotation() > 0) {
                    scale += e.getWheelRotation();
                }
            }
        });
        this.canvas.addMouseListener(new MouseListener() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (inputLock.get()) {
                    return;
                }
                int worldX = (int) (e.getX() / (ENTITY_SIZE * scale));
                int worldY = (int) (e.getY() / (ENTITY_SIZE * scale));
                currentGeneration[worldX][worldY] = e.getButton() == 3 ? 0 : 1;
            }

            @Override
            public void mousePressed(MouseEvent e) {
                if (e.getButton() == 3) {
                    rightButton = true;
                } else {
                    leftButton = true;
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.getButton() == 3) {
                    rightButton = false;
                } else {
                    leftButton = false;
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
        this.canvas.addMouseMotionListener(new MouseMotionListener() {

            @Override
            public void mouseDragged(MouseEvent e) {
                if (inputLock.get()) {
                    return;
                }
                int worldX = (int) (e.getX() / (ENTITY_SIZE * scale));
                int worldY = (int) (e.getY() / (ENTITY_SIZE * scale));
                currentGeneration[worldX][worldY] = rightButton ? 0 : 1;
            }

            @Override
            public void mouseMoved(MouseEvent e) {
            }
        });
        this.canvas.addKeyListener(new KeyListener() {

            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyChar() == 's') {
                    automatic.set(!automatic.get());
                }
                if (System.currentTimeMillis() - lastKeyPress >= 50 && !automatic.get()) {
                    lastKeyPress = System.currentTimeMillis();
                    if (inputLock.get()) {
                        return;
                    }
                    if (e.getKeyChar() == 'c') {
                        previousGeneration = new int[MAX_ENTITIES][MAX_ENTITIES];
                        currentGeneration = new int[MAX_ENTITIES][MAX_ENTITIES];
                        previousGenerationNumber = 0;
                        currentGenerationNumber = 0;
                    }
                    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
                        nextGeneration();
                    } else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
                        previousGeneration();
                    }
                }
            }

            @Override
            public void keyReleased(KeyEvent e) {
            }
        });
    }

    @Override
    public void init() {
        super.add(this.canvas);
        this.canvas.createBufferStrategy(2);
        new Thread(new Runnable() {

            @Override
            public void run() {
                while (true) {
                    try {
                        renderLoop();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(LifeGame.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }).start();
    }

    /**
     * Rendering loop
     */
    private void renderLoop() throws InterruptedException {
        BufferStrategy strategy = this.canvas.getBufferStrategy();
        Thread.sleep(1000 / 30);//30fps
        if (automatic.get()) {
            nextGeneration();
        }
        do {
            do {
                Graphics graphics = strategy.getDrawGraphics();
                graphics.clearRect(0, 0, getWidth(), getHeight());
                draw((Graphics2D) graphics);
                graphics.dispose();
            } while (strategy.contentsRestored());
            strategy.show();
        } while (strategy.contentsLost());
        Toolkit.getDefaultToolkit().sync();
    }

    /**
     * Sets current generation data to previous one.
     */
    private void previousGeneration() {
        if (currentGenerationNumber == 0 || currentGenerationNumber - previousGenerationNumber <= 0) {
            return;
        }
        currentGenerationNumber--;
        copyArray(previousGeneration, currentGeneration);
    }

    /**
     * Process the next generation.
     */
    private void nextGeneration() {
        inputLock.set(true);
        previousGenerationNumber = currentGenerationNumber;
        currentGenerationNumber++;
        copyArray(currentGeneration, previousGeneration);
        int[][] nextGenEntities = new int[MAX_ENTITIES][MAX_ENTITIES];

        for (int worldX = 0; worldX < currentGeneration.length; worldX++) {
            int[] is = currentGeneration[worldX];
            for (int worldY = 0; worldY < is.length; worldY++) {
                int neighbors = getNeighborsCount(worldX, worldY);
                if (currentGeneration[worldX][worldY] == 1) {
                    if (neighbors == 2 || neighbors == 3) {
                        nextGenEntities[worldX][worldY] = 1;
                    }
                } else {
                    if (neighbors == 3) {
                        nextGenEntities[worldX][worldY] = 1;
                    }
                }
            }
        }
        copyArray(nextGenEntities, currentGeneration);
        inputLock.set(false);

    }

    /**
     * Gets count of neighbors for specified world position
     *
     * @param worldX - the world's x
     * @param worldY - the world's x
     * @return - count
     */
    private int getNeighborsCount(int worldX, int worldY) {
        int temp = 0;
        for (Direction direction : Direction.values()) {
            int xx = worldX + direction.getOffsetX();
            int yy = worldY + direction.getOffsetY();
            if (xx >= 0 && yy >= 0 && xx < currentGeneration.length && yy < currentGeneration.length && currentGeneration[xx][yy] == 1) {
                temp++;
            }
        }
        return temp;
    }

    /**
     * Draws things on screen
     *
     * @param g - graphics instance.
     */
    private void draw(Graphics2D g) {
        g.setColor(Color.BLUE.brighter());
        drawNet(g);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.BLACK);
        for (int x = 0; x < currentGeneration.length; x++) {
            int[] is = currentGeneration[x];
            for (int y = 0; y < is.length; y++) {
                if (is[y] == 1) {
                    g.fillOval(1 + (int) (x * (ENTITY_SIZE * scale)), 1 + (int) (y * (ENTITY_SIZE * scale)), (int) (ENTITY_SIZE * scale) - 1, (int) (ENTITY_SIZE * scale) - 1);
                }
            }
        }
        g.setFont(new Font("Arial Black", Font.PLAIN, 15));
        g.setColor(Color.BLACK);
        g.drawString("Generation " + currentGenerationNumber, 0, 10);
    }

    /**
     * Draws a net on whole screen
     *
     * @param g - graphics instance.
     */
    private void drawNet(Graphics2D g) {
        for (int i = 1; i < (this.getWidth() / (ENTITY_SIZE * scale)); i++) {
            g.drawLine((int) (i * (ENTITY_SIZE * scale)), 0, (int) (i * (ENTITY_SIZE * scale)), this.getHeight());
        }
        for (int i = 1; i < (this.getHeight() / (ENTITY_SIZE * scale)); i++) {
            g.drawLine(0, (int) (i * (ENTITY_SIZE * scale)), this.getWidth(), (int) (ENTITY_SIZE * scale) * i);
        }
    }

    /**
     * Copy 2D array
     *
     * @param src
     * @param dest
     */
    private static void copyArray(int[][] src, int[][] dest) {
        for (int i = 0; i < src.length; i++) {
            int[] aMatrix = src[i];
            int aLength = aMatrix.length;
            dest[i] = new int[aLength];
            System.arraycopy(aMatrix, 0, dest[i], 0, aLength);
        }
    }
}

Oczywiście nic to zaawansowanego nie jest ale ci którzy zaczynają przygodę z programowaniem mogą sobie zajrzeć.

pl.wikipedia.org/wiki/Gra_w_życie

Podgląd na żywo:

http://95.160.129.245/lifegame/
Opublikowano

Fajne fajne, nie ogarniam jak to jest zrobione ale fajnie działa, ogólnie chodzi o to że poszczególne istnienia dążą do skupienia się w grupach ?

Ogólnie to chodzi o to:

2013-10-28_19-38-17.png

Opublikowano

Pomijając fakt, że chce mi pobierać jave (chociaż ją mam) propsy za live demo.



Do jakiej populacji testowałeś? Robiłem kiedy takie coś na zaliczenie w c++ i directx sdk, ale wystarczyło mu odpalić na 1min i zaliczał.

 

 

Ciekaw jestem jak będzie się miała sprawa przy 100kkk+, nigdy nie doszedłem :P

 

 

 

Ogólnie polecam program golly(?). Ma sporo gotowych patternów można się pobawić

Opublikowano

fejm sie krenci h3h3h3

 

ale dupa, bo nie ma gotowych wiosek i trzeba budowac samym :<

/ GA-970A-UD3 / FX-6300 / Sapphire Xtreme 5830 / OCZ ZS 550W / Brutus M23 /

| MPC Coders Team | MPC Gold Member | C#, C++, PHP, (N)ASM, AutoIT, Python, Java |

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...