Initial commit of Game of Life project. Added project configuration files for NetBeans, including genfiles.properties, project.properties, and project.xml. Implemented core classes: Cellula for cell state management and GameOfLifeApplet for the graphical interface and game logic. The applet supports mouse interactions for cell manipulation and includes buttons for random filling and controlling the simulation.

This commit is contained in:
Stefano Rossi 2025-07-10 03:41:50 +02:00
parent a54610c542
commit 2799c2f581
Signed by: chadmin
GPG key ID: 9EFA2130646BC893
20 changed files with 2452 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/nbproject/private/
/build/

8
.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
.idea/misc.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_19" default="true" project-jdk-name="openjdk-19" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/GameOfLife2D.iml" filepath="$PROJECT_DIR$/GameOfLife2D.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

11
GameOfLife2D.iml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

26
LICENSE Normal file
View file

@ -0,0 +1,26 @@
# DON'T BE A DICK PUBLIC LICENSE
> Version 1.1, December 2016
> Copyright (C) 2024 Rossi Stefano
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document.
> DON'T BE A DICK PUBLIC LICENSE
> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
1. Do whatever you like with the original work, just don't be a dick.
Being a dick includes - but is not limited to - the following instances:
1a. Outright copyright infringement - Don't just copy this and change the name.
1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
2. If you become rich through modifications, related works/services, or supporting the original work,
share the love. Only a dick would make loads off this work and not buy the original work's
creator(s) a pint.
3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.

3
applet.policy Normal file
View file

@ -0,0 +1,3 @@
grant {
permission java.security.AllPermission;
};

73
build.xml Normal file
View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="gameoflife" default="default" basedir=".">
<description>Builds, tests, and runs the project gameoflife.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="gameoflife-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

BIN
images/filled.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
images/start.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
images/started.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

3
manifest.mf Normal file
View file

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

1799
nbproject/build-impl.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
build.xml.data.CRC32=f6080af1
build.xml.script.CRC32=193fd0b3
build.xml.stylesheet.CRC32=f85dc8f2@1.111.0.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=f6080af1
nbproject/build-impl.xml.script.CRC32=d2ad8918
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.111.0.48

View file

@ -0,0 +1,89 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=gameoflife
application.vendor=Administrator
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/gameoflife.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
includes=**
jar.compress=false
javac.classpath=
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.external.vm=false
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=1.7
javac.target=1.7
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.html5=false
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
jlink.launcher=false
jlink.launcher.name=gameoflife
main.class=gameoflife.Gameoflife
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=Zulu_8.0.412_8
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=-Djava.security.policy=applet.policy
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

16
nbproject/project.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>gameoflife</name>
<explicit-platform explicit-source-supported="true"/>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>

View file

@ -0,0 +1,52 @@
package gameoflife;
public class Cellula {
boolean viva; //vero se viva
//Color colore = Color.BLACK; //colore della cellula
boolean destino; //lo stato successivo
//costruttore vuoto
public Cellula(){
this.viva = false;
this.destino = false;
}
//costruttore con parametri
public Cellula(boolean viva, boolean destino){
this.viva = viva;
this.destino = destino;
}
//verifica lo stato della cellula
public boolean diagnosi(){
return this.viva;
}
//decide che vive
public void vivi(){
this.viva = true;
}
//decide che muore
public void muori(){
this.viva = false;
}
//decide che domani vivra
public void vivrai(){
this.destino = true;
}
//decide che domani sara morta
public void morirai(){
this.destino = false;
}
//inverte lo stato vitale
public void toggleVita(){
this.viva = !this.viva;
}
public void impostaDestino(){
this.viva = this.destino;
}
}

View file

@ -0,0 +1,342 @@
package gameoflife;
// importazione delle classi di libreria necessarie
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.*;
public class GameOfLifeApplet extends Applet implements MouseListener, MouseMotionListener, ActionListener, Runnable {
//////////////////////////////////////////////
//VARIABILI DI DISEGNO DEL CONTESTO GRAFICO///
Image imgOffScreen;
Graphics gOffScreen;
Thread thAgg = new Thread(this);
private int coorX = 0, coorY = 0; //
private int rigClick = 0, colClick = 0; //
private int lato = 0; //
private int w = 0; //
private int h = 0; //
//////////////////////////////////////////////
Button bAvanti;
public static int numRighe = 440; //numero di colonne della griglia
public static int numColonne = 400; //numero di righe
private Cellula[][] griglia = new Cellula[numRighe][numColonne];
private Button bRandomFill1, bRandomFill2, bRandomFill3, bRandomFill4, bRandomFill5;
//istanzio un oggetto Griglia
@Override
public void init() {
this.setSize(800, 900);
this.setBackground(Color.BLUE);
this.addMouseListener(this);
this.addMouseMotionListener(this);
bAvanti = new Button("Play/Pause"); // assegno la label Avanti al pulsante avanti
bAvanti.addActionListener(this); // assegno l action listener al pulsante bAvanti
this.add(bAvanti); //aggiungo il pulsante al contesto grafico
bRandomFill1 = new Button("Fill Random 1 su 2");
bRandomFill1.addActionListener(this);
this.add(bRandomFill1);
bRandomFill2 = new Button("Fill Random 1 su 3");
bRandomFill2.addActionListener(this);
this.add(bRandomFill2);
bRandomFill3 = new Button("Fill Random 1 su 5");
bRandomFill3.addActionListener(this);
this.add(bRandomFill3);
bRandomFill4 = new Button("Fill Random 1 su 10");
bRandomFill4.addActionListener(this);
this.add(bRandomFill4);
bRandomFill5 = new Button("Fill Random 1 su 20");
bRandomFill5.addActionListener(this);
this.add(bRandomFill5);
imgOffScreen = createImage(this.getWidth(), this.getHeight());
gOffScreen = imgOffScreen.getGraphics();
for (int m = 0; m < numRighe; m++) {
for (int n = 0; n < numColonne; n++) {
griglia[m][n] = new Cellula(false, false);
if((m>60 && n>60) && (n < numColonne - 60 && m < numRighe - 60) && (m == 220 || n == 200)){
griglia[m][n].vivi();
griglia[m][n].vivrai();
}
}
}
}
@Override
public void update(Graphics g){
paint(g);
}
@Override
public void paint(Graphics g) {
w = this.getWidth(); //larghezza
h = this.getHeight(); //altezza
bAvanti.setLocation(10, (int) (h/10 * 0.6)); //riposiziono i pulsatni
bRandomFill1.setLocation(10, h/10); //riposiziono i pulsatni
bRandomFill2.setLocation(10,(int) (h/10 * 1.4)); //riposiziono i pulsatni
bRandomFill3.setLocation(10, (int) (h/10 * 1.8)); //riposiziono i pulsatni
bRandomFill4.setLocation(10, (int) (h/10 * 2.2)); //riposiziono i pulsatni
bRandomFill5.setLocation(10, (int) (h/10 * 2.6)); //riposiziono i pulsatni
//se ho piu rige che colonne
lato = w / numColonne;
gOffScreen.clearRect(0, 0, w, h);
gOffScreen.setColor(Color.BLACK);
//ciclo per la stampa della tabella
for (int m = 0; m < numRighe; m++) {
for (int n = 0; n < numColonne; n++) {
gOffScreen.fillRect(lato * n,lato * m, lato, lato);
if (griglia[m][n].diagnosi() == true) {
//in le il prossimo stato della cellula sara viva la colo ro verdo se no rossa
if(griglia[m][n].destino == true){
gOffScreen.setColor(Color.GREEN);
}
else if(griglia[m][n].destino == false){
gOffScreen.setColor(Color.RED);
}
gOffScreen.fillOval(lato * n, lato * m, lato, lato);
gOffScreen.setColor(Color.BLACK);
}
}
}
g.drawImage(imgOffScreen, 0, 0, bAvanti);
}
public void mouseClicked(MouseEvent e) {
//System.out.println(e.getButton());
if (e.getButton() == MouseEvent.BUTTON1) {
coorX = e.getX();
coorY = e.getY();
//trova in quale quadrato si e cliccato
trovaQuadratoCliccato();
griglia[rigClick][colClick].toggleVita();
} else if (e.getButton() == MouseEvent.BUTTON2) {
for (int rig = 0; rig < numRighe; rig++) {
for (int col = 0; col < numColonne; col++) {
griglia[rig][col].muori();
}
}
}
calcolaDestinoCellule();
repaint();
}
public void mouseDragged(MouseEvent e) {
coorX = e.getX();
coorY = e.getY();
if (e.getModifiers() == MouseEvent.BUTTON1_MASK) { //esegue solo se si preme il tasto sx del mouse che corrisponde al valore 1
trovaQuadratoCliccato();
griglia[rigClick][colClick].vivi();
} else if (e.getModifiers() == MouseEvent.BUTTON3_MASK) { //esegue solo se si preme il tasto dx del mouse che corrisponde al valore 3
trovaQuadratoCliccato();
griglia[rigClick][colClick].muori();
} else {
}
calcolaDestinoCellule();
repaint();
}
//questo metodo, conoscendo le coordinate x e y del clic setta la riga e la colonna in cui si trova la cellula cliccata
public void trovaQuadratoCliccato() {
//Trovo la colonna
for (int i = 0; i < numColonne; i++) {
if (coorX > i * lato) {
colClick = i;
}
}
//Trovo la riga
for (int i = 0; i < numRighe; i++) {
if (coorY > i * lato) {
rigClick = i;
}
}
}
//Quasto è il metodo di action Listener che viene attivato quando si preme il pulsante
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bAvanti) {
if(!thAgg.isAlive()){
thAgg.start();
//System.out.println("start");
}
else if(!thAgg.isInterrupted()){
thAgg.interrupt();
thAgg = new Thread(this);
//System.out.println("interr");
}
}
else if (e.getSource() == bRandomFill1) {
randomFill(2);
}
else if (e.getSource() == bRandomFill2) {
randomFill(3);
}
else if (e.getSource() == bRandomFill3) {
randomFill(5);
}
else if (e.getSource() == bRandomFill4) {
randomFill(10);
}
else if (e.getSource() == bRandomFill5) {
randomFill(20);
}
}
public void randomFill(int value){
for (int rig = 0; rig < numRighe; rig++) {
for (int col = 0; col < numColonne; col++) {
//genero un valore intero da 0 al param passato,
// se random ritorna un val <= 1 allora la setta viva se no morta
if(Math.rint(Math.random()*value) <= 1) griglia[rig][col].vivi();
else griglia[rig][col].muori();
}
}
calcolaDestinoCellule();
repaint();
}
//con questo metodo calcolo il destino delle cellule, ovvero lo stato successivo che devono avere
public void calcolaDestinoCellule() {
int vicini = 0; //serve per calolare le cellule vicine
for (int rig = 0; rig < numRighe; rig++) {
for (int col = 0; col < numColonne; col++) {
// conto le cellule vive vicino a questa
if (col > 0 && rig < numRighe - 1) {
if (griglia[rig + 1][col - 1].diagnosi()) {
vicini++;
}
}
if (rig < numRighe - 1) {
if (griglia[rig + 1][col].diagnosi()) {
vicini++;
}
}
if (col < numColonne - 1 && rig < numRighe - 1) {
if (griglia[rig + 1][col + 1].diagnosi()) {
vicini++;
}
}
if (col > 0) {
if (griglia[rig][col - 1].diagnosi()) {
vicini++;
}
}
if (col < numColonne - 1) {
if (griglia[rig][col + 1].diagnosi()) {
vicini++;
}
}
if (col > 0 && rig > 0) {
if (griglia[rig - 1][col - 1].diagnosi()) {
vicini++;
}
}
if (rig > 0) {
if (griglia[rig - 1][col].diagnosi()) {
vicini++;
}
}
if (rig > 0 && col < numColonne - 1) {
if (griglia[rig - 1][col + 1].diagnosi()) {
vicini++;
}
}
//se la cellula è viva e ha 2 o 3 vicini allora rimane viva, altrimenti muore
if ((griglia[rig][col].diagnosi() == true && vicini == 2) || (griglia[rig][col].diagnosi() == true && vicini == 3)) {
griglia[rig][col].vivrai();
} else {
griglia[rig][col].morirai();
}
//se la cellula è morta e ha 3 vicini allora vive
if (griglia[rig][col].diagnosi() == false && vicini == 3) {
griglia[rig][col].vivrai();
} else if (griglia[rig][col].diagnosi() == false) {
griglia[rig][col].morirai();
} else {
}
vicini = 0; // resetto il contatore
}
}
}
public void eseguiDestino() {
for (int rig = 0; rig < numRighe; rig++) {
for (int col = 0; col < numColonne; col++) {
griglia[rig][col].impostaDestino();
}
}
}
public void mouseMoved(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
@Override
public void run() {
boolean flag = true;
while (flag) {
try {
Thread.sleep(80);
eseguiDestino();
calcolaDestinoCellule();
repaint();
} catch (InterruptedException ex) {
flag = false;
}
}
}
}