Lottery Program Ignores Function - java

I'm meant to write a program that lists one random number after the other, which it does (along with a beep). However, it ignores a fundamental function needed for the program to run correctly. The ask() function does what it implies, it asks the user to input an integer between the range (1000-9999) which is then compared to the winning number (random) to see if the user correctly guessed it and thus won. I've only recently started writing in Java so I'm not very sure if there's a basic mistake I'm making. Any help would be appreciated!
package edu.pupr.pega4;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Scanner;
import javax.swing.JOptionPane;
import javax.swing.Timer;
public class Pega4Driver {
public static void main(String[] args) {
Pega4 test = new Pega4(2000, true);
test.start();
JOptionPane.showMessageDialog(null, "Quit program?");
JOptionPane.showMessageDialog(null, "Perdiste!!!");
System.exit(0);
}
}
class Pega4 {
private int interval; //Time interval for new number to appear
private boolean beep; //BEEP
private int number; //The input number
private int tiradas = 1; //Counter
private int winNum; //The winning number
//Constructor
public Pega4(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
//Returns a random number within a specified range
public double getRandomIntegerBetweenRange(double min, double max){
double x = (int)(Math.random()*((max-min)+1))+min;
return x;
}
public void start() {
class Pega4Inner implements Asker, ActionListener {
Scanner input = new Scanner(System.in);
Date now = new Date();
#Override
public void ask() {
System.out.println("Entrar numero deseado: ");
number = input.nextInt();
//Input Validation
if (number < 1000 || number > 9999)
{
System.out.println("Entrada invalida. Entrar numero deseado: ");
number = input.nextInt();
}
System.out.println(now);
}
#Override
public void actionPerformed(ActionEvent e) {
winNum = (int) getRandomIntegerBetweenRange(1000, 9999);
System.out.println("Tirada #" + (tiradas++) + ": " + winNum);
if (beep)
Toolkit.getDefaultToolkit().beep();
if (winNum == number)
{
JOptionPane.showMessageDialog(null, "Ganaste!!!");
System.exit(0);
}
}
}
ActionListener listener = new Pega4Inner();
Timer timer = new Timer(interval, listener);
timer.start();
}
}
The Pega4Inner class implements an interface named Asker created by me. Its code is as follows:
package edu.pupr.pega4;
public interface Asker {
void ask();
}

You would need to actually call your ask() method from somewhere :)
I think a proper point to do that in your current code would be in the beginning of your actionPerformed() method in Pega4Inner :
public void actionPerformed(ActionEvent e) {
ask();
winNum = (int) getRandomIntegerBetweenRange(1000, 9999);
…
EDIT
Based on your requirement to call ask() only once, one way to do it is by taking this method out of your inner class and put it in your outer class, then call it explicitly in your driver class. So your Pega4 class could look like this :
class Pega4 {
private int interval; //Time interval for new number to appear
private boolean beep; //BEEP
private int number; //The input number
private int tiradas = 1; //Counter
private int winNum; //The winning number
//Constructor
Date now = new Date();
Scanner input = new Scanner(System.in);
public Pega4(int interval, boolean beep) {
this.interval = interval;
this.beep = beep;
}
//Returns a random number within a specified range
public double getRandomIntegerBetweenRange(double min, double max) {
double x = (int) (Math.random() * ((max - min) + 1)) + min;
return x;
}
public void ask() {
System.out.println("Entrar numero deseado: ");
number = input.nextInt();
//Input Validation
while (number < 1000 || number > 9999) { // not IF here
System.out.println("Entrada invalida. Entrar numero deseado: ");
number = input.nextInt();
}
System.out.println(now);
}
public void start() {
class Pega4Inner implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// ask();
winNum = (int) getRandomIntegerBetweenRange(1000, 9999);
System.out.println("Tirada #" + (tiradas++) + ": " + winNum);
if (beep) {
Toolkit.getDefaultToolkit().beep();
}
if (winNum == number) {
JOptionPane.showMessageDialog(null, "Ganaste!!!");
System.exit(0);
}
}
}
ActionListener listener = new Pega4Inner();
Timer timer = new Timer(interval, listener);
timer.start();
}
}
And then in your Pega4Driver class :
...
Pega4 test = new Pega4(2000, true);
test.ask();
test.start();
...

Related

Swing Timer and ActionListener with StackOverflowError

I got a homework that I have tried for a long time and even asked professor about it and still not understand what gone wrong in this code. I have absolutely no idea on how to initialize time ( in SoilTempData constructor ) and not sure on what's wrong with the error so I got no idea on how to fix it. I also can't change codes much because of the Questions to remain the structure of the given code
[This is the given Diagram][1]
package Iot;
import java.util.ArrayList;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class SoilTempData implements ActionListener{
private final int REPORT_ROUND = 1000/100;
ArrayList<Integer> data;
private int round;
private int nextPrintIndex;
private Timer time;
private SoilTempIoT iot;
public SoilTempData(SoilTempIoT iot){
data = new ArrayList<>(10);
round = 0;
nextPrintIndex = 0;
time = new Timer(100, new SoilTempData(iot));
iot = new SoilTempIoT();
}
public void start() {
time.start();
}
public void actionPerformed(ActionEvent e){
if(!(round == REPORT_ROUND))
time.start();
else
printStat();
}
public void printStat() {
int min = data.get(nextPrintIndex);
int max = data.get(nextPrintIndex);
int sum = 0;
double average = 0.0;
double sd = 0.0;
System.out.println("********** Report Current Data: **********");
System.out.print("New set of data: ");
for(int i = nextPrintIndex ; i < data.size() ; i++) {
System.out.print(data.get(i) +", ");
sum += data.get(i);
round++;
}
average = sum/data.size();
for(int i = nextPrintIndex ; i < data.size() ; i++) {
sd += Math.pow((data.get(i) - average),2);
}
System.out.printf("\nTotal records: %d\n",REPORT_ROUND*round);
System.out.println("Statistics:");
if(!data.isEmpty()) {
System.out.printf("Min = %.2f\nMax = %.2f\nAverage = %.2f\nSD = %.2f\n",min,max,average,sd);
}
else
System.out.println("No data to report!");
nextPrintIndex = REPORT_ROUND*round;
}
}
and this is SoilTempIoT
package Iot;
import java.awt.event.ActionListener;
import java.util.Random;
public class SoilTempIoT {
public static final int MIN_TEMP = 10;
public static final int MAX_TEMP = 60;
private int temp;
private Random rand;
public SoilTempIoT() {
rand = new Random();
temp = rand.nextInt(50) + 10;
}
public int getTemp() {
int i = rand.nextInt(21) - 10;
return temp+i;
}
}
and Main class ( which can't change anything because of the Question but incase anyone want to take a look at it )
package Iot;
import javax.swing.JOptionPane;
public class SoilTempDataTest {
public static void main(String[] args) {
SoilTempData sensor = new SoilTempData(new SoilTempIoT());
sensor.printStat();
sensor.start();
JOptionPane.showMessageDialog(null, "Quit?");
System.exit(0);
}
}
If my question isn't good in any way please tell me I will improve overtime.
Edit : I also need to do it so that SoilTempData read data from SoilTempIoT 100ms and every 1000ms it will print out the Stat.
[1]: https://i.stack.imgur.com/VDefv.png
public SoilTempData(SoilTempIoT iot){
data = new ArrayList<>(10);
round = 0;
nextPrintIndex = 0;
time = new Timer(100, new SoilTempData(iot));
iot = new SoilTempIoT();
}
When you initialize time, you create another instance. That calls the same constructor, which initializes time, which creates another instance, etc.
Just use time = new Timer(100, this);

How can I implement a thread that gets user input?

I've implemented a thread that get user input by keyboard. However, when user sets input my program returns an IllegalThreadStateException error, at line 23.
import java.util.Scanner;
public class Main {
static MyThread myThread = new MyThread();
static public boolean answered = false;
public static void main(String[] args) {
String s = "";
while (!s.equalsIgnoreCase("q")) {
int seconds = 0, average = 5;
if (seconds > average) {
myThread.stop();
String phrase = choosePhrase(seconds, average);
System.out.println(phrase);
Scanner keyboard = new Scanner(System.in);
s = keyboard.nextLine();
} else {
long createdMillis = System.currentTimeMillis();
myThread.start();
while (!answered && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
private static String choosePhrase(int seconds, int average) {
if (seconds > average + 10) {
return "¿D?";
} else if (seconds > average + 5) {
return "¿E?";
} else {
return "¿F?";
}
}
}
class MyThread extends Thread {
static String[] questions = {"¿A?", "¿B?", "¿C?"};
public void run() {
System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
Scanner keyboard = new Scanner(System.in);
String s = keyboard.nextLine();
stop();
}
}
Why am I getting this exception? How do I make the thread gets and exits correctly to main function?
To make a thread exits proprely you have to use myThread.interrupt();
I've solved the issue with your suggestions:
import javax.swing.JOptionPane;
public class Main {
public static void main(String[] args) {
Latency latency = new Latency();
latency.start();
}
}
class Latency {
int seconds = 0, average = 5;
MyThread myThread;
ObjectToPass o = new ObjectToPass();
public void start() {
String s = "";
Thread t = null;
while (!s.equalsIgnoreCase("q")) {
// The program has just begun, or user has answered a question,
// or term has expired.
seconds = 0;
if (myThread != null) {
myThread.shutdown();
myThread = null;
}
if (o.answered) {
o.answered = false;
myThread = new MyThread(o, new String[]{"¿A?", "¿B?", "¿C?"});
} else {
myThread = new MyThread(o, new String[]{"¿D?", "¿E?", "¿F?"});
}
t = new Thread(myThread);
t.start();
long createdMillis = System.currentTimeMillis();
while (!this.o.getPlay() && seconds < average) {
long nowMillis = System.currentTimeMillis();
seconds = (int) ((nowMillis - createdMillis) / 1000);
}
}
}
}
class ObjectToPass {
boolean answered = true;
public synchronized boolean getPlay() {
return answered;
}
public synchronized void setPlay(boolean answered) {
this.answered = answered;
}
}
class MyThread implements Runnable {
ObjectToPass o;
static String[] questions;
public MyThread(ObjectToPass o, String[] questions) {
this.o = o;
this.questions = questions;
}
public void run() {
// System.out.println("MyThread running");
Double d = Math.random() * 100;
int n = (int) (Math.ceil(d) % 3);
String question = questions[n];
System.out.println(question);
// Scanner keyboard = new Scanner(System.in);
// String s = keyboard.nextLine();
Object[] options = {"Yes", "No"};
int oo = JOptionPane.showOptionDialog(null,
question, "Question", JOptionPane.YES_OPTION,
JOptionPane.NO_OPTION, null, options, options[0]);
this.o.setPlay(true);
}
public void shutdown() {
Thread.currentThread().interrupt();
return;
}
}

How to make two Threads wait and notify the correct way in Tic Tac Toe game

I followed some discussion on the website and implemented some suggestions but I was not able to complete the task.
I have this assignment to build Tic Tac Toe game in Java.
There's a lot of tutorials on the web I know, but I wanted to build it using threads for each player so that only one player at a time could enter X/O to the board and I was not able to figure out the implementation for the wait/ notify.
To be honest, I find it a bit confusing! I guess the logic is 90% done, and I am wondering how to finish it.
Basically, I have these classes:
abstract public class Player extends Thread
public class HumanPlayer extends Player
public class MachinePlayer extends Player
public class Board
public class Game
public class Main
I'll paste first the players classes. Notice the run method I tried to Synchronize on top of the gameOver variable:
Player.java
abstract public class Player extends Thread {
abstract int getMyTurn() ;
abstract String getPlayerName() ;
abstract void setPlayerName(String n ) ;
abstract void setSign(int n ) ;
abstract int getSign() ;
}
MachinePlayer.java
import java.util.Random;
public class MachinePlayer extends Player {
private String name ;
private int sign ;
Board board ;
public MachinePlayer(Board board) {
this.board = board;
}
#Override
public void run() {
System.out.println("Player "+name+" turn:" );
while (!board.isGameOver())
{
board.setCurrentPlayerTurn(this.getSign()); // i think it keeps track of which player is holding the lock ?
Move move = generateRandomMove();
board.makeMove(this, move.getX(), move.getY() );
}
}
#Override
int getMyTurn() {
return 0;
}
#Override
public String getPlayerName() {
return name;
}
#Override
public void setPlayerName(String name) {
this.name = name;
}
#Override
void setSign(int sign) {
this.sign = sign ;
}
#Override
int getSign() {
return sign;
}
private Move generateRandomMove(){
while (true)
{
int x = getRandomNumber(0,board.getBoardSize()) ;
int y = getRandomNumber(0,board.getBoardSize()) ;
if (board.isPositionAvalabile(x, y ))
{
return new Move(x,y);
}
}
// todo implement the best move !
}
public int getRandomNumber(int min, int max) {
return (int) ((Math.random() * (max - min)) + min);
}
}
HumanPlayer.java
public class HumanPlayer extends Player {
private String name ;
private int sign ;
private Board board ;
public HumanPlayer(Board board) {
this.board = board;
}
#Override
public void run() {
while (!board.isGameOver())
{
board.setCurrentPlayerTurn(this.getSign()); // I think it keeps track of which player is holding the lock ?
Move move = requestMoveFormHuman(); // request move for human player // will be changed in the GUI?
board.makeMove(this, move.getX() , move.getY()); // check for move logic here >
}
}
#Override
int getSign() {
return sign;
}
#Override
int getMyTurn() {
return 0;
}
#Override
public String getPlayerName() {
return name;
}
#Override
public void setPlayerName(String name) {
this.name = name;
}
#Override
void setSign(int n) {
this.sign = n ;
}
// logic
private Move requestMoveFormHuman(){
int i=0 ;
while (true)
{
System.out.println(i);
Move move = requestMove() ;
int x = move.getX();
int y = move.getY();
if (board.isPositionAvalabile(x,y))
{
return new Move(x,y);
}
}
}
private Move requestMove() {
System.out.println("Player "+name+" turn:" );
System.out.println("Enter Row number: ");
int x = ScanInt();
System.out.println("Enter Coulmn number ");
int y = ScanInt();
return new Move(x ,y ) ;
}
private int ScanInt(){
Scanner scan = new Scanner(System.in);
// This method reads the number provided using keyboard
int num = scan.nextInt();
// Closing Scanner after the use
return num;
}
}
Main.java
public class Main {
public static void main(String[] args) {
Game game = new Game() ;
game.start();
}
}
Board.java
import java.util.HashMap;
import java.util.Scanner;
public class Board {
private int currentPlayerTurn = 0 ;
public int getBoardSize() {
return boardSize;
}
private int boardSize ;
private int[][] board_values ;
private boolean gameOver ;
private HashMap<String , String> result_history;
public Board(int boardSize) {
this.boardSize = boardSize;
board_values = new int[boardSize][boardSize];
for (int i = 0; i < boardSize; i++) {
for (int j = 0 ; j < boardSize; j++)
board_values[i][j] = 0 ;
}
System.out.println("");
}
private String getSign(int n) {
if (n==1)
return "X" ;
if (n==2)
return "0" ;
return " " ; // empty cell
}
public void printBoard(){
// todo change to ui components
for (int i = 0 ; i < boardSize ; i++)
{
for (int j = 0 ; j < boardSize ; j++)
{
System.out.print("|");
System.out.print(" " + getSign(board_values[i][j])+ " ");
System.out.print("|");
}
System.out.println("");
System.out.println("----------------------------------" );
}
}
/** is this the Synchronized one ? */
public boolean makeMove(Player player , int x , int y ) {
/*Update Board Value
insert 1 in the 2d board at x,y for player 1
insert 2 in the 2d board at x,y for player 2
*/
int sign = player.getSign();
updateBoard(x,y , sign ) ;
/*print Board*/
printBoard();
/* check for winner */
doWeHaveAwinner(x,y , sign);
return true ;
}
/*check the whole row (x) for if all signs are equals
, checks the whole column (x) for if all signs are equals
check diagonal if x=y */
private boolean doWeHaveAwinner(int x, int y, int sign) {
// TODO: 16/01/2022
return false ;
}
private void updateBoard(int x, int y , int sign ) {
board_values[x][y] = sign ;
}
public boolean isPositionAvalabile(int x , int y ){
return !(x>this.boardSize || x < 0 || y>this.boardSize || y < 0) ;
}
private void checkMove() {
// todo > ?
}
private void resetBoard(){
// todo set al values to 0
}
private void updateResultHistory(){
// TODO: 16/01/2022 update <Winner Name , Ps+1 >
}
private int ScanInt(){
Scanner scan = new Scanner(System.in);
System.out.print("Enter any number: ");
// This method reads the number provided using keyboard
int num = scan.nextInt();
// Closing Scanner after the use
return num;
}
/*Get Set*/
public synchronized boolean isGameOver() {
return gameOver;
}
public void setGameOver(boolean gameOver) {
this.gameOver = gameOver;
}
public int getCurrentPlayerTurn() {
return currentPlayerTurn;
}
public void setCurrentPlayerTurn(int currentPlayerTurn) {
this.currentPlayerTurn = currentPlayerTurn;
}
}
And here is Game.java, it basically inits 2 players.
Notice that in each player init I passed the board instance as a parameter.
It might a look little bit messy but I think passing the board instance for the players is the important thing here. Also I called the player1().start and player2.start()
Game.java
public class Game {
private Player player1 ;
private Player player2 ;
private Board board ;
private void initBoard(){
/* request board size */
int board_size = requestBoardSize();
board = new Board(board_size); // Synchronized class fields ?
}
private void initGameMode(){
/*
init the players objects as follows
1 - for human-machine game
2 - for machine-human game, and
3 - for human-human game
*/
System.out.println(Utils.str_gameType);
Scanner scanner = new Scanner( System.in);
int game_mode = scanner.nextInt( );
switch (game_mode) {
case 1:
/* init game type1 human-machine Game*/
player1 = new HumanPlayer(board);
player2 = new MachinePlayer(board);
break;
case 2:
player1 = new MachinePlayer(board);
player2 = new HumanPlayer(board);
break;
case 3:
player1 = new HumanPlayer(board);
player2 = new HumanPlayer(board);
break;
default:
throw new IllegalStateException("Unexpected value: " + game_mode);
}
player1.setSign(1);
player2.setSign(2);
System.out.println("");
}
private void initPlayersName(){
/*request name player 1 */
System.out.println(Utils.str_player1Name); /*Scan first name*/
Scanner scan1 = new Scanner(System.in);
String name1 = scan1.next();
player1.setPlayerName(name1);
/*request name player 2 */
System.out.println(Utils.str_player2Name); /*Scan first name*/
Scanner scan2 = new Scanner(System.in);
String name2 = scan2.next();
player2.setPlayerName(name2);
}
public Game() {
System.out.println(Utils.str_start_game);
initBoard();
initGameMode();
initPlayersName();
}
public void start() {
// todo change who starts first
player1.start();
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(300);
player2.start();
}catch (Exception e)
{
}
}
}).start();
}
private int requestBoardSize() {
System.out.println(Utils.str_request_board_size);
Scanner scanner = new Scanner(System.in) ;
int i = scanner.nextInt() ;
return i ;
}
}///End of Class

How can I distinguish a winner in this thread race?

I have been writing a race code for a class I am in that races two threads, a tortoise and a hare. I can get both of them to run for 80 units but I don't know how to write a code that determines and outputs who the winner is. Any help would be appreciated because I am super new to coding.
I have the tortoise, hare, and raceParticipant classes. My driver class looks like this, where I would assume I put the winner code?
package Domain;
public class Driver
{
public static void main(String[] args)
{
Hare bob = new Hare();
Tortoise fred = new Tortoise();
int winDistance = 80;
do {
bob.sprint();
fred.sprint();
bob.display();
fred.display();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
}
}
My sprint method is
public int sprint()
{
int sleep = generator.nextInt(100);
int sprintDistance = 0;
if (sleep > sleepPercent)
{
sprintDistance = generator.nextInt(topSpeed) + 1;
}
totalDistance +=sprintDistance;
return sprintDistance;
}
I don't see you creating a new thread anywhere.
You can create a Hare class like this:
public class Hare implements Runnable {
private static final int SLEEP_DURATION = 3000; //milliseconds
private static final int SPEED = 3; //units per second
private int distanceToRun;
private final RaceFinishListener listener;
public Hare(int distanceToRun, RaceFinishListener listener) {
this.distanceToRun = distanceToRun;
this.listener = listener;
}
#Override
public void run() {
do {
distanceToRun -= SPEED;
try {
Thread.sleep(SLEEP_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (distanceToRun > 0);
listener.onRaceFinished(getClass().getSimpleName());
}
}
and a similar Tortoise class with these variables:
private static final int SLEEP_DURATION = 1000; //sleeps less
private static final int SPEED = 1; //but is slow
Then create a listener to get notified when someone has finished:
public interface RaceFinishListener {
void onRaceFinished(String finisher);
}
and finally your main class:
public class Test implements RaceFinishListener {
private String winner;
private static final int DISTANCE_TO_RUN = 10;
public static void main(String[] args) {
new Test().race();
}
private void race() {
Hare bob = new Hare(DISTANCE_TO_RUN, this);
Tortoise fred = new Tortoise(DISTANCE_TO_RUN, this);
new Thread(bob).start();
new Thread(fred).start();
}
#Override
public void onRaceFinished(String finisher) {
synchronized (this) {
if (winner == null) {
winner = finisher;
System.out.println(finisher + " is the winner!");
} else {
System.out.println(finisher + " lost.");
}
}
}
}
Output
Tortoise is the winner!
Hare lost.
After this line:
}while(bob.getTotalDistance() < winDistance && fred.getTotalDistance() < winDistance);
You would just have:
boolean bobWins = (bob.getTotalDistance() >= winDistance);
boolean fredWins = (fred.getTotalDistance() >= winDistance);
if (bobWins && fredWins) {
System.out.println("It's a tie");
}
else if (bobWins) {
System.out.println("Bob Wins");
}
else {
System.out.println("Fred Wins");
}

arithmetic expression Math.random in java

the purpose of this program is to let the user try to guess a number up to 20 randomly chosen by the computer. The user inputs their guess. The computer then tells the user if their guess is too high or too low. The user keeps inputting their guess until theu guess correctly. Then they are told how many guesses it took them. The problem is that I am not understanding whether the arithmetic expression in the program generates random numbers from 1 to 20 because when I am inputting numbers from 1 to 20, the pop-up says 'number is too big'.
package pkTopic6Exercise13;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Font;
public class Topic6Exercise13
{
private GuessingGame MyGuessingGame = new GuessingGame();
private Topic6Exercise13()
{//constructor
}
public static void main(String[] args)
{
Topic6Exercise13 myTopic6Exercise13 = new Topic6Exercise13();
myTopic6Exercise13.go();
}
private void go()
{
T6Ex13GUIin myT6Ex13GUIin = new T6Ex13GUIin();
}
private class GuessingGame
{
private int NumToGuess=0;
private int Guess=0;
private int NumGuesses=0;
private GuessingGame()
{//constructor
}
private void GenerateNum()
{
NumToGuess = 1+(int)(20*Math.random());
}
private String CheckNum()
{
NumGuesses = NumGuesses + 1;
if (Guess > NumToGuess)
{
JOptionPane.showMessageDialog(null, Guess + " is too BIG!");
return "NotGuessed";
}
else if (Guess < NumToGuess)
{
JOptionPane.showMessageDialog(null, Guess + " is too SMALL!");
return "NotGuessed";
}
else
{
JOptionPane.showMessageDialog(null, "Well done! " + Guess +" is correct, it took " + NumGuesses + " goes.");
return "Guessed";
}
}
}
private class T6Ex13GUIin extends JFrame
{
private JLabel lblGuess;
private JTextField txfGuess;
private JButton btnPickNumber;
private JButton btnQuit;
private T6Ex13GUIin()
{//constructor
Font fontDialog = new Font("Dialog", Font.BOLD,24);
this.setSize(1000,500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(100,0);
this.setTitle("Guessing Game");
this.setLayout(null);
lblGuess = new JLabel("Type Guess:");
lblGuess.setFont(fontDialog);
lblGuess.setBounds(100,200,200,50);
lblGuess.setVisible(false);
this.add(lblGuess);
txfGuess = new JTextField("");
txfGuess.setBounds(300,200,100,50);
txfGuess.setFont(fontDialog);
txfGuess.setVisible(false);
ReturnListener MyReturnListener = new ReturnListener();
txfGuess.addKeyListener(MyReturnListener);
this.add(txfGuess);
ClickListener MyClickListener = new ClickListener();
btnPickNumber = new JButton("Pick Number");
btnPickNumber.setBounds(100,100,750,50);
btnPickNumber.setFont(fontDialog);
btnPickNumber.addActionListener(MyClickListener);
this.add(btnPickNumber);
btnQuit = new JButton("Quit");
btnQuit.setBounds(750,300,100,50);
btnQuit.setFont(fontDialog);
btnQuit.addActionListener(MyClickListener);
this.add(btnQuit);
this.setVisible(true);
}
private class ClickListener implements ActionListener
{
private ClickListener()
{//constructor
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == btnPickNumber)
{
MyGuessingGame.GenerateNum();
MyGuessingGame.NumGuesses=0;
btnPickNumber.setVisible(false);
lblGuess.setVisible(true);
txfGuess.setVisible(true);
txfGuess.setText("");
}
if (e.getSource() == btnQuit)
{
System.exit(0);
}
}
}
private class ReturnListener implements KeyListener
{
private ReturnListener()
{//constructor
}
public void keyPressed(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
if (e.getKeyChar() == '\n')
{
MyGuessingGame.Guess =
Integer.parseInt(txfGuess.getText());
if (MyGuessingGame.CheckNum().equals("Guessed"))
{
lblGuess.setVisible(false);
txfGuess.setVisible(false);
btnPickNumber.setVisible(true);
}
else
{
txfGuess.setText("");
}
}
}
}
}
}
Have you tried any testing? Like, debugging and seeing what value is getting set for NumToGuess? Or perhaps simply displaying the value being set? Then if you know what the random number is, you can test out your logic.
Based on your core logic, I ran this simple code below and didn't experience any problems.
public static void main(String[] args) {
int NumToGuess = 1+(int)(20*Math.random());
int myGuess = Integer.parseInt("10");
System.out.println("Value is: " + NumToGuess);
System.out.println("My Guess: " + myGuess);
if (myGuess > NumToGuess) {
System.out.println("Too Big");
}
else if (myGuess < NumToGuess) {
System.out.println("Too Small");
}
}
Math.rand() generates a random number between 0 and 1 exclusive. So by multiplying by 20 you get a value between 0 and 20 exclusive. By rounding down with the (int) cast it becomes between 0-19 inclusive and by adding one it becomes between 1-20 inclusive. So yes, your number is being generated correctly. However, you do add 1 again at the beginning of the checkNum() method so that could be a problem. Hope this helps.

Categories