/*******************************************************************************
* Copyright (c) 2016 Alex Shapiro - github.com/shpralex
* This program and the accompanying materials
* are made available under the terms of the The MIT License (MIT)
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*******************************************************************************/
package com.sproutlife.model;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.swing.SwingUtilities;
import com.sproutlife.model.step.GameStep.StepType;
import com.sproutlife.model.step.GameStepEvent;
import com.sproutlife.model.step.GameStepListener;
public class GameThread {
private boolean playGame = false;
Thread innerThread;
GameStepListener gameStepListener;
GameModel gameModel;
ReentrantReadWriteLock interactionLock;
int sleepDelay;
int iterations;
boolean superSlowIntro;
boolean slowIntro;
boolean autoAdjust;
public GameThread(GameModel gameModel, ReentrantReadWriteLock interactionLock) {
this.gameModel = gameModel;
this.interactionLock = interactionLock;
this.autoAdjust = true;
this.sleepDelay = 0;
this.iterations = 1;
superSlowIntro = false;
slowIntro = true;
}
private GameModel getGameModel() {
return gameModel;
}
public void setPlayGame(boolean playGame) {
this.playGame = playGame;
if (playGame) {
new InnerGameThread().start();
}
}
public boolean getPlayGame() {
return playGame;
}
public void setAutoAdjust(boolean autoAdjust) {
this.autoAdjust = autoAdjust;
}
public void setSleepDelay(int sleepDelay) {
this.sleepDelay = sleepDelay;
}
public void setIterations(int iterations) {
this.iterations = iterations;
}
/*
* Only expecting one gameStepListener for now, therefore a "set" method
*/
public void setGameStepListener(GameStepListener gameStepListener) {
this.gameStepListener = gameStepListener;
}
private void fireStepBundlePerformed() {
if (gameStepListener!=null) {
GameStepEvent event = new GameStepEvent(StepType.STEP_BUNDLE);
gameStepListener.stepPerformed(event);
}
}
private int getSleepDelay() {
if (!autoAdjust) {
return sleepDelay;
}
int sleep = 1;
if (superSlowIntro) {
if (getGameModel().getTime()<100 ) {
sleep = 800 - (int) (Math.log10(getGameModel().getTime()/13.0+1)*800) ;
}
else {
sleep = Math.max(1, 40-(int) Math.sqrt(getGameModel().getTime()/4));
}
}
if (slowIntro && !superSlowIntro) {
if (getGameModel().getTime()<2000 ) {
sleep = 10;
}
else if (getGameModel().getTime()<4000 ) {
sleep = 8;
}
}
return sleep;
}
private int getIterations() {
if (!autoAdjust) {
return this.iterations;
}
int iterations = 1;
if(getGameModel().getEchosystem().getOrganisms().size()>120) {
iterations =2;
}
if(getGameModel().getEchosystem().getOrganisms().size()>180) {
iterations =4;
}
if (getGameModel().getEchosystem().getOrganisms().size()>240) {
iterations = 8;
}
return iterations;
}
private class InnerGameThread extends Thread {
public void run() {
while (playGame) {
try {
//synchronized (getGameModel().getEchosystem()) {
interactionLock.writeLock().lock();
getGameModel().performGameStep();
interactionLock.writeLock().unlock();
//}
int iterations = getIterations();
if (getGameModel().getTime() % iterations == 0) {
fireStepBundlePerformed();
int sleep = Math.max(1, getSleepDelay());
//Painting is glitchy if sleepDelay is less than 1;
Thread.sleep(sleep);
}
}
catch (InterruptedException ex) {}
}
}
}
}