How do I run a (pseudo)main method with an applet? - java

I'm a beginner/intermediate java programmer that is attempting to code something that is "out-of-my-league". The program is supposed to judge a boxing/MMA match in real time by pressing keys that correspond to different scoring values. I've figured out that I need a KeyListener, and the only way I've found to use that is with an applet.
The problem I've run into is the only cues I have to print out a score come from keyPresses and keyReleases. I want the score to print EVERY second, along with the time. I'm made a clock function and can print every second using another class with a main method, but I don't know how to do this in the applet.
Here's what I have so far:
import java.applet.Applet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.*;
public class KeyPressTwo
extends Applet
implements KeyListener{
private long t;
private ArrayList<Integer> keysDown = new ArrayList<Integer>();
private double controlOnlyValue = 1; //Stores the score per second for control only
private double threateningValue = 2.5; //Score for threatening with strikes, i.e. landing sig strikes, or sub attempts
private double damagingValue = 4; //Score for doing significant damage and dominating hea
private static double redTotal = 0; //Stores fighter score
private static double blueTotal = 0;
private static boolean firstRun = true;
private static boolean start = false;
private static boolean releasePressed = false; //Tells KeysReleased method when to wipe keysDown list
private static long roundBeganAt = 0; //System time when the round began 5
private static String redName;
private static String blueName;
public void init(){
this.addKeyListener(this);
//If names aren't hardcoded in, get them when the program is run
if (redName == null){
redName = JOptionPane.showInputDialog("Enter the red corner fighter's name.");
blueName = JOptionPane.showInputDialog("Enter the blue corner fighter's name.");
}
}
public void paint(){
setSize(500,500);
}
#Override
public void keyPressed(KeyEvent e) {
if(!keysDown.contains(e.getKeyCode()))
keysDown.add(e.getKeyCode());
//Starts the timer, don't print anything until started
if(keysDown.contains(KeyEvent.VK_SPACE)){
start = true;
roundBeganAt = System.currentTimeMillis();
}
//If it's been more than 1s
if(nextStep()){
//If space has been pushed
if(start){
if(keysDown.contains(KeyEvent.VK_Z) || keysDown.contains(KeyEvent.VK_NUMPAD1)){
redTotal += controlOnlyValue;
}
if(keysDown.contains(KeyEvent.VK_X) || keysDown.contains(KeyEvent.VK_NUMPAD4)){
redTotal += threateningValue;
}
if(keysDown.contains(KeyEvent.VK_C) || keysDown.contains(KeyEvent.VK_NUMPAD7)){
redTotal += damagingValue;
}
if(keysDown.contains(KeyEvent.VK_COMMA) || keysDown.contains(KeyEvent.VK_NUMPAD3)){
blueTotal += controlOnlyValue;
}
if(keysDown.contains(KeyEvent.VK_M) || keysDown.contains(KeyEvent.VK_NUMPAD6)){
blueTotal += threateningValue;
}
if(keysDown.contains(KeyEvent.VK_N) || keysDown.contains(KeyEvent.VK_NUMPAD9)){
blueTotal += damagingValue;
}
System.out.print("\n" +redName +": " +redTotal +" \t" +blueName +": " +blueTotal +"\t\t" +time());
releasePressed = true;
}
}
}
//Prints time since start (e.g. 2:05)
private static String time() {
String minutes = "";
String seconds = "";
int sRaw; //Gets time directly from system, will go above 60
int s; //Gets time from sRaw, (0 - 59)
sRaw = (int)((System.currentTimeMillis() - roundBeganAt))/1000;
s = sRaw%60;
minutes = Integer.toString(sRaw/60);
if(s < 10)
seconds = "0" +Integer.toString(s);
else seconds = Integer.toString(s);
return minutes +":" +seconds;
}
//Returns true if it's been more than1s since the last time it ran
public boolean nextStep() {
if(firstRun){
t = System.currentTimeMillis();
firstRun = false;
return true;
}
if(System.currentTimeMillis() > t + 1000){
t = System.currentTimeMillis();
return true;
}else
return false;
}
public void printList(){
for(int i : keysDown)
System.out.print(i +" ");
System.out.println();
}
#Override
public void keyReleased(KeyEvent e) {
if(releasePressed){
keysDown.clear();
releasePressed = false;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
}

Maybe something along these lines would work for you:
Thread timerOutputThread = new Thread(new Runnable(){
public boolean running = true;
public void run(){
output();
}
private void output(){
try {
Thread.sleep(1000);
} catch(Exception ex) {
ex.printStackTrace();
}
System.out.println("PRINT THE SCORE HERE");
if(running){
output();
}
}
});
timerOutputThread.start();
Stick that code wherever you want the Thread timer to be started, and then fill in that spot where it says "PRINT THE SCORE HERE".

I've figured out that I need a KeyListener,.."
Or preferably key bindings.
..and the only way I've found to use that is with an applet.
Where on Earth did you hear that?!? It is definitely wrong. Start using a JFrame for this app. and it will work better because focus will be more reliable.

Related

Problem with Class scope, how should I resolve this?

I started my first java project and I get stuck in class scope. I cant initiate below code:
if (guessAttemts = MaxGuesses) {
System.out.println("Sorry you used all your nine chances. Game Over.)
I will be appreciate if someone will help me to clarify what I doing wrong with that code: This NewGame class look like below.
class NewGame {
GuessAttempts GuessAttempts = new GuessAttempts();
private String WordToGuess;
private String CorrectGuesses;
private String misses;
int guessAttempts;
int MAX_Guesses = 9;
public NewGame(String WordToGuess) {
this.WordToGuess = WordToGuess;
CorrectGuesses = "";
misses = "";
guessAttempts = 0;
}
public boolean UserGuessing(char letter) {
boolean isHit = WordToGuess.indexOf(letter) != -1;
if (isHit) {
CorrectGuesses += letter;
} else {
misses += letter;
}
guessAttempts =+ 1;
return isHit;
}
if (guessAttemts = MaxGuesses) {
System.out.println("Sorry you used all your nine chances. Game Over.");
}
}
To compare to values, you should use ==.
That means that your if-statement should look so:
if (guessAttemts == MaxGuesses) {
System.out.println("Sorry you used all your nine chances. Game Over.");
}

For Loop to score bowling

I'm working on a project for a potential internship to take a String input of bowling scores and add them up to a final score. I'm having difficult passing one of my tests and was wondering if you could help me figure out my fault.
The test that is not working is isNinetySix and it is giving me a result of 98 instead. Please help!
public class Game {
private int roll = 0;
private int[] rolls = new int[21];
public void rolls(String scoreCard) {
for (int i=0; i< scoreCard.length(); i++) {
if (scoreCard.charAt(i) == 'X') {
rolls[roll++] = 10;
} else if (scoreCard.charAt(i) == '/') {
rolls[roll++] = 10;
} else if (scoreCard.charAt(i) == '-') {
} else {
int x = scoreCard.charAt(i);
rolls[roll++] = x - '0';
}
}
}
public int score() {
int score = 0;
int cursor = 0;
for (int frame = 0; frame < 10; frame++) {
if (isStrike(cursor)) {
score += 10 + rolls[cursor+1] + rolls[cursor+2];
cursor ++;
} else if (isSpare(cursor)) {
score += 10 + rolls[cursor+2];
cursor += 2;
} else {
score += rolls[cursor] + rolls[cursor+1];
cursor += 2;
}
}
return score;
}
private boolean isStrike(int cursor) {
return rolls[cursor] == 10;
}
private boolean isSpare(int cursor) {
return rolls[cursor] + rolls[cursor+1] == 10;
}
//Print scores for each frame
public void printFrameScore(int[] frame) {
for (int i = 1; i < frame.length; i++) {
System.out.println(i + ": " + frame[i]);
}
}
public void displayRolls() {
for (int i = 0; i < rolls.length; i++) {
System.out.print(rolls[i] + ", ");
}
}
}
Tests
import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.is;
import org.junit.Before;
import org.junit.Test;
public class GameTest {
private Game game;
#Before
public void setUp(){
game = new Game();
}
#Test
public void isPerfect() {
game.rolls("X-X-X-X-X-X-X-X-X-X-XX");
assertThat(game.score(), is(300));
}
#Test
public void isGutter() {
game.rolls("00-00-00-00-00-00-00-00-00-00");
assertThat(game.score(), is(0));
}
#Test
public void isNinety() {
game.rolls("45-54-36-27-09-63-81-18-90-72");
assertThat(game.score(), is(90));
}
#Test
public void isOneFifty(){
game.rolls("5/-5/-5/-5/-5/-5/-5/-5/-5/-5/-5");
assertThat(game.score(), is(150));
}
#Test
public void isNinetySix() {
game.rolls("45-54-36-27-09-63-81-18-90-7/-5");
assertThat(game.score(), is(96));
}
}
The problem here seems to be that your isSpare() function never returns true because you assigned each / a value of 10. The result of the addition of the two rolls in a frame with a spare was more than 10. If I were you I would try to clean up the assignment of / to actually be 10 - prev_role_score. This would be cleaner than making isSpare() check for greater than 10. There are other ways to clean up the code to, you could try to refactor some to impress whoever you submit to.
} else if (scoreCard.charAt(i) == '/') {
int diff = 10 - rolls[roll - 1];
rolls[roll++] = diff;
}
Your code is failing in the below block (after your 9th frame, you're at a score of 81). You're code is looking at the index that contains the value 7 and the / which you represent as 10, thereby giving you 17 rather than 10 for the spare.
...
} else {
score += rolls[cursor] + rolls[cursor+1];
cursor += 2;
}
...
So, if I were making suggestions, and I'm not sure what the expectations are for your project, I would tell you to think about easier ways to traverse your string by splitting, searching, then adding. Below is a quick example:
public void rolls(String scorecard) {
String [] framesets = scorecard.split("-");
//hunt for special cases like spare and strikes
//do work to hold your scores
}

For Loop error as method

I am trying to write a code that changes a value by either -1 or +1 depending on a random chance. It is basically a person moving through blocks. He starts from 6 and if he ends up in 1 he wins but if he ends up in 11 he loses. The final output would look something like this:
Here we go again... time for a walk!
Walked 37 blocks, and
Landed at Home
Here we go again... time for a walk!
Walked 19 blocks, and
Landed in JAIL
Here we go again... time for a walk!
Walked 13 blocks, and
Landed in JAIL
Here we go again... time for a walk!
Walked 25 blocks, and
Landed in JAIL
I have written the following code:
public class Drunk {
public int street;
public double move;
public int i;
public boolean jail;
public static void drunkWalk() {
do {
street = 6;
move = Math.random();
i++;
if (move > 0.5) {
street++;
} else {
street--;
}
} while (street != 1 && street != 11);
if ( street == 1) {
jail = false;
} else {
jail = true;
}
for (; ; ) { --- } //This is the problem. It treats it as a method.
//How can I fix this?
}
}
How about somethink like:
public static void main(String args[])
{
Drunk drunk = new Drunk();
while (true)
{
DrunkResult result = drunk.drunkWalkToJail();
System.out.println("Walked " + result.getSteps() + " blocks, and Landed at " + (result.isInJail() ? "Jail":"Home"));
}
}
public DrunkResult drunkWalkToJail()
{
int street;
int stepCount = 0;
do
{
street = 6;
double move = Math.random();
stepCount++;
if (move > 0.5)
{
street++;
}
else
{
street--;
}
}
while (street != 1 && street != 11);
return new DrunkResult(street == 11, stepCount);
}
and
public class DrunkResult
{
boolean jail = false;
int stepCount = 0;
public DrunkResult(boolean jail, int stepCount)
{
this.jail = jail;
this.stepCount = stepCount;
}
public boolean isInJail()
{
return jail;
}
public int getSteps()
{
return stepCount;
}
}
You can do walks in parallel (a group of drunk people) and process the results independent.

Adding data to a program if exist; else do generate random data in java

I have a math program that shows random math problems, when you click to see the next answer the next answer appears.
I have added a method which uploads a file called upload.txt
I want my program to run the math problems in this file instead of running the random
math problems if the file exist. If not I want the program to run the current way which is running the random math problems.
My current method for adding the text file is not 100 percent accurate.
I wont to just take the problems written in the file to be added. I got it working just uploading numbers to the command prompt by using code from another thread on StackOverflow.
random math problems class
import java.util.Random;
public class MathProblems {
private static final int MAX_NUMBER = 1000;
private static final Random random = new Random();
private double expected = 0;
private String question = "";
public void run() {
final int a = random.nextInt(MAX_NUMBER);
final int b = random.nextInt(MAX_NUMBER);
final int type = random.nextInt(4);
switch (type) {
case 0:
add(a, b);
break;
case 1:
subtract(a, b);
break;
case 2:
multiply(a, b);
break;
case 3:
divide(a, b);
break;
}
}
private void add(final int a, final int b) {
expected = a + b;
askQuestion(a + " + " + b + " = ");
}
private void subtract(final int a, final int b) {
expected = a - b;
askQuestion(a + " - " + b + " = ");
}
private void multiply(final int a, final int b) {
expected = a * b;
askQuestion(a + " * " + b + " = ");
}
private void divide(final int a, final int b) {
expected = (double)a / b;
askQuestion(a + " / " + b + " = ");
}
private void askQuestion(final String question) {
this.question = question;
}
public String getQuestion() {
return question;
}
#Override
public String toString(){
return Double.toString(expected);
}
}
Driver Class
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
import javax.swing.*;
public class Driver extends MathProblems {
MathProblems problems = new MathProblems();
Scanner textfile;
String s = "Welcome Students!";
String b = "Start!";
private JFrame f;
private JPanel p;
JFrame frame = new JFrame();
JButton b1 = new JButton(b);
JLabel jl = new JLabel(s);
int i;
private int clicked;
public Driver() {
gui();
}
public void gui() {
f = new JFrame("Flash Card Program");
p = new JPanel();
f.setLayout(new GridLayout(2, 1));
f.add(jl);
f.add(p);
p.setLayout(new GridLayout(2, 1));
p.add(b1);
jl.setHorizontalAlignment(JLabel.CENTER);
// pack the frame for better cross platform support
f.pack();
// Make it visible
f.setVisible(true);
f.setSize(500, 400); // default size is 0,0
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (b1.getText().equals("Click For Answer")) {
jl.setText(problems.toString());
b = "Next Question";
b1.setText(b);
} else {
problems.run();
jl.setText(problems.getQuestion());
b = "Click For Answer";
b1.setText(b);
}
}
});
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (clicked++ == 10) {
Object[] options = { "No, thanks", "Yes, please" };
int response = JOptionPane.showOptionDialog(frame,
"Would you like more math questions? ",
"Math Questions", JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE, null, options,
options[1]);
if (response == 1)
clicked = 0; // reset
else
System.exit(0);
}
}
});
}
static void filereader(Scanner textfile) {
int i = 0;
int sum = 0;
while(i <= 19)
{
int nextInt = textfile.nextInt();
System.out.println(nextInt);
sum = sum + nextInt;
i++;
}
}
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Driver();
Scanner textfile = null;
try {
textfile = new Scanner(new File("upload.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
filereader(textfile);
}
});
}
}
.txt file
1 + 1
2 + 2
3 + 3
4 + 4
5 + 5
6 + 6
7 + 7
8 + 8
9 + 9
10 + 10
You need to define a global vector of question values for each of a and b. A nicer way to do this is to define a class called "OneProblem" which has members for a, b, and op. You create a single 'Vector<OneProblem>' and as you read the file you create a OneProblem object for each line of the source. Then, at run time you either pick a random math problem, or loop through all the OneProblem objects, or you generate a completely random OneProblem from the random number generator. Something like:
class OneProblem {
public int a = 0;
public int b = 0;
public int op = 0;
public OneProblem(int _a, int _op, int _b) {
a =_a;
b = _b;
op = _op;
}
}
class MathProblems {
Vector<OneProblem> problems = new Vector<OneProblem>();
//...lot of your other code here as well....
workQuestion(OneProblem problem) {
switch (problem.op) {
case 0:
add(problem.a, problem.b);
break;
case 1:
subtract(problem.a, problem.b);
break;
case 2:
multiply(problem.a, problem.b);
break;
case 3:
divide(problem.a, problem.b);
break;
}
}
}
You file reader needs to read each line and parse the first and second values out of the line, as well as (I presume) the operand between them. Read the line, and search for the operand, and separate the integer before and the integer after. Then as you read each line, construct an instance of OneProblem to match each line. Now you are set to run.
When presenting the math questions, you loop through the values from i=0 to i<problems.size(). If there was no file read, those vectors will have no entries and so it will fall through. After you finish the vectors, or if the vectors are empty, present math questions with random values.
if (problems.size()>0) {
for (int i=0; i<problems.size(); i++) {
OneProblem selProblem = problems.get(i);
workQuestion(selProblem);
}
}
else {
workQuestion(new OneProblem({{random a}}, {{random op}}, {{random b}}));
}
Fill in the appropriate method for 'askQuestion'. This is represented above as a loop, but maybe you want to pick a random one of the test values for presentation? Then pick a reasonable random value for i in that range, and get the problem out of the vectors.
In your filereader method, you have this line, in a loop:
int nextInt = textfile.nextInt();
But the sample text that you show contains '+' characters between your numbers, and I see no code present to take that into account.
To fix, you can either define '+' as a delimiter on your Scanner object, or make sure your loop reads it as a string.

How to get input without pressing enter every time?

I made a simple game(well not really a game yet) in which the player can move in a room 4x20 characters in size. It runs in console.
But in my game loop I want to be able to move around in the room without pressing enter every time I want to move. The player should be able to press w/a/s/d and have the screen update instantly, but I don't know how to do that.
public class Main{
public static void main(String[] args){
MovementLoop();
}
public static void MovementLoop(){
Scanner input = new Scanner(System.in);
int pos=10, linepos=2;
String keypressed;
boolean playing = true;
while(playing == true){
display dObj = new display(linepos, pos);
dObj.drawImage();
keypressed=input.nextLine();
if(keypressed.equals("w")){
linepos -= 1;
}
else if(keypressed.equals("s")){
linepos += 1;
}
else if(keypressed.equals("a")){
pos -= 1;
}
else if(keypressed.equals("d")){
pos += 1;
}
else if(keypressed.equals("q")){
System.out.println("You have quit the game.");
playing = false;
}
else{
System.out.println("\nplease use w a s d\n");
}
}
}
}
public class display{
private String lines[][] = new String[4][20];
private String hWalls = "+--------------------+";
private String vWalls = "|";
private int linepos, pos;
public display(int linepos1, int pos1){
pos = pos1 - 1;
linepos = linepos1 - 1;
}
public void drawImage(){
for(int x1=0;x1<lines.length;x1++){
for(int x2=0;x2<lines[x1].length;x2++){
lines[x1][x2]="#";
}
}
lines[linepos][pos]="O";
System.out.println(hWalls);
for(int x2=0;x2<lines.length;x2++){
System.out.print(vWalls);
for(int x3=0;x3<lines[x2].length;x3++){
System.out.print(lines[x2][x3]);
}
System.out.println(vWalls);
}
System.out.println(hWalls);
}
}
The answer is simple
You can't do that
Because command line environment is different from swing, as swing can do such a thing as it deals with events and object, whereas, command line have no events.
So, maybe it's a right time to leave command line.

Categories