Loading .idea/workspace.xml +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/brain/Brain.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/brain/Brain.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java" afterDir="false" /> </list> <option name="SHOW_DIALOG" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" /> Loading Loading @@ -46,10 +47,12 @@ </component> <component name="PropertiesComponent"><![CDATA[{ "keyToString": { "ASKED_ADD_EXTERNAL_FILES": "true", "Application.EC504 SameGameTris.executor": "Run", "RunOnceActivity.OpenProjectViewOnStart": "true", "RunOnceActivity.ShowReadmeOnStart": "true", "WebServerToolWindowFactoryState": "false", "git-widget-placeholder": "master", "kotlin-language-version-configured": "true", "node.js.detected.package.eslint": "true", "node.js.detected.package.tslint": "true", Loading Loading @@ -110,6 +113,7 @@ <workItem from="1706057188033" duration="218000" /> <workItem from="1706070762735" duration="2123000" /> <workItem from="1706112889389" duration="6798000" /> <workItem from="1706139932552" duration="5472000" /> </task> <task id="LOCAL-00001" summary="Apparently working version."> <created>1580084914114</created> Loading Loading @@ -193,8 +197,8 @@ <breakpoints> <line-breakpoint enabled="true" type="java-line"> <url>file://$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java</url> <line>626</line> <option name="timeStamp" value="3" /> <line>615</line> <option name="timeStamp" value="9" /> </line-breakpoint> </breakpoints> </breakpoint-manager> Loading src/edu/bu/ec504/spr24/brain/Brain.java +4 −12 Original line number Diff line number Diff line Loading @@ -12,10 +12,6 @@ import edu.bu.ec504.spr24.sameGameTris.SameGameTris; public abstract class Brain implements Runnable { // CONSTANTS /** * The number of milliseconds between Brain moves */ private static final long BRAIN_WAIT_MS = 1000; // FIELDS protected final GUI myGUI; // stores the GUI class attached to this Brain Loading @@ -38,18 +34,14 @@ public abstract class Brain implements Runnable { final public void allDone() {allDone = true;} /** * Starts the Brain a'thinking. * This is the code for requests decisions about which circles you Brain selects. * Asks the Brain to for a move, and effects it on the GUI. * * @see java.lang.Runnable#run() */ final public void run() { while (!allDone && !myGUI.gameOverQ()) { if (!allDone && !myGUI.gameOverQ()) { Board.Pos theNextMove = nextMove(); myGUI.makeMove(theNextMove.xx, theNextMove.yy); // i.e. click on the lower left corner try { Thread.sleep(BRAIN_WAIT_MS); } catch (InterruptedException ignored) {} myGUI.makeMove(theNextMove.xx, theNextMove.yy); } } Loading src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java +49 −11 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.*; import java.io.Serial; import java.lang.reflect.InvocationTargetException; import java.util.Date; import java.util.Random; import java.util.Timer; import java.util.TimerTask; Loading Loading @@ -56,6 +56,10 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { */ static private long DROP_CIRCLE_US = 5000000; /** * The number of microseconds between Brain moves */ private static final long BRAIN_WAIT_US = 1000000; /** * The number of empty rows on the top of the game. */ Loading Loading @@ -120,6 +124,8 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // ... Brain elements Brain theBrain; // the Brain (automated player) for the game Thread brainThread; // the thread that will run the Brain final ScheduledExecutorService brainExec = newScheduledThreadPool(2); // set up the brain threads private ScheduledFuture<?> brainFuture = null; // schedule for Brain events (i.e., make moves) // ... Tetris executor final ScheduledExecutorService tetrisExec = newScheduledThreadPool(2); // sets up tetris threads Loading Loading @@ -269,6 +275,7 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { */ @Override public void makeMove(int xx, int yy) { System.out.println(new Date()+": Moving to "+xx+", "+yy); circles[xx][yy].mouseEntered(null); // pretend the mouse was pressed at location (xx,yy) Timer t = new Timer(); TimerTask tt = new TimerTask() { Loading Loading @@ -428,17 +435,24 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { * Cancel schedules for adding / dropping circles. */ private void cancelTetrisingSchedules() { if (produceCircleFuture != null) { if (produceCircleFuture != null) produceCircleFuture.cancel(true); if (dropCircleFuture != null) dropCircleFuture.cancel(true); } /** * @return true iff tetrising is going on */ public boolean isTetrisingQ() { return produceCircleFuture!=null && produceCircleFuture.isCancelled()==false; } /** * Sets up threads that drop circles onto the board and move them down over time. * As {@link #numClicks} gets larger, circles come more often and drop faster. */ public void updateTetrising() { public void restartTetrising() { System.out.println("Restarting tetrising: "); // cancel the old schedules cancelTetrisingSchedules(); Loading @@ -457,8 +471,7 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // close down the brain highScoreName = null; if (theBrain != null) theBrain.allDone(); stopBrain(); // score panel totalPoints.setText("0"); Loading Loading @@ -506,9 +519,11 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { /* * Called to request a reshifting of the board (as necessary). * This should happen if some circles are rendered "clear"ed * @return true iff the shift succeeded without the game ending, * and false if the game ended as a result of the shift. */ final void shiftCircles() { final boolean shiftCircles() { /* start at the bottom and move up ... all cleared circles are * removed, with upper circles falling into their positions; * if a column is totally empty, then its rightmost columns Loading Loading @@ -578,11 +593,15 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // 3. (LAST ITEM) CHECK IF THE GAME HAS ENDED // This happens if every circle is surrounded by cleared circles or circles of a different color if (gameOverQ()) if (gameOverQ()) { doGameOver("exhausted all circles"); // all done return false; } } finally { GUIlock.unlock(); // release the circles for other processes } return true; } /** Loading @@ -591,12 +610,15 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { * @param feedback Some string to present to the user; typically the reason that the game is over. */ private void doGameOver(String feedback) { // close out other threads cancelTetrisingSchedules(); // cancel Tetrising threads stopBrain(); // stop the thinking Brain System.out.println("Game over, man!"); // check the high score int score = Integer.parseInt(totalPoints.getText()); highScore hs = new highScore(HIGH_SCORE_FILE); // check the high score if (hs.newRecordQ(score)) { // i.e. a new record _showMessage(null, "Game Over (" + feedback + ") - You got a new high score of " + score + " points!\n" + Loading Loading @@ -643,6 +665,10 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { return JOptionPane.showInputDialog(parent, message); } /** * Handle menu events * @param e The event to handle. */ public void actionPerformed(ActionEvent e) { Object source = e.getSource(); Loading Loading @@ -692,11 +718,23 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { private void startBrain(Brain theBrain) { this.theBrain = theBrain; highScoreName = theBrain.myName(); // the computer gets credit for any subsequent high score brainThread = new Thread(theBrain, "Brain Thread"); brainThread.start(); // brainThread = new Thread(theBrain, "Brain Thread"); // brainThread.start(); brainFuture = brainExec.scheduleAtFixedRate(theBrain, 0, BRAIN_WAIT_US, TimeUnit.MICROSECONDS); } // For handling the menu checkBox /** * Stops the Brain that makes move. */ private void stopBrain() { if (theBrain != null) theBrain.allDone(); brainFuture.cancel(true); } /** * Handles the menu checkBox */ public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); Loading src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java +7 −5 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ class SelfAwareCircle extends Component implements MouseListener, SelfAwareListe * The mouse button was released. */ public void mouseReleased(MouseEvent e) { System.out.println("Released mouse:"+Thread.currentThread().getName()); _highlightButton(Visibility.clear); // register the score Loading @@ -207,11 +208,12 @@ class SelfAwareCircle extends Component implements MouseListener, SelfAwareListe sameGameTrisGUI.score(SelfAwareCircle.getRegionLength(), getColor()))); // request that the board be shifted appropriately sameGameTrisGUI.shiftCircles(); if (sameGameTrisGUI.shiftCircles()) { // if shifting concluded without ending the game // update Tetrising sameGameTrisGUI.updateNumClicks(); sameGameTrisGUI.updateTetrising(); if (!sameGameTrisGUI.isTetrisingQ()) sameGameTrisGUI.restartTetrising(); } } Loading Loading
.idea/workspace.xml +6 −2 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/brain/Brain.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/brain/Brain.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java" afterDir="false" /> </list> <option name="SHOW_DIALOG" value="false" /> <option name="HIGHLIGHT_CONFLICTS" value="true" /> Loading Loading @@ -46,10 +47,12 @@ </component> <component name="PropertiesComponent"><![CDATA[{ "keyToString": { "ASKED_ADD_EXTERNAL_FILES": "true", "Application.EC504 SameGameTris.executor": "Run", "RunOnceActivity.OpenProjectViewOnStart": "true", "RunOnceActivity.ShowReadmeOnStart": "true", "WebServerToolWindowFactoryState": "false", "git-widget-placeholder": "master", "kotlin-language-version-configured": "true", "node.js.detected.package.eslint": "true", "node.js.detected.package.tslint": "true", Loading Loading @@ -110,6 +113,7 @@ <workItem from="1706057188033" duration="218000" /> <workItem from="1706070762735" duration="2123000" /> <workItem from="1706112889389" duration="6798000" /> <workItem from="1706139932552" duration="5472000" /> </task> <task id="LOCAL-00001" summary="Apparently working version."> <created>1580084914114</created> Loading Loading @@ -193,8 +197,8 @@ <breakpoints> <line-breakpoint enabled="true" type="java-line"> <url>file://$PROJECT_DIR$/src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java</url> <line>626</line> <option name="timeStamp" value="3" /> <line>615</line> <option name="timeStamp" value="9" /> </line-breakpoint> </breakpoints> </breakpoint-manager> Loading
src/edu/bu/ec504/spr24/brain/Brain.java +4 −12 Original line number Diff line number Diff line Loading @@ -12,10 +12,6 @@ import edu.bu.ec504.spr24.sameGameTris.SameGameTris; public abstract class Brain implements Runnable { // CONSTANTS /** * The number of milliseconds between Brain moves */ private static final long BRAIN_WAIT_MS = 1000; // FIELDS protected final GUI myGUI; // stores the GUI class attached to this Brain Loading @@ -38,18 +34,14 @@ public abstract class Brain implements Runnable { final public void allDone() {allDone = true;} /** * Starts the Brain a'thinking. * This is the code for requests decisions about which circles you Brain selects. * Asks the Brain to for a move, and effects it on the GUI. * * @see java.lang.Runnable#run() */ final public void run() { while (!allDone && !myGUI.gameOverQ()) { if (!allDone && !myGUI.gameOverQ()) { Board.Pos theNextMove = nextMove(); myGUI.makeMove(theNextMove.xx, theNextMove.yy); // i.e. click on the lower left corner try { Thread.sleep(BRAIN_WAIT_MS); } catch (InterruptedException ignored) {} myGUI.makeMove(theNextMove.xx, theNextMove.yy); } } Loading
src/edu/bu/ec504/spr24/sameGameTris/SameGameTris.java +49 −11 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.*; import java.io.Serial; import java.lang.reflect.InvocationTargetException; import java.util.Date; import java.util.Random; import java.util.Timer; import java.util.TimerTask; Loading Loading @@ -56,6 +56,10 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { */ static private long DROP_CIRCLE_US = 5000000; /** * The number of microseconds between Brain moves */ private static final long BRAIN_WAIT_US = 1000000; /** * The number of empty rows on the top of the game. */ Loading Loading @@ -120,6 +124,8 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // ... Brain elements Brain theBrain; // the Brain (automated player) for the game Thread brainThread; // the thread that will run the Brain final ScheduledExecutorService brainExec = newScheduledThreadPool(2); // set up the brain threads private ScheduledFuture<?> brainFuture = null; // schedule for Brain events (i.e., make moves) // ... Tetris executor final ScheduledExecutorService tetrisExec = newScheduledThreadPool(2); // sets up tetris threads Loading Loading @@ -269,6 +275,7 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { */ @Override public void makeMove(int xx, int yy) { System.out.println(new Date()+": Moving to "+xx+", "+yy); circles[xx][yy].mouseEntered(null); // pretend the mouse was pressed at location (xx,yy) Timer t = new Timer(); TimerTask tt = new TimerTask() { Loading Loading @@ -428,17 +435,24 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { * Cancel schedules for adding / dropping circles. */ private void cancelTetrisingSchedules() { if (produceCircleFuture != null) { if (produceCircleFuture != null) produceCircleFuture.cancel(true); if (dropCircleFuture != null) dropCircleFuture.cancel(true); } /** * @return true iff tetrising is going on */ public boolean isTetrisingQ() { return produceCircleFuture!=null && produceCircleFuture.isCancelled()==false; } /** * Sets up threads that drop circles onto the board and move them down over time. * As {@link #numClicks} gets larger, circles come more often and drop faster. */ public void updateTetrising() { public void restartTetrising() { System.out.println("Restarting tetrising: "); // cancel the old schedules cancelTetrisingSchedules(); Loading @@ -457,8 +471,7 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // close down the brain highScoreName = null; if (theBrain != null) theBrain.allDone(); stopBrain(); // score panel totalPoints.setText("0"); Loading Loading @@ -506,9 +519,11 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { /* * Called to request a reshifting of the board (as necessary). * This should happen if some circles are rendered "clear"ed * @return true iff the shift succeeded without the game ending, * and false if the game ended as a result of the shift. */ final void shiftCircles() { final boolean shiftCircles() { /* start at the bottom and move up ... all cleared circles are * removed, with upper circles falling into their positions; * if a column is totally empty, then its rightmost columns Loading Loading @@ -578,11 +593,15 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { // 3. (LAST ITEM) CHECK IF THE GAME HAS ENDED // This happens if every circle is surrounded by cleared circles or circles of a different color if (gameOverQ()) if (gameOverQ()) { doGameOver("exhausted all circles"); // all done return false; } } finally { GUIlock.unlock(); // release the circles for other processes } return true; } /** Loading @@ -591,12 +610,15 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { * @param feedback Some string to present to the user; typically the reason that the game is over. */ private void doGameOver(String feedback) { // close out other threads cancelTetrisingSchedules(); // cancel Tetrising threads stopBrain(); // stop the thinking Brain System.out.println("Game over, man!"); // check the high score int score = Integer.parseInt(totalPoints.getText()); highScore hs = new highScore(HIGH_SCORE_FILE); // check the high score if (hs.newRecordQ(score)) { // i.e. a new record _showMessage(null, "Game Over (" + feedback + ") - You got a new high score of " + score + " points!\n" + Loading Loading @@ -643,6 +665,10 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { return JOptionPane.showInputDialog(parent, message); } /** * Handle menu events * @param e The event to handle. */ public void actionPerformed(ActionEvent e) { Object source = e.getSource(); Loading Loading @@ -692,11 +718,23 @@ public class SameGameTris extends GUI implements ActionListener, ItemListener { private void startBrain(Brain theBrain) { this.theBrain = theBrain; highScoreName = theBrain.myName(); // the computer gets credit for any subsequent high score brainThread = new Thread(theBrain, "Brain Thread"); brainThread.start(); // brainThread = new Thread(theBrain, "Brain Thread"); // brainThread.start(); brainFuture = brainExec.scheduleAtFixedRate(theBrain, 0, BRAIN_WAIT_US, TimeUnit.MICROSECONDS); } // For handling the menu checkBox /** * Stops the Brain that makes move. */ private void stopBrain() { if (theBrain != null) theBrain.allDone(); brainFuture.cancel(true); } /** * Handles the menu checkBox */ public void itemStateChanged(ItemEvent e) { Object source = e.getItemSelectable(); Loading
src/edu/bu/ec504/spr24/sameGameTris/SelfAwareCircle.java +7 −5 Original line number Diff line number Diff line Loading @@ -199,6 +199,7 @@ class SelfAwareCircle extends Component implements MouseListener, SelfAwareListe * The mouse button was released. */ public void mouseReleased(MouseEvent e) { System.out.println("Released mouse:"+Thread.currentThread().getName()); _highlightButton(Visibility.clear); // register the score Loading @@ -207,11 +208,12 @@ class SelfAwareCircle extends Component implements MouseListener, SelfAwareListe sameGameTrisGUI.score(SelfAwareCircle.getRegionLength(), getColor()))); // request that the board be shifted appropriately sameGameTrisGUI.shiftCircles(); if (sameGameTrisGUI.shiftCircles()) { // if shifting concluded without ending the game // update Tetrising sameGameTrisGUI.updateNumClicks(); sameGameTrisGUI.updateTetrising(); if (!sameGameTrisGUI.isTetrisingQ()) sameGameTrisGUI.restartTetrising(); } } Loading