I am attempting to make a Game of Nim for a school project, but whenever the computer attempts to make its move, it will not actually do anything unless there is three or less rocks left. My temp code will also execute in the console, so it runs through it, its just not working.
These are the custom voids:
public void winnerCheck(){
if(rocksLeft == 0 && lastPlayer == 0){
logBox.append("Plose gameOver");
}else if(rocksLeft == 0 && lastPlayer == 1){
logBox.append("Close gameOver");
}
//temp
System.out.println("winnerCheck() successful");
}
public void playersMove() throws BadLocationException{
lastPlayer = 0;
//used to gather players input and attempt to make a move
try{
playersRocks = Integer.parseInt(txtfPlayer.getText());
if(playersRocks <= 3 && playersRocks>=1){
rocksLeft -= playersRocks;
logBox.append("You have taken "+playersRocks+" rocks.\nThere are: "+rocksLeft+" rocks left.\nIt is the computer's turn.\n\n");
}else{
isValid = false;
}
}catch(NumberFormatException e){
isValid = false;
}
//temp
System.out.println("playersMove() successful");
}
public void computerAttempt(int computersRocks){
//this void is a snippet for the computer trying to make a play.
//contains only outputs and rocksLeft altering equation
logBox.append("\nThe computer is making a play.\n");
try {
//makes the game feel more realistic, as the computer takes time to make a move.
Thread.sleep(1600);
} catch (InterruptedException ex) {
Logger.getLogger(GameOfNim.class.getName()).log(Level.SEVERE, null, ex);
}
rocksLeft -= computersRocks;
logBox.append("The computer has taken "+computersRocks+" rocks.\nThere are: "+rocksLeft+" rocks left.\nIt is your turn!\n\n");
}
public void computersMove() throws BadLocationException{
lastPlayer = 1;
//computer will attempt to win, if not possible at the time it will take a random number
if(rocksLeft == 3){
computerAttempt(2);
}else if(rocksLeft == 2){
computerAttempt(1);
}else if(rocksLeft == 1){
logBox.append("The computer takes 1 rock.\n There are: 0 rocks left.\n\n Y O U H A V E W O N\n\n");
}else if(rocksLeft > 3){
computersRocks = (int) (Math.random()*(3-1+1)+1);
}
//temp
System.out.println("computersMove() succesful");
}
These are the two buttons:
private void buttonStartActionPerformed(java.awt.event.ActionEvent evt) {
//starts/resets game
rocksLeft = (int)(Math.random()*(30-15+1)+15);
buttonStart.setText("Reset");
buttonPlay.setEnabled(true);
logBox.setText("T h e g a m e h a s b e g u n !\n\nThere are: "+rocksLeft+" rocks left.\nIt is your turn!\n\n");
}
private void buttonPlayActionPerformed(java.awt.event.ActionEvent evt) {
//check if game is over
if(rocksLeft == 0){
logBox.append("The game has completed!\n Press the reset button to play again!");
System.out.println("gameOver succesful");
}else{
try {
//allows each player to move then checks if the player won or not
playersMove();
winnerCheck();
computersMove();
winnerCheck();
//temp
System.out.println("buttonPlay() succesful\n");
} catch (BadLocationException ex) {
Logger.getLogger(GameOfNim.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I don't know the game you are making, but here is your mistake I think.
If there are more than 3 rocks left, you call
}else if(rocksLeft > 3){
computersRocks = (int) (Math.random()*(3-1+1)+1);
}
Which, I think, should be
}else if(rocksLeft > 3){
computerAttempt((int) (Math.random()*(3-1+1)+1));
}
Because you just changed the variable without calling the method on the value.(And I presume the important variable is the 'rocksLeft' which never got changed in your code, when the value was > 3.
Related
I am doing the following programming exercise: Killer Garage Door. The statement is:
Situation
You have been hired by a company making electric garage doors.
Accidents with the present product line have resulted in numerous
damaged cars, broken limbs and several killed pets. Your mission is to
write a safer version of their controller software. Specification
We always start with a closed door. The remote control has exactly one
button, with the following behaviour.
If the door is closed, a push starts opening the door, and vice-versa
It takes 5 seconds for the door to open or close completely
While the door is moving, one push pauses movement, another push resumes movement in the same direction
In order to make the door safer, it has been equiped with
resistance-based obstacle detection. When the door detects an
obstacle, it must immediately reverse the direction of movement. Input
A string where each character represents one second, with the
following possible values.
'.' No event
'P' Button has been pressed
'O' Obstacle has been detected (supersedes P)
As an example, '..P....' means that nothing happens for two seconds,
then the button is pressed, then no further events. Output
A string where each character represents one second and indicates the
position of the door (0 if fully closed and 5 fully open). The door
starts moving immediately, hence its position changes at the same
second as the event. Example
..P...O..... as input should yield 001234321000 as output
I have written the following code:
public class Door {
public static String run(String events) {
System.out.println("\n\n\nevents: "+events);
int count = 0;
StringBuilder result = new StringBuilder();
boolean movingUp = false;
boolean movingDown = false;
for(char c : events.toCharArray()){
System.out.println("movingUp: "+movingUp);
System.out.println("movingDown: "+movingDown);
System.out.println("c: "+c);
System.out.println("count: "+count);
System.out.println("result: "+result);
if(c=='.'){
if(movingUp){
result.append(count < 5 ? ++count : 5);
}else if(movingDown){
result.append(count > 0 ? --count : 0);
}else{
result.append(count);
}
}else if(c=='P'){
if(count==5){
movingUp = false;
movingDown = true;
result.append(count > 0 ? --count : 0);
}else if(movingUp){
movingUp = false;
result.append(count);
}else if(movingDown){
movingDown = false;
result.append(count);
}else{
movingUp = true;
result.append(count < 5 ? ++count : 5);
}
}else if(c=='O'){
movingUp = false;
movingDown = true;
result.append(count > 0 ? --count : 0);
}
}
return result.toString();
}
}
I was wondering how could we handle, when there is a pause and then the door resumes again, to be able to keep it going up or down, as it was doing before the pause?
Here are some tests, the ones marked with →, are the ones where the pause or obstacle behaviour fails because of currently the code assumes that after a pause it should go upwards, and after an obstacle it should go downwards.
import static org.junit.Assert.*;
import org.junit.Test;
public class MainTest {
#Test
public void testNormalOperation() {
test("should stay closed unless button is pressed (no buttonpresses)", "..........", "0000000000");
test("should start opening on buttonpress", "P..", "123");
test("should open completely and stay open", "P....", "12345");
}
#Test
public void testPause() {
test("should start opening and pause on second buttonpress", "P.P..", "12222");
test("→ should resume closing on third buttonpress", ".....P......P.P..P....", "0000012345554333321000");
}
#Test
public void testObstacles() {
test("should reverse while opening", "P.O....", "1210000");
test("→ should reverse while closing", "P.O....", "12345554345555");
}
#Test
public void testObstaclePlusPause () {
test("→ should reverse while opening (and allow pause)", "P..OP..P..", "1232222100");
}
#Test
public void testExample() {
test("should start opening and reverse when obstacle", "..P...O.....", "001234321000");
}
private void test(String description, String events, String result) {
assertEquals(description ,result, Door.run(events));
}
}
I have also read:
https://users.cs.jmu.edu/bernstdh/web/common/lectures/summary_state_pattern.php
How could we implement a garage door keeping track of what was its last moving direction?
You're almost there. So in the interest of keeping your code intact I attempted
to introduce as few changes as needed.
However one correction is needed before proceeding - one of your test cases
is not correct, the 2nd test case in testObstacles is not valid.
Was:
test("→ should reverse while closing", "P.O....", "12345554345555");
// in the above the first 'P' would start it "12" and the first "O" should
// immediately reverse it (which would be reversing while opening) "1000"
So assuming the text is correct and the expected result is correct then the input should be:
test("→ should reverse while closing", "P.......P.O....", "12345554345555");
Short answer:
Introduce a boolean which records the previous up or down movement:
boolean lastUp = true; // default to true since we always assume initially CLOSED
The remaining changes are in th 'P' and 'O' case using lastUp:
else if (movingUp)
{
movingUp = false;
lastUp = true; // ADDED
result.append (count);
}
...
else if (movingDown)
{
movingDown = false;
lastUp = false; // ADDED
result.append (count);
}
... and update default case
else
{
movingUp = lastUp; // CHANGED
movingDown = !lastUp; // ADDED
result.append(movingUp ? ++count : --count); // CHANGED
}
And in 'O' case:
{
movingUp = !movingUp; // CHANGED
movingDown = !movingDown; // CHANGED
lastUp = !lastUp; // ADDED
result.append(movingUp ? ++count : --count); // CHANGED
}
Long Answer
Well, the long answer uses a different approach and this is essentially #grodzi 's answer (state then input) which has a great explanation but since it took me so long to enter it the point is moot.
I'll add it since it is in the language of your choice.:
public static class Door
{
enum DoorStates { OPEN, CLOSED, MOVINGUP, MOVINGDOWN, PAUSED }
public static String run (String events)
{
int count = 0;
StringBuilder result = new StringBuilder ();
DoorStates currentState = DoorStates.CLOSED;
DoorStates lastMovingState = DoorStates.MOVINGUP;
for (char c:events.toCharArray ())
{
switch (currentState)
{
case OPEN:
if (c == 'P') {
currentState = DoorStates.MOVINGDOWN;
count--;
}
// do nothing for O and .
break;
case CLOSED:
if (c == 'P') {
currentState = DoorStates.MOVINGUP;
count = 1;
}
// do nothing for O and .
break;
case MOVINGUP: // movingup
if (c == 'P') {
currentState = DoorStates.PAUSED; // paused
} else if (c == 'O') {
currentState = DoorStates.MOVINGDOWN; // movingdown
count--;
} else {
if (count < 5) {
count++;
}
if (count == 5) {
currentState = DoorStates.OPEN; // open
}
}
break;
case MOVINGDOWN:
if (c == 'P') {
currentState = DoorStates.PAUSED; // paused
} else if (c == 'O') {
currentState = DoorStates.MOVINGUP; // movingup
count++;
} else {
if (count > 0) {
count--;
}
if (count == 0) {
currentState = DoorStates.CLOSED;
}
}
break;
case PAUSED:
if (c == 'P') {
currentState = lastMovingState;
count = (currentState == DoorStates.MOVINGUP ? count+1 : count-1);
}
// do nothing for O and .
break;
} // end switch
if (currentState == DoorStates.MOVINGUP ||
currentState == DoorStates.MOVINGDOWN) {
lastMovingState = currentState;
}
result.append (count);
} // endfor
return result.toString();
} // end run
} // door class
An approach by using states.
We can list two trivial ones: closed and opened.
I will name them respectively idleUp, and idleDown.
transitions for idleUp:
P (user pushed the button): so you are now activeUp
transitions for activeUp:
P (user pushed another time): idleUp (keep the direction, but do nothing)
O: activeDown
End (door is fully opened): idleDown
transitions for activeDown:
P: idleDown
O: activeUp
End: idleUp
transitions for idleDown:
P (user pushed the button): so you are now activeDown
Something like graph below.
+----------+ P +--------+
| activeUp +<----->+ idleUp |
+----------+ +--------+
| ^ O ^
|End +---------+ |End
v v |
+----------+ P +------------+
| idleDown +<----->+ activeDown |
+----------+ +------------+
Notice the (somehow elegant) symmetry between activeUp-idleUp and activeDown-idleDown.
In your approach you are char first, then state. In below code we are state first, then char.
Instead of considering four states, we only "code" two: active and idle (but under the hood we indeed have four states, simply conditionned via variable instead of classes)
You sure can use a pattern state, but feels a bit tiresome.
function simu (str) {
let direction = 1 // 1 for up, -1 for down
let pos = 0 // initially closed
let active = false
let out = '' // the return string
for (let c of str) {
if (active) {
if (c === '.') {
pos += 1 * direction
if (pos <= 0 || pos >= 5) {// End
active = false
direction *= -1
}
}
else if (c === 'O') {
direction *= -1
pos += 1 * direction // instant change of direction
}
else if (c === 'P') {
active = false
}
} else { // idle
if (c === 'P') {
active = true
pos += 1 * direction // instant change too
}
}
out += pos
}
return out
}
function test(libel, s, exp) {
const out = simu(s)
if (out != exp) {
throw 'failed '+libel+' got '+out+' expect '+exp
}
console.log('OK', s, '->', out)
}
test("should stay closed unless button is pressed (no buttonpresses)", "..........", "0000000000")
test("should start opening on buttonpress", "P..", "123")
test("should open completely and stay open", "P....", "12345")
test("should start opening and pause on second buttonpress", "P.P..", "12222")
test("→ should resume closing on third buttonpress", ".....P......P.P..P....", "0000012345554333321000")
test("should reverse while opening", "P.O....", "1210000")
test("→ should reverse while closing", "P.......P.O....", "123455554345555") //thx Andy
test("→ should reverse while opening (and allow pause)", "P..OP..P..", "1232222100")
test("should start opening and reverse when obstacle", "..P...O.....", "001234321000")
I'm trying to program a bug to move around an array attached to a custom Room object, whilst keeping count of how many times each tile has been stepped on.
The Room object is working properly, as are the movement and the counting. However, the bug's coordinates, bugX and bugY, are somehow reverting to 0 after exiting the nextMove method. Their values only revert when exiting the method; even the last line of code in the nextMove method itself uses their new values.
Relevant portion of the method is attached, but other sections can be added upon request.
if (dirNum == 0 && bugY < length-1) //Move up
bugY++;
else if (dirNum == 1 && bugX < width-1) //Move right
bugX++;
else if (dirNum == 2 && bugY > 0) //Move down
bugY--;
else if (dirNum == 3 && bugX > 0) //Move left
bugX--;
else {
System.out.println("Error: Cannot move " + direction + ".");
canMove = false;
dirNum = generator.nextInt(4);
continue;
}
This is the context for the command itself.
while (endSim == false) {
nextMove(bugX, bugY);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
The declarations where the starting coordinates are assigned aren't inside any loops, let alone where the variable itself is called.
The problem is the one described by #T.J.Crowder in his answer though applied to java.
Variables passed as parameters in java are passed by value. If the value is changed by the method receiving the parameter, the change only affects the value inside that method. The "outside" value doesn't change.
What you can do is to encapsulate the coords in an object and pass the encapsulating object as a parameter.
Then the method will receive the object by value, and change it's state (instead of the value of the object).
For a deeper understanding see this question
EDIT I:
I cleand up the code a bit. Though it is is missing the declaration of room and simSentinel, if you add that you should have a running example.
public class Bug{
public int x=0;
public int y=0;
}
public class SimpleSim {
private int dirNum = 0;
private int length = 20;
private int width = 20;
private boolean canMove = true;
private Random generator = new Random();
private boolean endSim = false;
public static void main(String [] args) {
SimpleSim simpleSim = new SimpleSim();
simpleSim.start();
}
private void start() {
Bug myBug = new Bug();
// Give the bug some initial x, y values.
myBug.x = 0;
myBug.y = 0;
while (endSim == false) {
nextMove(myBug);
System.out.print(room.printRoom() + "\n\nNext move? (y/n) ");
simSentinel = in.next();
if (simSentinel.charAt(0) == 'n')
endSim = true;
}
}
}
public void nextMove(Bug bug){
if (dirNum == 0 && bug.y < length-1) //Move up
bug.y++;
else if (dirNum == 1 && bug.x < width-1) //Move right
bug.x++;
else if (dirNum == 2 && bug.y > 0) //Move down
bug.y--;
else if (dirNum == 3 && bug.x > 0) //Move left
bug.x--;
else {
System.out.println("Error: Cannot move " + "?" + ".");
canMove = false;
dirNum = generator.nextInt(4);
}
}
}
It seems that you are passing your bugX and bugY parameters by value. In this case, changing their value inside the method won't affect their values outside the method.
You may want to make your nextMove method return the new values for bugX and bugY after they are computed so that you can gather them back into your actual bugX and bugY variables
i have a problem with one thing. I have a map of 10 cities and a civilian. I want the civilian to be walking from city to city randomly. But the problem is that the city is beeing chosen on and on so the civilian is changing the destination before he reachs it. This is my part of a code of a Jpanel where everything is drawn:
#Override
public void run() {
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException ex) {
}
}
}
private void update() {
if (game != null && running == true) {
c.goTo(cities); // c is civilian
}
}
and this is part of code for civilian
private boolean set = true;
public void move(int x, int y) {
if (this.location.x != x || this.location.y != y) {
if (this.location.x > x) {
this.location.x -= 1;
} else {
this.location.x += 1;
}
if (this.location.y > y) {
this.location.y -= 1;
} else {
this.location.y += 1;
}
}
}
public void goTo(ArrayList<City> cities) {
City city;
if (set) {
city = cities.get(rand());
move(city.location.x, city.location.y);
set = false;
} else {
set = true;
}
}
public int rand() {
int i;
Random rand = new Random();
i = rand.nextInt(10);
return i;
}
How to solve it ?
So, your problem is here:
while (running) {
update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException ex) {
}
}
You're calling update every 17 milliseconds which in turn is causing your civilian to move to a new city every 17 milliseconds. You could make a separate statement that calls update while another boolean statement is false so that you travel only when he is in a city.
For example:
boolean travelling = //whatever you go about to configure this
while(travelling == false){
update();
}
This will cause him to only travel when he is not in a city. Here is some very rough code (you will have to configure it to your liking):
//civilian x //civilian y
if(this.location.x == //randomed city.x && this.location.y == //randomed city.y){
travelling = false;
}
This will most likely need to be within the run() method in your first set of code, so it can be checked over and over. But let me explain what the above code is doing:
First, you have a thread or something keeping it running checking if your civilian's x and y correspond to the most recently randomed city's x and y, obviously when they're the same, the civilian is at the city.
Second, when the x and y's are the same, the statement makes travelling false
Third, When travelling is false, your custom update method is called, picking a new city, at random and putting your civilian back on the move.
I'm coding up a GUI game of craps. There is a JButton called "roll" which when clicked rolls the dice for the game. The GUI then displays what you rolled using jpeg's of die faces.
Everything works great, except I'm supposed to now add an animation to the GUI. My idea was to somehow rapidly display different face values for a short period of time (simulating a "roll") using the same method of displaying the jpeg's. However, as I'm sure you all know, that doesn't work.
I'm familiar with the idea of EDT and the Timer class, but I'm not sure exactly how to use them. Basically I want this animation to happen when I hit the "roll" button, and when the animation is finished, I want it to display what was actually rolled like it did before.
Any help would be greatly appreciated. Here's the code I have thus far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/* This is the GUI declaration */
public class NCrapsGUI extends JFrame {
//code...
/* Action when "roll" is clicked */
private void rollActionPerformed(java.awt.event.ActionEvent evt){
game.rollDice();
//Rolls both die
sumOfDice.setText(Integer.toString(game.getSum()));
//Displays the sum of the die
numRolls.setText(Integer.toString(game.getNumRolls()));
//Displays the number of rolls in each game
// <editor-fold defaultstate="collapsed" desc="Die JPEG's">
// If statements display the die face based on the number rolled
if (game.getDie1Value() == 1) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face1.jpg")));
}
if (game.getDie1Value() == 2) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face2.jpg")));
}
if (game.getDie1Value() == 3) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face3.jpg")));
}
if (game.getDie1Value() == 4) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face4.jpg")));
}
if (game.getDie1Value() == 5) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face5.jpg")));
}
if (game.getDie1Value() == 6) {
die1Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face6.jpg")));
}
if (game.getDie2Value() == 1) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face1.jpg")));
}
if (game.getDie2Value() == 2) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face2.jpg")));
}
if (game.getDie2Value() == 3) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face3.jpg")));
}
if (game.getDie2Value() == 4) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face4.jpg")));
}
if (game.getDie2Value() == 5) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face5.jpg")));
}
if (game.getDie2Value() == 6) {
die2Disp.setIcon(new javax.swing.ImageIcon(getClass().getResource("/face6.jpg")));
}
//</editor-fold>
/*
* If the game is beyond the first roll, it checks to see if the sum of the
* values rolled equal 7 or the point value for a loss or win respectively.
* If it is a win, it adds a win. Likewise for a loss.
*/
if (game.getGameStatus() == 2) {
if (game.getSum() == game.getPoint()) {
game.addWin();
numWins.setText(Integer.toString(game.getWins()));
game.setGameStatus(1);
game.setPoint(0);
game.resetRolls();
return;
}
if (game.getSum() == 7) {
game.addLoss();
numLosses.setText(Integer.toString(game.getLosses()));
game.setGameStatus(1);
game.setPoint(0);
game.resetRolls();
return;
}
}
/*
* This checks to see if the game is on the first roll. If it is, it checks
* if the sum of the die is 7 or 11 for a win, or 2, 3, or 12 for a loss. If
* not, it passes it on to the next roll and sets the point value to the sum
*/
if (game.getGameStatus() == 1) {
game.setPoint(game.getSum());
dieSum.setText(Integer.toString(game.getPoint()));
if (((game.getSum() == 7) || ((game.getSum() == 11)))) {
game.addWin();
numWins.setText(Integer.toString(game.getWins()));
game.setPoint(0);
dieSum.setText(Integer.toString(game.getPoint()));
game.resetRolls();
return;
}
if (((game.getSum() == 2) || ((game.getSum()) == 3)) || (game.getSum()) == 12) {
game.addLoss();
numLosses.setText(Integer.toString(game.getLosses()));
game.setPoint(0);
dieSum.setText(Integer.toString(game.getPoint()));
game.resetRolls();
return;
} else {
game.setGameStatus(2);
}
}
}
EDIT WITH UPDATED CODE!!!
Here's where the Timer and array are declared:
public class NCrapsGUI extends JFrame
{
private Timer timer;
private int numPlayers;
private int totalIcons = 6;
private ImageIcon imageArray[];`
/* CODE */
And here is where the array is populated inside the NCrapsGUI constructor:
imageArray = new ImageIcon[totalIcons];
for (int i = 0; i < 6 ;i++)
{
int temp = i + 1;
imageArray[i] = new ImageIcon("face" + temp + ".jpg");
}
initComponents();`
This is the entire rollActionPerformed method. I'm guessing the Timer gets started right
at the beginning, but whenever I try to start it I get loads of error. However, when I
I made a new JPanel seperately, and made it implement action listener, I got no
errors. I tried adding implements ActionListner to this declaration, but NetBeans literally
would not let me type anything in.
private void rollActionPerformed(java.awt.event.ActionEvent evt) {
game.rollDice();
//Rolls both die
sumOfDice.setText(Integer.toString(game.getSum()));
//Displays the sum of the die
numRolls.setText(Integer.toString(game.getNumRolls()));
//Displays the number of rolls in each game
// <editor-fold defaultstate="collapsed" desc="Die JPEG's">
// If statements display the die face based on the number rolled
if (game.getDie1Value() == 1)
{
die1Disp.setIcon(imageArray[0]);
}
if (game.getDie1Value() == 2)
{
die1Disp.setIcon(imageArray[1]);
}
if (game.getDie1Value() == 3)
{
die1Disp.setIcon(imageArray[2]);
}
if (game.getDie1Value() == 4) {
die1Disp.setIcon(imageArray[3]);
}
if (game.getDie1Value() == 5) {
die1Disp.setIcon(imageArray[4]);
}
if (game.getDie1Value() == 6)
{
die1Disp.setIcon(imageArray[5]);
}
if (game.getDie2Value() == 1)
{
die2Disp.setIcon(imageArray[0]);
}
if (game.getDie2Value() == 2)
{
die2Disp.setIcon(imageArray[1]);
}
if (game.getDie2Value() == 3)
{
die2Disp.setIcon(imageArray[2]);
}
if (game.getDie2Value() == 4)
{
die2Disp.setIcon(imageArray[3]);
}
if (game.getDie2Value() == 5)
{
die2Disp.setIcon(imageArray[4]);
}
if (game.getDie2Value() == 6)
{
die2Disp.setIcon(imageArray[5]);
}
//</editor-fold>
/*
* If the game is beyond the first roll, it checks to see if the sum of the
* values rolled equal 7 or the point value for a loss or win respectively.
* If it is a win, it adds a win. Likewise for a loss.
*/
if (game.getGameStatus() == 2) {
if (game.getSum() == game.getPoint()) {
game.addWin();
numWins.setText(Integer.toString(game.getWins()));
game.setGameStatus(1);
game.setPoint(0);
game.resetRolls();
return;
}
if (game.getSum() == 7) {
game.addLoss();
numLosses.setText(Integer.toString(game.getLosses()));
game.setGameStatus(1);
game.setPoint(0);
game.resetRolls();
return;
}
}
`
Your basic idea behind the animation is a good one I think, but whether it works or not is all in the implementation details of course. I suggest
That you read in your images and make ImageIcons once, probably at the start of the program.
That you put the icons into an ImageIcon array with a length of 7 -- but you'll put an icon into the 1-6 slots, leaving the 0th item null.
That you use a Swing Timer to swap these icons randomly with some appropriate delay, say 200 or 300 msec.
That you use a a Random object to get a random number between 1 and 6, and then with this number as your array index, get the Icon out of the array.
That you display the ImageIcons in a JLabel (or two JLabels if you're displaying 2 die) and swap Icons by simply calling the JLabel's setIcon(...) method.
Edit
You state in your comment that you tried:
timer = new Timer(100,this);
And that's your problem -- your use of this. You shouldn't try to use the same ActionListner for everything. Instead create an ActionListener right there, where you need it. Something like,
timer = new Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent actionEvt) {
// ... put your ActionListener's code here
}
});
Hey im trying to create a random way to pick a team of 4 from a linkedlist and am wondering if this code will work.
heres an example code
public static void enterGame(Client c) {
int n = teamSize;
boolean startNewGame = false;
if(waitingPlayers.size() <= 3) {
return; // not enough players
}
startNewGame = true;
if(startNewGame) {
System.out.println("Starting new game");
for(int i=0; i<n; i++) {
Collections.shuffle(waitingPlayers);
System.out.println("Picking random player");
waitingPlayers.remove(c);
System.out.println("removing from random player list");
players.add(c);
System.out.println("adding player to ingame list");
}
}
}
I would use Collections.shuffle() and a sublist. In order to know if your code works why don't you test it (unit test or just some try)?
Also, this part:
boolean startNewGame = false;
if(waitingPlayers.size() > 3) {
startNewGame = true;
} else {
startNewGame = false;
return;
}
if(startNewGame) {
is over complicated, I would replace it by:
if(waitingPlayers.size() <= 3) {
return; // not enough players
}
Full code:
public static void enterGame(final Client c) {
if(waitingPlayers.size() <= 3) {
return; // not enough players
}
System.out.println("Starting new game");
Collections.shuffle(waitingPlayers);
System.out.println("Picking random players");
// ? to be replaced by the real type of objects inside waitingPlayers
final List<?> picked = waitingPlayers.subList(0, 3);
players.addAll(picked);
waitingPlayers.removeAll(picked);
}
You have a bug - you are picking a number from 0 to n. If n is selected, you will get an out of bounds exception. Other fhan that it seems fine.