GUI Calculator with no number buttons - java

Hello I have this calculator and I want it to be buttonless like make the user input in the textfield but I don't know how to make it work like that. I want to simplify it like this but I don't know how to make it work without the number buttons.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class MP2_2 extends JFrame implements ActionListener {
Container c;
JTextField result;
JPanel p = new JPanel();
JButton b[] = new JButton[16];
String s[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "-", "/", "*", "=", "C"};
//----------------------Me------------------------
String Screen = "", monitor1 = "", monitor2 = "", OperationOnScreen = "";
boolean CommandEmpty = true, switcher = true;
double R = Integer.MIN_VALUE, L = Integer.MIN_VALUE;
//------------------------------------------------
public MP2_2() {
super("MP2_2");
c = getContentPane();
result = new JTextField();
result.setEditable(true);
p.setLayout(new GridLayout(4, 4));
for (int i = 0; i < 16; i++) {
b[i] = new JButton(s[i]);
b[i].addActionListener(this);
p.add(b[i]);
}
c.add(result, BorderLayout.NORTH);
c.add(p);
}//End Constructor
public static void main(String[] args) {
MP2_2 calcu = new MP2_2();
calcu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
calcu.setSize(300, 300);
calcu.setVisible(true);
}
//------------------------------------------------
public void actionPerformed(ActionEvent event) {
for (int i = 0; i <= 9; i++)//Numbers
{
if (event.getSource() == b[i]) {
Screen += i;
result.setText("");
result.setText(Screen);
}
}
for (int i = 10; i <= 14; i++)//Commands
{
if (event.getSource() == b[i]) {
if (result.getText().lastIndexOf(OperationOnScreen) != -1)//prevent exception
{
result.setText(result.getText().substring(0, result.getText().lastIndexOf(OperationOnScreen)) + s[i]);
} else {
result.setText(result.getText() + s[i]);
}
OperationOnScreen = s[i];
if (switcher) {
monitor1 = s[i];
switcher = false;
} else {
monitor2 = s[i];
switcher = true;
}
if (monitor1 != monitor2 && monitor2 != "") {
if (switcher) //execute older,send sign newer
{
Calc(event, monitor1.charAt(0), monitor2);
} else {
Calc(event, monitor2.charAt(0), monitor1);
}
}
if (s[i] != "=") //calc returns 0
{
Calc(event, s[i].charAt(0), s[i]);
}
}
}
if (event.getSource() == b[15]) //Clear
{
Screen = "";
monitor1 = "";
monitor2 = "";
switcher = true;
CommandEmpty = true;
result.setText("");
}
}//end actionPerformed
public void Calc(ActionEvent event, char OpType, String Operator) {
if (Operator == "=") {
Operator = "";
}
if (CommandEmpty && Screen == "") {
return;
} else if (CommandEmpty && Screen != "") {
R = Integer.parseInt(Screen);
result.setText(Screen + Operator);
Screen = "";
CommandEmpty = false;
} else if (!CommandEmpty && Screen != "") {
L = Integer.parseInt(Screen);
R = Operations(R, L, OpType);//calculate
Screen = "";
result.setText("");
result.setText(R + Operator);
}
}//End Calc
public static double Operations(double R, double L, char op) {
switch (op) {
case '+':
return R + L;
case '-':
return R - L;
case '*':
return R * L;
case '/':
return R / L;
}
return 0;
}
}//end class
EDIT: I guess my question wasn't clear sorry. I wanted my program to support inputs from the keyboard also, How do I do this? So I can finally delete the number buttons like in the picture.

When you remove the buttons, you'll need to restore the action of the buttons with a call to result.getText().
Here is the code that works on your number buttons. It sets the value of Screen.
for (int i = 0; i <= 9; i++)//Numbers
{
if (event.getSource() == b[i]) {
Screen += i;
result.setText("");
result.setText(Screen);
}
}
Therefore, when you hit your operation buttons, you will need to set Screen.
Here is your loop for Commands. I added Screen = result.getText(); in the else block. It worked for me.
for (int i = 10; i <= 14; i++)//Commands
{
if (event.getSource() == b[i]) {
if (result.getText().lastIndexOf(OperationOnScreen) != -1)//prevent exception
{
result.setText(result.getText().substring(0, result.getText().lastIndexOf(OperationOnScreen)) + s[i]);
} else {
Screen = result.getText();
result.setText(result.getText() + s[i]);
}

Related

Memory game not revealing correct guesses

This program is a Domino memory game where you flip dominos until you make a correct guess where the correct dominos are supposed to stay revealed. However the problem is that while the game does work correctly the dominos do not stay revealed nor does the game end.
This is the code for my Domino Class
`
public class Domino {
private int top, bottom;
private boolean revealed;
public Domino(int x, int y) {
if (x > y) {
top = y;
bottom = x;
} else {
top = x;
bottom = y;
}
}
public int getTop() {
return top;
}
public int getBottom() {
return bottom;
}
public boolean isRevealed() {
if (revealed)
return true;
return false;
}
public void setRevealed(boolean revealed) {
this.revealed = revealed;
}
public boolean equals(Domino other) {
if (top == bottom)
return true;
return false;
}
}
`
Then here is the memory game class (called MemoryLane)
`
import java.util.Arrays;
import java.util.Random;
public class MemoryLane
{
private Domino[] board;
public MemoryLane(int max)
{
board = new Domino[(max * max) + max];
int i = 0;
for(int top = 1; top <= max; top++)
for(int bot = 1; bot <= max; bot++)
{
// make new Domino(2x) +
// save into array
if(top <= bot)
{
board[i] = new Domino(top, bot);
i++;
board[i] = new Domino(top, bot);
i++;
}
}
shuffle();
}
private void shuffle()
{
int index;
Random random = new Random();
for (int i = board.length - 1; i > 0; i--)
{
index = random.nextInt(i + 1);
if (index != i)
{
Domino temp = board[index];
board[index] = board[i];
board[i] = temp;
}
}
}
public boolean guess(int i, int k)
{
if(board[i] == board[k])
{
return true;
}
return false;
}
public String peek(int a, int b)
{
String text = new String();
text += ("[" + board[a].getTop()+ "] [" + board[b].getTop()+ "]\n");
text += ("[" + board[a].getBottom()+ "] [" + board[b].getBottom()+ "]\n");
return text;
}
public boolean gameOver() {
int count = 0;
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
count ++;
}
return (count == board.length);
}
public String toString() {
String text = new String();
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
text += ("[" + board[i].getTop()+ "] ");
else
text += ("[ ] ");
}
text += ('\n');
for(int i=0; i< board.length; i++)
{
if(board[i].isRevealed())
text += ("[" + board[i].getBottom()+ "] ");
else
text += ("[ ] ");
}
return text;
}
}
`
Then here is the driver (the driver was provided to me by a third party so it must work as it is presented and cannot be changed)
`
import java.util.Scanner;
public class MemoryLaneDriver
{
public static void main(String[] args)
{
String message = "Welcome to Memory Lane!" + "\n" +
"Choose two indexes to reveal the corresponding dominoes." + "\n" +
"If the dominoes match, they stay revealed." + "\n" +
"Reveal all the dominoes to win the game!" + "\n";
System.out.println(message);
Scanner input = new Scanner(System.in);
MemoryLane game = new MemoryLane(2);
long start = System.currentTimeMillis();
while(!game.gameOver())
{
System.out.println(game);
System.out.print("First: ");
int first = input.nextInt();
System.out.print("Second: ");
int second = input.nextInt();
game.guess(first, second);
System.out.println(game.peek(first, second) + "\n");
}
long stop = System.currentTimeMillis();
long elapsed = (stop - start) / 1000;
System.out.println(game);
System.out.println("\nYou win!");
System.out.println("Total time: " + elapsed + "s");
}
}
`
I have tried using the methods in Domino like setRevealed and isRevealed in the guess method (for example when i try board.setRevealed = true or board.isRevealed = true), but it wont work and turns up red in IntelliJ. I can also not use any Stringbuilder uses (such as append) because it is outside of what has been covered in class.
When I say the game is working correctly, I mean that it outputs my choices like:
`
Welcome to Memory Lane!
Choose two indexes to reveal the corresponding dominoes.
If the dominoes match, they stay revealed.
Reveal all the dominoes to win the game!
[ ] [ ] [ ] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ]
First: 1
Second: 3
[2] [2]
[2] [2]
[ ] [ ] [ ] [ ] [ ] [ ]
[ ] [ ] [ ] [ ] [ ] [ ]
First:
`
However as you can see it is not revealing the correct guess, and even if I guess all of the Dominos correctly the game does not end.
So, in your original code, you were using board[i] == board[k] which is comparing memory address locations and not the object properties, instead, you should be using board[i].equals(board[k]).
In this case you need to override equals method of the Domino class in order to change how the comparison works, for example...
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.getTop();
hash = 59 * hash + this.getBottom();
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Domino)) {
return false;
}
final Domino other = (Domino) obj;
if (this.getTop() != other.getTop()) {
return false;
}
if (this.getBottom() != other.getBottom()) {
return false;
}
return true;
}
It's important to remember, if you override equals you should also override hashCode as they have an important relationship to each other.
You also never call setRevealed, which I guess should be done in guess
public boolean guess(int i, int k) {
if (board[i].equals(board[k])) {
board[i].setRevealed(true);
board[k].setRevealed(true);
return true;
}
return false;
}
Runnable example...
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
new Main();
}
Main() {
String message = "Welcome to Memory Lane!" + "\n"
+ "Choose two indexes to reveal the corresponding dominoes." + "\n"
+ "If the dominoes match, they stay revealed." + "\n"
+ "Reveal all the dominoes to win the game!" + "\n";
System.out.println(message);
Scanner input = new Scanner(System.in);
MemoryLane game = new MemoryLane(2);
long start = System.currentTimeMillis();
while (!game.gameOver()) {
// This is just making it easier to cheat.
System.out.println(game.debug());
System.out.println(game);
System.out.print("First: ");
int first = input.nextInt();
System.out.print("Second: ");
int second = input.nextInt();
game.guess(first, second);
System.out.println(game.peek(first, second) + "\n");
}
long stop = System.currentTimeMillis();
long elapsed = (stop - start) / 1000;
System.out.println(game);
System.out.println("\nYou win!");
System.out.println("Total time: " + elapsed + "s");
}
public class Domino {
private int top, bottom;
private boolean revealed;
public Domino(int x, int y) {
if (x > y) {
top = y;
bottom = x;
} else {
top = x;
bottom = y;
}
}
public int getTop() {
return top;
}
public int getBottom() {
return bottom;
}
public boolean isRevealed() {
return revealed;
}
public void setRevealed(boolean revealed) {
this.revealed = revealed;
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.getTop();
hash = 59 * hash + this.getBottom();
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Domino)) {
return false;
}
final Domino other = (Domino) obj;
if (this.getTop() != other.getTop()) {
return false;
}
if (this.getBottom() != other.getBottom()) {
return false;
}
return true;
}
}
public class MemoryLane {
private Domino[] board;
public MemoryLane(int max) {
board = new Domino[(max * max) + max];
int i = 0;
for (int top = 1; top <= max; top++) {
for (int bot = 1; bot <= max; bot++) {
// make new Domino(2x) +
// save into array
if (top <= bot) {
board[i] = new Domino(top, bot);
i++;
board[i] = new Domino(top, bot);
i++;
}
}
}
shuffle();
}
private void shuffle() {
int index;
Random random = new Random();
for (int i = board.length - 1; i > 0; i--) {
index = random.nextInt(i + 1);
if (index != i) {
Domino temp = board[index];
board[index] = board[i];
board[i] = temp;
}
}
}
public boolean guess(int i, int k) {
if (board[i].equals(board[k])) {
board[i].setRevealed(true);
board[k].setRevealed(true);
return true;
}
return false;
}
public String peek(int a, int b) {
String text = new String();
text += ("[" + board[a].getTop() + "] [" + board[b].getTop() + "]\n");
text += ("[" + board[a].getBottom() + "] [" + board[b].getBottom() + "]\n");
return text;
}
public boolean gameOver() {
int count = 0;
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
count++;
}
}
return (count == board.length);
}
public String debug() {
String text = new String();
for (int i = 0; i < board.length; i++) {
text += ("[" + board[i].getTop() + "] ");
}
text += ('\n');
for (int i = 0; i < board.length; i++) {
text += ("[" + board[i].getBottom() + "] ");
}
return text;
}
public String toString() {
String text = new String();
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
text += ("[" + board[i].getTop() + "] ");
} else {
text += ("[ ] ");
}
}
text += ('\n');
for (int i = 0; i < board.length; i++) {
if (board[i].isRevealed()) {
text += ("[" + board[i].getBottom() + "] ");
} else {
text += ("[ ] ");
}
}
return text;
}
}
}
I figured it out
The problem was my equals method was comparing top to bottom which is why i was getting such weird results. I changed it to
public boolean equals(Domino other){
return this.top == other.top && this.bottom == other.bottom
}
and now it works perfectly fine thanks for all of the help guys!

Java: Fixing array "linking" to allow for resetting

Firstly, I know Lists are better in almost(if not all) every way. I have encountered a substantial bug in an encoder program that I am making. In this program, I have a button that resets the "wheels" responsible for encoding(One of the wheels rotates after every letter encoded). I have a final int[][] called wheelsOriginal that is supposed to store the original value of the int[][] called wheels. Both of these arrays are int[9][36]. I would like a way of making wheelsOriginal stay unchanged throughout the program instead of changing with wheels for some reason. Here is a good way to recreate the problem(Sorry for the lengthy intToChar and charToInt methods!):
Main class:
import java.awt.*;
import javax.swing.*;
public class mainClass {
public static void main(String[] args) {
JFrame frame = new JFrame("Encoder");
frame.setBackground(new Color(225,225,225));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Display d = new Display();
frame.add(d);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
}
Display class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Display extends JPanel implements ActionListener {
static JButton button;
static JLabel letter;
static int currentKey = -10;
static int wheel = 0;
static int[][] wheels = {
{-3,10,-6,2,20,-7,22,5,23,4,6,-9,3,26,0,15,21,-2,13,14,12,1,17,11,-8,-5,18,8,24,9,25,7,19,16,-4,-1},
{9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7},
{18,20,-9,15,12,-6,16,-4,-5,14,24,-7,-8,-3,-1,1,4,7,8,25,10,11,5,6,13,22,19,21,23,-2,3,26,17,9,0,2},
{-3,10,-6,2,20,-7,22,5,23,4,6,-9,3,26,0,15,21,-2,13,14,12,1,17,11,-8,-5,18,8,24,9,25,7,19,16,-4,-1},
{9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7},
{25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
{25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
{25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
{9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7}
};
final static int[][] wheelsOriginal = wheels;
public Display() {
setPreferredSize(new Dimension(250,200));
setFocusable(true);
button = new JButton("Reset");
button.setPreferredSize(new Dimension(225,50));
button.setFont(new Font(button.getFont().getFontName(), button.getFont().getStyle(), 25));
letter = new JLabel(" ", SwingConstants.CENTER);
letter.setPreferredSize(new Dimension(225,100));
letter.setFont(new Font(letter.getFont().getFontName(), Font.BOLD, 125));
letter.setForeground(new Color(0,0,0));
addKeyListener(
new KeyListener() {
public void keyPressed(KeyEvent e) {
if(currentKey == -10 && e.getKeyCode() >= 65 && e.getKeyCode() <= 90) {
currentKey = e.getKeyCode() - 64;
letter.setText(encode() + "");
}
else if(currentKey == -10 && e.getKeyCode() >= 48 && e.getKeyCode() <= 57) {
currentKey = -1 * (e.getKeyCode() - 48);
letter.setText(encode() + "");
}
}
public void keyReleased(KeyEvent e) {
currentKey = -10;
letter.setText(" ");
}
public void keyTyped(KeyEvent e) {}
}
);
button.addActionListener(this);
add(button, TOP_ALIGNMENT);
add(letter);
}
public static char encode() {
int key = currentKey;
for(int i = 0; i < 9; i++) {
key = wheels[i][key + 9];
}
for(int i = 8; i >= 0; i--) {
key = wheels[i][key + 9];
}
rotate(wheels[wheel], isEven(wheel));
if(wheel < 8) {
wheel++;
}
else {
wheel = 0;
}
return((char) key);
}
public static int[] rotate(int[] wheel, boolean positive) {
int revolve;
if(positive) {
revolve = wheel[wheel.length - 1];
for(int i = wheel.length - 2; i > 0; i--) {
wheel[i + 1] = wheel[i];
}
wheel[0] = revolve;
}
else {
revolve = wheel[0];
for(int i = 1; i < wheel.length - 1; i++) {
wheel[i - 1] = wheel[i];
}
wheel[wheel.length - 1] = revolve;
}
return wheel;
}
public static boolean isEven(int num) {
return (num/2 == Math.abs(num/2));
}
public void actionPerformed(ActionEvent e) {
if(e.getSource().equals(button)) {
reset();
grabFocus();
}
}
public static void reset() {
for(int[] i : wheels) {
for(int x : i) {
System.out.print(x + " ");
}
System.out.println("");
}
System.out.println(" ");
for(int[] i : wheelsOriginal) {
for(int x : i) {
System.out.print(x + " ");
}
System.out.println("");
}
System.out.println(" ");
wheels = wheelsOriginal;
for(int[] i : wheels) {
for(int x : i) {
System.out.print(x + " ");
}
System.out.println("");
}
wheel = 0;
letter.setText(" ");
currentKey = ' ';
System.out.println("Pressed");
}
}
Whenever a key is pressed, the encoded letter appears in the window. Even pressing the same key over and over again will usually produce different letters. Pressing the reset button should reset the encoder so that pressing the letter 'A' three times should produce S, E, and Q in that order. I also have designed this so that whenever you press the reset button, three large bulks of numbers print in the console. These show the wheels array before reset, the wheelsOriginal array, and the product wheels array in that order. If you press keys and click reset several times, you will notice that wheelsOriginal changes with wheels. Please help...
Your problem is that you are creating wheelsOriginal as reference of wheels instead of copy. Thats why when you change wheels, wheelsOriginal changes as well.
final static int[][] wheelsOriginal = wheels;
Something like this loop can be used to create a copy of wheels
int[][] wheelsOriginal = new int[wheels.length][];
for( int i = 0; i < wheelsOriginal.length; i++ )
{
wheelsOriginal[i] = Arrays.copyOf( wheels[i], wheels[i].length );
}
Also, for your charToInt and IntToChar methods - you could use the fact that chars are numbers and a->z A->Z 0->9 are grouped together to shorten them significantly
I didn't test that - in case you decide to use something like this - think and test yourself
public int charToInt( char c )
{
if( c >= '0' && c <= '9' ) {
return '0' - c;
} else if( c >= 'A' && c <= 'Z' ) {
return c - 'A' + 1;
} else if( c >= 'a' && c <= 'z' ) {
return c - 'a' + 1;
} else {
return -10;
}
}
public char intToChar( int c )
{
if( c >= -9 && c <= 0 ){
return (char)('0' - c);
} else if( c >= 1 && c <= 26 ){
return (char)(c + 'A' - 1);
} else{
return ' ';
}
}

Tic tac toe in java, overwrite issues

This is a simple tic tac toe game,every thing is right but with a problem that anyone can overwrite the previous marker and put his
I want to disable overwrite, How can I do it ?
Do we have to use final syntax ?
import java.util.*;
class TicTacToe {
static String Side;
static int NumberOfMoves=0;
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
Functions fc = new Functions();
int move;
System.out.println("Enter your Side :\n1) X\n2) O");
Side = sc.next();
if(Side.equals("1") ||Side.equals("x") ||Side.equals("X")) {
Side = "X";
} else if(Side.equals("2") ||Side.equals("o") ||Side.equals("O")) {
Side = "O";
}
fc.initialize();
fc.DisplayBoard();
while(fc.CheckIfWin() == 0) {
System.out.println("Its "+Side+"'s turn");
move = sc.nextInt();
fc.Move(move);
NumberOfMoves++;
fc.CheckIfWin();
fc.DisplayBoard();
fc.SideChange();
}
}
static class Functions {
String Row[] = new String[9];
public void initialize() {
for(int i = 1;i<=9;i++) {
Row[i-1] = Integer.toString(i);
}
}
public void DisplayBoard() {
System.out.print('\u000C');
System.out.println(" "+Row[0]+" | "+Row[1]+" | "+Row[2]);
System.out.println("---|---|---");
System.out.println(" "+Row[3]+" | "+Row[4]+" | "+Row[5]);
System.out.println("---|---|---");
System.out.println(" "+Row[6]+" | "+Row[7]+" | "+Row[8]);
}
public int CheckIfWin() {
/* Possible wins :-
* Horzontal : ( 0=1=2 ), (3, 4, 5), (6, 7, 8)
* Vertical : ( 0=3=6 ), (1=4=7), (2=5=8)
* Croswards : (0=4=8 ), (2=4=6)
*/
if(Row[0].equals(Row[1]) && Row[1].equals(Row[2])) {
System.out.println(Side+" wins.");
Row[0] = "--";Row[1] = "--";Row[2] = "--";
return 1;
} else if(Row[3].equals(Row[4]) && Row[4].equals(Row[5])) {
System.out.println(Side+" wins.");
Row[3] = "--";Row[4] = "--";Row[5] = "--";
return 1;
} else if(Row[6].equals(Row[7]) && Row[7].equals(Row[8])) {
System.out.println(Side+" wins.");
Row[6] = "--";Row[7] = "--";Row[8] = "--";
return 1;
} else if(Row[0].equals(Row[3]) && Row[3].equals(Row[6])) {
System.out.println(Side+" wins.");
Row[0] = "|";Row[3] = "|";Row[6] = "|";
return 1;
} else if(Row[1].equals(Row[4]) && Row[4].equals(Row[7])) {
System.out.println(Side+" wins.");
Row[1] = "|";Row[4] = "|";Row[7] = "|";
return 1;
} else if(Row[2].equals(Row[5]) && Row[5].equals(Row[8])) {
System.out.println(Side+" wins.");
Row[2] = "|";Row[5] = "|";Row[8] = "|";
return 1;
} else if(Row[0].equals(Row[4]) && Row[4].equals(Row[8])) {
System.out.println(Side+" wins.");
Row[0] = "\\";Row[4] = "\\";Row[8] = "\\";
return 1;
} else if(Row[2].equals(Row[4]) && Row[4].equals(Row[6])) {
System.out.println(Side+" wins.");
Row[2] = "/";Row[4] = "/";Row[6] = "/";
return 1;
}
return 0;
}
public void SideChange() {
if(Side.equals("O")) {
Side = "X";
} else {
Side = "O";
}
}
public void Move(int move) {
try {
Row[move-1] = Side;
} catch(Exception e) {
System.out.println("Tried to cheat\n Move will not be accepted");
}
}
}
}
This is pretty scholastic so I can just give you some advice and not the solution.
When you enter the new move, put a method that returns a Boolean (like isValid(int move)) and if that area is occupied it return false. Than put the moves request in a while waiting for a valid move

Recursively find connectivity in a 2D Array

I have a game and I'm having trouble implementing the scores.
Prof stated that it must be recursively done without a for-loop. But I'm having trouble thinking of the algorithm that is used. This is the game.
The score system works so it starts with the valve pipe (Pipe.ValvePipe) and then it checks to see how many pipes are connected to it. Is there a certain algorithm/strategy for doing this type of recursion? Thank you in advance.
pipe.java
public class Pipe {
private boolean openAtTop;
private boolean openAtRight;
private boolean openAtBottom;
private boolean openAtLeft;
private boolean isValve;
private static Pipe VALVE_PIPE;
public Pipe(boolean t, boolean r, boolean b, boolean l, boolean valve) {
openAtTop = t; openAtBottom = b; openAtRight = r; openAtLeft = l;
isValve = valve;
}
public boolean isValve() { return isValve; }
public static Pipe ValvePipe() { return new Pipe(false, false, true, false, true); }
public boolean isValid() { return !(!openAtTop&&!openAtBottom&&!openAtLeft&&!openAtRight); }
public static Pipe RandomPipe() {
Pipe p;
do {
p = new Pipe(Math.random() < 0.5, Math.random() < 0.5,
Math.random() < 0.5, Math.random() < 0.5, false);
} while (!p.isValid());
return p;
}
public boolean isOpenAtTop() { return openAtTop; }
public boolean isOpenAtBottom() { return openAtBottom; }
public boolean isOpenAtLeft() { return openAtLeft; }
public boolean isOpenAtRight() { return openAtRight; }
public boolean fitsBelow(Pipe p) {
return (p == null) || (!openAtTop && !p.isOpenAtBottom()) || (openAtTop && p.isOpenAtBottom());
}
public boolean fitsAbove(Pipe p) {
return (p == null) || (!openAtBottom && !p.isOpenAtTop()) || (openAtBottom && p.isOpenAtTop());
}
public boolean fitsToLeftOf(Pipe p) {
return (p == null) || (!openAtRight && !p.isOpenAtLeft()) || (openAtRight && p.isOpenAtLeft());
}
public boolean fitsToRightOf(Pipe p) {
return (p == null) || (!openAtLeft && !p.isOpenAtRight()) || (openAtLeft && p.isOpenAtRight());
}
public String toString() {
String s = "";
if (openAtTop) s+="1"; else s+="0";
if (openAtRight) s+="1"; else s+="0";
if (openAtBottom) s+="1"; else s+="0";
if (openAtLeft) s+="1"; else s+="0";
return s;
}
public int toInt() {
int s = 0;
if (openAtTop) s+=8;
if (openAtRight) s+=4;
if (openAtBottom) s+=2;
if (openAtLeft) s+=1;
return s;
}
}
PipeGameView.java
import java.awt.*;
import javax.swing.*;
// Subclass JFrame so you can display a window
public class PipeGameView extends JPanel {
private PipeGame game; // The model
private BoardPanel tiles;
private JButton[][] buttons;
private JProgressBar timeBar;
private JButton startStop;
private JRadioButton twoMinButton, tenMinButton, noLimitButton;
private JLabel statusLabel;
// This constructor builds the window
public PipeGameView(PipeGame g) {
game = g; // Store the model for access in update()
// Set up the components
tiles = new BoardPanel();
tiles.setLayout(new GridLayout(game.getRows(), game.getRows()));
buttons = new JButton[game.getRows()][game.getRows()];
// Add the buttons to the tile panel
ImageIcon ic = new ImageIcon("Pipes0000.GIF");
for (int r=0; r<game.getRows(); r++) {
for (int c=0; c<game.getRows(); c++) {
buttons[r][c] = new JButton(ic);
tiles.add(buttons[r][c]);
}
}
// Now layout the components using a gridbag layout
GridBagLayout layout = new GridBagLayout();
GridBagConstraints layoutConstraints = new GridBagConstraints();
this.setLayout(layout);
// Add the Start/Stop Button
startStop = new JButton("Start Game");
layoutConstraints.gridx = 0; layoutConstraints.gridy = 0;
layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(startStop, layoutConstraints);
this.add(startStop);
// Add the JRadioButtons
twoMinButton = new JRadioButton("2 minutes");
tenMinButton = new JRadioButton("10 minutes");
noLimitButton = new JRadioButton("No Time Limit");
ButtonGroup group = new ButtonGroup();
group.add(twoMinButton); group.add(tenMinButton); group.add(noLimitButton);
layoutConstraints.gridx = 1;
layout.setConstraints(twoMinButton, layoutConstraints);
this.add(twoMinButton);
layoutConstraints.gridx = 2;
layout.setConstraints(tenMinButton, layoutConstraints);
this.add(tenMinButton);
layoutConstraints.gridx = 3;
layout.setConstraints(noLimitButton, layoutConstraints);
this.add(noLimitButton);
// Add the tiles
layoutConstraints.gridx = 0; layoutConstraints.gridy = 1;
layoutConstraints.gridwidth = 4; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(tiles, layoutConstraints);
this.add(tiles);
// Add the label
statusLabel = new JLabel("Time Left: ");
statusLabel.setVisible(false);
layoutConstraints.gridx = 0; layoutConstraints.gridy = 2;
layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.NONE;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.WEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(statusLabel, layoutConstraints);
this.add(statusLabel);
timeBar = new JProgressBar(0, 100);
timeBar.setValue(100);
timeBar.setVisible(false);
layoutConstraints.gridx = 1; layoutConstraints.gridy = 2;
layoutConstraints.gridwidth = 3; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.HORIZONTAL;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.EAST;
layoutConstraints.weightx = 5.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(timeBar, layoutConstraints);
this.add(timeBar);
update();
}
// Get methods for the components
public JButton getButton(int r, int c) { return buttons[r][c]; }
public JButton getStartStopButton() { return startStop; }
public JProgressBar getTimeBar() { return timeBar; }
public JRadioButton getTwoMinButton() { return twoMinButton; }
public JRadioButton getTenMinButton() { return tenMinButton; }
public JRadioButton getNoLimitButton() { return noLimitButton; }
public void setGame(PipeGame g) { game = g; }
// This is called whenever the model has changed. Note that this code is not efficient. All ICONS should really
// be loaded upon game start and stored into a static array of ImageIcons. Then, these static icons should be
// used instead of re-creating icons each time.
public void update() {
// Update the look of the buttons
for (int r=0; r<game.getRows(); r++) {
for (int c=0; c<game.getRows(); c++) {
if (game.isOver())
buttons[r][c].setEnabled(false);
else
buttons[r][c].setEnabled(true);
if (game.getPipe(r,c) == null)
buttons[r][c].setSelected(false);
else {
// Determine the portion of the icon's filename that matches the pipe
String currentPipeCodes = "Start";
if (!game.getPipe(r,c).isValve())
currentPipeCodes = game.getPipe(r,c).toString();
buttons[r][c].setSelectedIcon(new ImageIcon("pipes"+ currentPipeCodes +".GIF"));
buttons[r][c].setSelected(true);
}
}
}
// Update the start/stop button
if (game.isOver())
startStop.setText("Start");
else
startStop.setText("Stop");
// Update the radio buttons
if (game.isOver()) {
twoMinButton.setEnabled(true);
tenMinButton.setEnabled(true);
noLimitButton.setEnabled(true);
}
else {
twoMinButton.setEnabled(false);
tenMinButton.setEnabled(false);
noLimitButton.setEnabled(false);
}
// Update the status label
if (game.isOver()) {
statusLabel.setText("Final Score: " + game.getPlacedPipes());
statusLabel.setVisible(true);
}
else {
if (game.getStyle() == 2) {
statusLabel.setVisible(false);
}
else {
statusLabel.setText("Time Left: ");
statusLabel.setVisible(true);
}
}
// Update the timer bar
if (game.isOver() || (game.getStyle() == 2)) {
timeBar.setVisible(false);
}
else {
timeBar.setValue((int)(game.getTimeRemaining() / (float)game.getTimeLimit() * 100));
timeBar.setVisible(true);
}
// Update the cursor
ImageIcon i;
if (game.isOver()) {
tiles.setCursor(Cursor.getDefaultCursor());
}
else {
if (game.getNextPipe().isValve())
i = new ImageIcon("pipesStart.GIF");
else
i = new ImageIcon("pipes"+ game.getNextPipe().toString() +".GIF");
tiles.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(i.getImage(), new Point(0,0), "pipe"));
}
}
}
I didnt go through all your code but as a hint the function would look like this:
getScore( Pipe p ){
if ( p == null ) return 0;
int res = 1; // size of this pipe
res += getScore(leftPipe);
res += getScore(rightPipe);
...
return res;
}
hope this helps
I think you need to includes the row and col to calculate the pipes that are connected to the main starting pipe
public void connectedPipes(int row, int col){
if(row == null) return 0;
int res = 1; // size of this pipe
res += getScore(leftPipe);
res += getScore(rightPipe);
return res;
}

accessing javascript from inside java

I know that there are lots of examples out there on this, but they all feel a little dated (even the sun docs) so I'm asking here to make sure what I'm doing is up to date. How would I go about talking to javascript from inside a java applet? Something simple like how to call alert() is all I'm looking for. Bonus points for a way to check if the browser has javascript enabled (this applet may be used in a school setting where having javascript turned off is a real possibility). All help is greatly appreciated, thanks in advance...
Code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import netscape.javascript.JSObject;
public class TeamProject extends Applet implements ActionListener, MouseListener {
char[][] charValues = new char[10][10];
Table aTable;
boolean allowUserInput = false;
Button BtnStart;
Button randomChangeBtn;
boolean guessMode;
JSObject jso;
public void init() {
//setup buttons
BtnStart = new Button("add row/column");
BtnStart.addActionListener((ActionListener)this); //cast
randomChangeBtn = new Button("change one value");
randomChangeBtn.addActionListener((ActionListener)this);
//add button
this.add(BtnStart);
//add image to Image objects
Image imgO = getImage(getCodeBase(), "images/not.gif");
Image imgX= getImage(getCodeBase(), "images/cross.gif");
//setup table
aTable = new Table(100, 100, 75, 55, 5, 5, imgX, imgO);
//setBackground(Color.LIGHT_GRAY);
super.resize(700, 700);
//add mouse listener
addMouseListener(this);
//initially guessMode will be false
guessMode = false;
//to talk to javascript
jso = JSObject.getWindow(this);
}
public void paint(Graphics g) {
g.setColor(Color.black);
aTable.draw(g);
}
//Mouse listener methods
public void mousePressed (MouseEvent e) {
if(!guessMode){
if ((allowUserInput)) { //&&(aTable.isDrawable(e.getX(), e.getY())))
aTable.swapSquareValue(e.getX(), e.getY());
repaint();
}
} else {
System.out.println("guessed row = " + e.getY() + " guessed col = " + e.getX());
aTable.checkGuess(e.getX(), e.getY());
//repaint();
}
}
public void mouseClicked (MouseEvent e) {}
public void mouseEntered (MouseEvent e) {}
public void mouseReleased (MouseEvent e) {}
public void mouseExited (MouseEvent e) {}
//Button action listener
public void actionPerformed(ActionEvent e) {
if (e.getSource() == BtnStart) {
aTable.addRow();
aTable.addColumn();
this.remove(BtnStart);
this.add(randomChangeBtn);
repaint();
} else if (e.getSource() == randomChangeBtn) {
//aTable.addRow();
aTable.randomChangeFunc();
repaint();
guessMode = true;
}
allowUserInput = true;
System.out.println(aTable.toString());
}
}
and my Table class:
import java.awt.*;
import java.util.Random;
public class Table {
private char[][]values = new char[10][10]; //probably better to use array of integer values(0 or 1)
Image imgO;
Image imgX;
private int Rows;
private int Columns;
private int BoxWidth ;
private int BoxHeight;
public Point Pos = new Point();
private int tableHeight;
private int tableWidth;
private int changedRow;
private int changedCol;
//constructor
public Table(int x, int y, int width, int height, int col, int rows, Image X, Image O) {
Rows = rows;
Columns = col;
BoxWidth = width;
BoxHeight = height;
Pos.x = x;
Pos.y = y;
imgX = X;
imgO = O;
tableHeight = Rows*BoxHeight;
tableWidth = Columns*BoxWidth;
this.setValues();
}
//draw table
public void draw(Graphics g) {
//draw vertical table lines
for (int i = 0 ; i <= Columns ; i++)
g.drawLine(i*BoxWidth + Pos.x, Pos.y, i*BoxWidth + Pos.x, tableHeight+Pos.y);
//draw horizontal table line
for(int i = 0 ; i <= Rows ; i++)
g.drawLine(Pos.x, i*BoxHeight + Pos.y, tableWidth+Pos.x, i*BoxHeight + Pos.y);
//draw values
drawValues(g);
}
public void swapSquareValue(int x, int y) {
if (this.isDrawable(x, y)) {
int col = this.getColumn(x)-1;
int row = this.getRow(y)-1;
if(values[row][col] == 'X')
values[row][col] = 'O';
else if(values[row][col] == 'O')
values[row][col] = 'X';
else
System.out.println("ERROR SWAPPING SQUARE VALUE");
} else
System.out.println("says not drawable");
}
public char getValue(int col, int row) {
return values[row][col];
}
//return true if (x,y) is a point in the table
public boolean isDrawable(int x, int y) {
if((this.getRow(y)!=-1)||(this.getColumn(x)!=-1))
return true;
else
return false;
}
public void addRow() {
Rows++;
tableHeight = (Rows*BoxHeight);
int numOfXs = 0;
for (int c=0; c < Columns; c++) {
numOfXs = 0;
for(int r = 0; r < Rows - 1; r++) {
if(values[r][c] == 'X'){
numOfXs++;
System.out.println("in column " + c + "new x found at " + r + " " + c + ", numOfXs = " + numOfXs);
}
if(numOfXs % 2 == 0) {
values[Rows - 1][c] = 'O';
} else{
values[Rows - 1][c] = 'X';
}
}//end inner for
System.out.println("end of column " + c);
}//end outer for
}// end function
public void addColumn() {
Columns++;
tableWidth = (Columns*BoxWidth);
int numOfXs = 0;
for (int r=0; r < Rows; r++) {
numOfXs = 0;
for(int c = 0; c < Columns - 1; c++) {
if(values[r][c] == 'X') {
numOfXs++;
System.out.println("in row " + r + "new x found at " + r + " " + c + ", numOfXs = " + numOfXs);
}
if(numOfXs % 2 == 0) {
values[r][Columns - 1] = 'O';
}
else {
values[r][Columns - 1] = 'X';
}
}//end inner for
System.out.println("end of row " + r);
}
}
//does not add or remove values
public void setColumn(int col) {
Columns = col;
tableWidth = (Columns*BoxWidth);
}
//does not add or remove values
public void setRows(int row) {
Rows = row;
tableHeight = (row*BoxHeight);
}
public String toString() {
String ValueString = "Displaying charValues[" + Rows + "][" + Columns + "]\n";
for (int r=0; r < Rows; r++) {
for (int c=0; c < Columns; c++) {
ValueString += (char)values[r][c];
}
ValueString += "\n"; //next line
}
return ValueString;
}
private void drawValues(Graphics g) {
Point drawPoint = new Point();
for (int r=0; r < Rows; r++)
for (int c=0; c < Columns; c++) {
drawPoint.x = Pos.x+BoxWidth*c;
drawPoint.y = Pos.y+BoxHeight*r;
//g.setColor(Color.white);
//g.fillRect(drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1);
if (values[r][c] == 'X') {
g.drawImage(imgX,drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1, null);
} else {
g.drawImage(imgO,drawPoint.x+1, drawPoint.y+1, BoxWidth-1, BoxHeight-1, null);
}
//System.out.print((char)values[r][c]);
}
g.setColor(Color.black);
}
//fills array with random values
private void setValues() {
for (int r=0; r < Rows; r++)
for (int c=0; c < Columns; c++) {
values[r][c] = this.randomChar();
}
}
//randomly return 'X' or 'O'
private char randomChar() {
char randomValue;
Random RandomGen = new Random();
if (RandomGen.nextInt(2)==0)
randomValue = 'O';
else
randomValue ='X';
return randomValue;
}
private int getColumn(int x) {
int offsetx=0;
for (int i = 0 ; i < Columns ; i++) {
offsetx = i*BoxWidth;
if((x>Pos.x+offsetx)&& (x<Pos.x+offsetx+BoxWidth))
return i+1;
}
return -1;
}
private int getRow(int y) {
int offsety=0;
for (int i = 0 ; i < Rows ; i++) {
offsety = i*BoxHeight;
if((y>Pos.y+offsety)&& (y<Pos.x+offsety+BoxHeight))
return i+1;
}
return -1;
}
public void randomChangeFunc() {
//get random row and column
Random rand=new Random();
int randRow = rand.nextInt(Rows);
int randCol = rand.nextInt(Columns);
System.out.println("randRow = " + randRow + " randCol = " + randCol);
/*THIS SHOULD BE HANDLED BY swapSquareValue(randCol,randRow)
/*BUT GETTING ERRORS (notDrawable). THE FOLLOWING CODE IS A WORK-AROUND
*/
if(values[randRow][randCol] == 'X')
values[randRow][randCol] = 'O';
else if(values[randRow][randCol] == 'O')
values[randRow][randCol] = 'X';
else
System.out.println("ERROR SWAPPING SQUARE VALUE");
//set globals
changedRow = randRow;
changedCol = randCol;
}
public void checkGuess(int guessCol, int guessRow){
int gCol = this.getColumn(guessCol)-1;
int gRow = this.getRow(guessRow)-1;
System.out.println("gCol = " + gCol + " gRow = " + gRow);
if(gCol == changedCol && gRow == changedRow) {
System.out.println("CORRECT!!!");
} else
System.out.println("incorrect :(");
}
}
Changing my javac command to:
javac -classpath /usr/lib/Java6u1/jre/lib/plugin.jar TeamProject.java
ignores my "Table" class and I get errors where I mention that. Any ideas?
Look at this article. If you try calling JS from applet on this page it definitely works, because there are js exception after update action from applet :)
import netscape.javascript.JSObject
public void init()
{
jso = JSObject.getWindow(this);
}
public void actionPerformed(ActionEvent e) {
if(jso != null )
try {
jso.call("updateWebPage", new String[] {txt.getText()});
}
catch (Exception ex) {
ex.printStackTrace();
}
}
EDIT:
For the classpath problem you need to add plugin.jar to your classpath which is located in %JAVA_HOME%\jre\lib\plugin.jar
EDIT2:
I think that your problem is that a class Table isn't compiled too:
try javac -classpath /usr/lib/Java6u1/jre/lib/plugin.jar TeamProject.java Table.java or use wildcards like *.java.
Maybe you should consider use IDE like Eclipse or Netbeans to compile and run project instead of struggling with command line tools.
As requested a sample which calls alert on the page it is embedded in (tested in Opera 10.01, FF 3.5.4, IE6).
Note the MAYSCRIPT in the applet tag, this MUST be present to enable java-javascript communication. As per default access to JSObject is disabled due to security reasons.
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<applet code="HelloWWW.class" width="300px" height="100px" MAYSCRIPT></applet>
</body>
</html>
Java (compile with javac -cp .;[pathtojre]/jre/lib/plugin.jar HelloWWW.java)
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import netscape.javascript.*;
public class HelloWWW extends Applet implements ActionListener {
Button runButton;
public void init() {
runButton = new Button("Run: alert(\"Hello WWW\")");
add(runButton);
runButton.addActionListener(this);
}
public void actionPerformed(ActionEvent evt) {
if (evt.getSource() == runButton) {
try {
//get JSOBject
JSObject jso = JSObject.getWindow(this);
//call alert with parameter passed as Object array
jso.call("alert", new Object[]{"Hello WWW"});
} catch (JSException e) {
e.printStackTrace();
}
runButton.setLabel("Did it!");
repaint();
}
}
}
Also check Java-to-Javascript Communication and Mozilla Dev: JSObject for further info.

Categories