I want to start off by saying sorry, I wasn't able to search for this problem as I couldn't exactly describe it myself.
I have a series of if-statements to account for each scenario. As you can see in the mammoth block of code below, I want arguments to come in any order. How, if possible, can I shorten this?
if(args[1].startsWith("u:") && args[2].startsWith("r:") && args[3].startsWith("l:")){ // u / r / l
Player p = player.getServer().getPlayer(args[1].split(":")[1]);
String r = args[2].split(":")[1];
String l = args[3].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}else if(args[1].startsWith("r:") && args[2].startsWith("l:") && args[3].startsWith("u:")){ // r / l / u
Player p = player.getServer().getPlayer(args[3].split(":")[1]);
String r = args[1].split(":")[1];
String l = args[2].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}else if(args[1].startsWith("l:") && args[2].startsWith("u:") && args[3].startsWith("r:")){ // l / u / r
Player p = player.getServer().getPlayer(args[2].split(":")[1]);
String r = args[3].split(":")[1];
String l = args[1].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}else if(args[1].startsWith("u") && args[2].startsWith("l:") && args[3].startsWith("r:")){ // u / l / r
Player p = player.getServer().getPlayer(args[1].split(":")[1]);
String r = args[3].split(":")[1];
String l = args[2].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}else if(args[1].startsWith("l:") && args[2].startsWith("r:") && args[3].startsWith("u:")){ // l / r / u
Player p = player.getServer().getPlayer(args[2].split(":")[1]);
String r = args[2].split(":")[1];
String l = args[1].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}else if(args[1].startsWith("r:") && args[2].startsWith("u:") && args[3].startsWith("l:")){ // r / u / l
Player p = player.getServer().getPlayer(args[2].split(":")[1]);
String r = args[1].split(":")[1];
String l = args[3].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}
Player p = null;
String r = null;
String l = null;
for (int i = 1; i <= 3; i++) {
String[] components = args[i].split(":");
switch(components[0]) {
case "u":
p = player.getServer().getPlayer(components[1]);
break;
case "r":
r = components[1];
break;
case "l":
l = components[1];
}
}
if (p != null && r != null && l != null) {
Config.addPlayer(p, r, l, player);
return true;
}
I think you could copy the array with Arrays.copyOfRange(T[], int, int) and then sort it with Arrays.sort(Object[]). Something like,
String[] tmp = Arrays.copyOfRange(args, 1, args.length);
Arrays.sort(tmp);
if(tmp[0].startsWith("l:") && tmp[1].startsWith("r:")
&& tmp[2].startsWith("u:"))
{ /* l / r / u */
Player p = player.getServer().getPlayer(tmp[2].split(":")[1]);
String r = tmp[1].split(":")[1];
String l = tmp[0].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}
What you are looking for is called Chain of Responsibility pattern:
Since you don't show enough context of what this is actually supposed to be doing, I just named the classes and methods strawman names, use more contextual names.
And you will have to modify what is in the isValid() method maybe, but this is the general way to handle exploding if/elseif/else statements.
public static void main(String[] args)
{
final List<Scenario> scenarios = new ArrayList<>();
scenarios.add(new Scenario("u:", "r:", "l:"));
scenarios.add(new Scenario("r:", "L:", "u:"));
scenarios.add(new Scenario("l:", "u:", "r:"));
for (final Scenario f : scenarios)
{
if (f.isValid(args)) { break; }
}
}
public static class Scenario
{
private final String arg1prefix;
private final String arg2prefix;
private final String arg3prefix;
public Scenario(#Nonnull final String arg1prefix, #Nonnull final String arg2prefix, final String arg3prefix)
{
this.arg1prefix = arg1prefix;
this.arg2prefix = arg2prefix;
this.arg3prefix = arg3prefix;
}
public boolean isValid(#Nonnull final String... args)
{
if (args[1].startsWith(this.arg1prefix) && args[2].startsWith(this.arg2prefix) && args[3].startsWith(this.arg3prefix))
{
final Player p = player.getServer().getPlayer(args[1].split(":")[1]);
final String r = args[2].split(":")[1];
final String l = args[3].split(":")[1];
Config.addPlayer(p, r, l, player);
return true;
}
else
{
return false;
}
}
}
Related
I'm having this error:
The method getValue() is undefined for the type Object
*This is the code in error: In the line:
final String materialName = BasePlugin.getPlugin().getItemDb().getName(new ItemStack(((Object) ((Map)dataMap).entrySet().iterator().next()).getValue().getItemType(), 1));
Complete Code
public class LandMap
{
private static final int FACTION_MAP_RADIUS_BLOCKS = 22;
private static final Material[] BLACKLISK;
#SuppressWarnings("rawtypes")
public static boolean updateMap(final Player player, final HCF plugin, final VisualType visualType, final boolean inform) {
final Location location = player.getLocation();
final World world = player.getWorld();
final int locationX = location.getBlockX();
final int locationZ = location.getBlockZ();
final int minimumX = locationX - 22;
final int minimumZ = locationZ - 22;
final int maximumX = locationX + 22;
final int maximumZ = locationZ + 22;
final Set<Claim> board = new LinkedHashSet<Claim>();
boolean subclaimBased;
if (visualType == VisualType.SUBCLAIM_MAP) {
subclaimBased = true;
}
else {
if (visualType != VisualType.CLAIM_MAP) {
player.sendMessage(ConfigurationService.RED + "Not supported: " + visualType.name().toLowerCase() + '.');
return false;
}
subclaimBased = false;
}
for (int x = minimumX; x <= maximumX; ++x) {
for (int z = minimumZ; z <= maximumZ; ++z) {
final Claim claim = plugin.getFactionManager().getClaimAt(world, x, z);
if (claim != null) {
if (subclaimBased) {
board.addAll(claim.getSubclaims());
}
else {
board.add(claim);
}
}
}
}
if (board.isEmpty()) {
player.sendMessage(ConfigurationService.RED + "No claims are in your visual range to display.");
return false;
}
for (final Claim claim2 : board) {
if (claim2 == null) {
continue;
}
final int maxHeight = Math.min(world.getMaxHeight(), 256);
final Location[] corners = claim2.getCornerLocations();
final List<MemoryBlockLocation> shown = new ArrayList<MemoryBlockLocation>(maxHeight * corners.length);
for (final Location corner : corners) {
for (int y = 0; y < maxHeight; ++y) {
shown.add(new MemoryBlockLocation(world, corner.getBlockX(), y, corner.getBlockZ()));
}
}
final Object dataMap = plugin.getVisualiseHandler().generate(player, shown, visualType, true);
if (((Map)dataMap).isEmpty()) {
continue;
}
final String materialName = BasePlugin.getPlugin().getItemDb().getName(new ItemStack(((Object) ((Map)dataMap).entrySet().iterator().next()).getValue().getItemType(), 1));
if (!inform || claim2.getFaction() == null) {
continue;
}
player.sendMessage(ConfigurationService.YELLOW + claim2.getFaction().getDisplayName((CommandSender)player) + ConfigurationService.YELLOW + " owns land " + ConfigurationService.GRAY + " (displayed with " + materialName + ")" + ConfigurationService.YELLOW + '.');
}
return true;
}
public static Location getNearestSafePosition(final Player player, final Location origin, final int searchRadius) {
return getNearestSafePosition(player, origin, searchRadius, false);
}
public static Location getNearestSafePosition(final Player player, final Location origin, final int searchRadius, final boolean stuck) {
final FactionManager factionManager = HCF.getPlugin().getFactionManager();
final Faction playerFaction = factionManager.getPlayerFaction(player.getUniqueId());
final int max = ConfigurationService.BORDER_SIZES.get(origin.getWorld().getEnvironment());
final int originalX = Math.max(Math.min(origin.getBlockX(), max), -max);
final int originalZ = Math.max(Math.min(origin.getBlockZ(), max), -max);
final int minX = Math.max(originalX - searchRadius, -max) - originalX;
final int maxX = Math.min(originalX + searchRadius, max) - originalX;
final int minZ = Math.max(originalZ - searchRadius, -max) - originalZ;
final int maxZ = Math.min(originalZ + searchRadius, max) - originalZ;
for (int x = 0; x < searchRadius; ++x) {
if (x <= maxX) {
if (-x >= minX) {
for (int z = 0; z < searchRadius; ++z) {
if (z <= maxZ) {
if (-z >= minZ) {
final Location atPos = origin.clone().add((double)x, 0.0, (double)z);
final Faction factionAtPos = factionManager.getFactionAt(atPos);
if (factionAtPos == null || (!stuck && playerFaction != null && playerFaction.equals(factionAtPos)) || !(factionAtPos instanceof PlayerFaction)) {
final Location safe = getSafeLocation(origin.getWorld(), atPos.getBlockX(), atPos.getBlockZ());
if (safe != null) {
return safe.add(0.5, 0.5, 0.5);
}
}
final Location atNeg = origin.clone().add((double)x, 0.0, (double)z);
final Faction factionAtNeg = factionManager.getFactionAt(atNeg);
if (factionAtNeg == null || (!stuck && playerFaction != null && playerFaction.equals(factionAtNeg)) || !(factionAtNeg instanceof PlayerFaction)) {
final Location safe2 = getSafeLocation(origin.getWorld(), atNeg.getBlockX(), atNeg.getBlockZ());
if (safe2 != null) {
return safe2.add(0.5, 0.5, 0.5);
}
}
}
}
}
}
}
}
return null;
}
private static Location getSafeLocation(final World world, final int x, final int z) {
Block highest = world.getHighestBlockAt(x, z);
Material type = highest.getType();
if (Arrays.asList(LandMap.BLACKLISK).contains(type)) {
return null;
}
while (!type.isSolid()) {
if (highest.getY() <= 1 || Arrays.asList(LandMap.BLACKLISK).contains(type)) {
return null;
}
highest = highest.getRelative(BlockFace.DOWN);
type = highest.getType();
}
return highest.getRelative(BlockFace.UP).getLocation();
}
static {
BLACKLISK = new Material[] { Material.LEAVES, Material.LEAVES_2, Material.FENCE_GATE, Material.WATER, Material.LAVA, Material.STATIONARY_LAVA, Material.STATIONARY_WATER };
}
}
Imports:
import org.bukkit.entity.*;
import net.tutorialesaful.hardcorefactions.faction.claim.*;
import net.tutorialesaful.hardcorefactions.*;
import net.tutorialesaful.hardcorefactions.util.location.*;
import net.tutorialesaful.framework.*;
import net.tutorialesaful.hardcorefactions.visualise.*;
import org.bukkit.inventory.*;
import org.bukkit.command.*;
import org.bukkit.*;
import net.tutorialesaful.hardcorefactions.faction.type.*;
import java.util.*;
import org.bukkit.block.*;
This is a class of bukkit
what object generate() method returns? Could you add generate() method to your question?
you try to cast it to an instance of the Object
((Object) ((Map)dataMap).entrySet().iterator().next()).getValue()...
which (as #MadProgrammer said) doesn't have getValue() method. If you need the Map you should to cast it to the Map and use the get(Object key) method
final String materialName = BasePlugin.getPlugin().getItemDb().getName(new ItemStack(((Map) ((Map)dataMap).entrySet().iterator().next()).get(**the key**).getItemType(), 1));
But in this case you must know the key.
I had previously written code that would take a mathematical expression and turn it into a parse tree, I am now trying to visually display the tree that has been created by drawing on a JPanel. The expression is input into the console by the user, it outputs the postfix and I want to also display the tree. However when I run my current program the tree is not rendered on the JPanel. I don't get any errors from the compiler so I'm unsure what the issue is.
public class TreeView extends JPanel {
//Class for drawing the Tree onto a panel
private int radius = 20;
private int levelGap = 50;
ExpTree t;
public TreeView(ExpTree t) {
this.t = t;
}
protected void paintComponent(Graphics g) {
super.paintComponents(g);
if (t.getRoot() != null) {
displayTree(g, t.getRoot(), getWidth() / 2, 30, getWidth() / 4);
}
}
private void displayTree(Graphics g, ExpTree t, int x, int y, int gap) {
g.drawOval(x - radius, y - radius, 2 * radius, 2 * radius);
g.drawString(t.getLeafVal() + "", x - 6, y + 4);
if (t.getlChild() != null) {
connectCircles(g, x - gap, y + levelGap, x, y);
displayTree(g, t.lChild, x - gap, y + levelGap, gap /2);
}
if (t.getrChild() != null) {
connectCircles(g, x + gap, y + levelGap, x, y);
displayTree(g, t.rChild, x + gap, y + levelGap, gap /2);
}
}
private void connectCircles(Graphics g, int x1, int y1, int x2, int y2) {
double d = Math.sqrt(levelGap * levelGap + (x2 - x1) * (y2 - y1));
int x11 = (int)(x1 - radius * (x1 - x2) / d);
int y11 = (int)(y1 - radius * (y1 - y2) / d);
int x21 = (int)(x2 + radius * (x1 - x2) / d);
int y21 = (int)(y2 + radius * (y1 - y2) / d);
g.drawLine(x11, y11, x21, y21);
}
}
public class Test extends JFrame {
public Test() {
setSize(400, 400);
setLayout(new BorderLayout());
JPanel jp = new JPanel();
add(jp);
setVisible(true);
}
public static void main(String[] args) {
Test test = new Test();
//create parse trees from input in console
boolean done = false;
boolean valid = false;
Parser p = new Parser();
ExpTree myTree;
System.out.println("Enter an expression to convert into postfix notation");
do {
System.out.println("Enter an expression: ");
try {
myTree = p.parseLine();
}
catch (ParseException e) {
System.out.println("Invalid Expression: Ensure it ends with a semicolon");
continue;
}
System.out.println(myTree.toPostfix(myTree));
TreeView view = new TreeView(myTree);
test.add(view);
view.repaint();
System.out.println("Do you want to enter another expression? (y/n)");
do {
String s = p.getLine();
switch (s) {
case "y" : valid = true;
done = false;
continue;
case "n" : valid = true;
done = true;
continue;
default: valid = false;
done = false;
System.out.println("Invalid input: Must be y or n");
}
} while (!valid);
} while (!done);
}
}
//Setup of the tree incase it's useful
public class ExpTree {
//Tree object that is created when an expression is parsed
private int type;
private Object leafVal;
public ExpTree lChild, rChild;
public static final int NUM = 0, VAL = 1, OP = 2;
private StringBuffer sb = new StringBuffer();
public ExpTree(int type, Object leafVal, ExpTree l, ExpTree r) {
this.type = type;
this.leafVal = leafVal;
this.lChild = l;
this.rChild = r;
}
//return the forth expression, a postfix expression
public String toPostfix(ExpTree t) {
if (t != null) {
toPostfix(t.lChild);
toPostfix(t.rChild);
sb.append(t.leafVal);
sb.append(" ");
}
return sb.toString();
}
public ExpTree getRoot() {
return this;
}
public Object getLeafVal() {
return leafVal;
}
public ExpTree getlChild() {
return lChild;
}
public ExpTree getrChild() {
return rChild;
}
}
class ParseException extends RuntimeException
{ public ParseException(String s)
{ super("Invalid expression: "+s);
}
}
public class Parser
{ private Lexer lex;
public Parser()
{ lex = new Lexer();
}
public ExpTree parseLine()
{ lex.init();
lex.getToken();
ExpTree result = parseExp(true);
if (lex.token==Lexer.where)
{ lex.getToken();
ExpTree defs = parseDefList();
result = makeWhereTree(result, defs);
}
if (lex.token!=Lexer.semico)
{ throw new ParseException("semicolon expected");
}
return result;
}
public String getLine()
{ return lex.getLine();
}
private ExpTree parseExp(boolean idsAllowed)
{ ExpTree result = parseTerm(idsAllowed);
{ while (lex.token==Lexer.plus || lex.token==Lexer.minus)
{ int op = lex.token;
lex.getToken();
if (op==Lexer.plus)
result = makePlusTree(result, parseTerm(idsAllowed));
else
result = makeMinusTree(result, parseTerm(idsAllowed));
}
}
return result;
}
private ExpTree parseTerm(boolean idsAllowed)
{ ExpTree result = parseOpd(idsAllowed);
{ while (lex.token==Lexer.times || lex.token==Lexer.div || lex.token==Lexer.mod)
{ int op = lex.token;
lex.getToken();
if (op==Lexer.times)
result = makeTimesTree(result, parseOpd(idsAllowed));
else if (op==Lexer.mod)
result = makeModTree(result, parseOpd(idsAllowed));
else
result = makeDivideTree(result, parseOpd(idsAllowed));
}
}
return result;
}
private ExpTree parseOpd(boolean idsAllowed)
{ ExpTree result;
switch(lex.token)
{ case Lexer.num:
result = makeNumberLeaf(lex.numval);
lex.getToken();
return result;
case Lexer.id:
if (!idsAllowed)
throw new ParseException("identifier not allowed in identifier defintion");
result = makeIdLeaf(lex.idval);
lex.getToken();
return result;
case Lexer.lp:
lex.getToken();
result = parseExp(idsAllowed);
if (lex.token!=Lexer.rp)
throw new ParseException("right parenthesis expected");
lex.getToken();
return result;
default:
throw new ParseException("invalid operand");
}
}
private ExpTree parseDefList()
{ ExpTree result = parseDef();
while (lex.token==Lexer.and)
{ lex.getToken();
result = makeAndTree(result, parseDef());
}
return result;
}
private ExpTree parseDef()
{ if (lex.token!=Lexer.id)
throw new ParseException("definition must start with identifier");
char id = lex.idval;
if (Character.isUpperCase(id))
throw new ParseException("upper-case identifiers cannot be used in defintion list");
lex.getToken();
if (lex.token!=Lexer.eq)
throw new ParseException("'=' expected");
lex.getToken();
return makeDefTree(id, parseExp(false));
}
// the next seven methods need to be modified for part 3 of the assignment
static ExpTree makeNumberLeaf(int n)
{ return new ExpTree(ExpTree.NUM, n, null, null);
// this method should return a new number leaf with value n created using your constructor
// if you've used the abstract class approach you will probably need something like
// return new NumLeaf(n);
// if you've used an ExpTree class that stores the node kind you will probably need something like
// return new ExpTree(ExpTree.numNode, n , null, null);
}
static ExpTree makeIdLeaf(char c)
{ return new ExpTree(ExpTree.VAL, c, null, null);
// this method should return a new id leaf with value c
}
static ExpTree makePlusTree(ExpTree l, ExpTree r)
{ return new ExpTree(ExpTree.OP, '+', l, r);
// this method should return a new plus node with children l and r created using your constructor
// if you've used the abstract class approach you will probably need something like
// return new OpNode('+', l, r);
// or
// return new PlusNode(l, r);
// if you've used an ExpTree class that stores the node kind you will probably need something like
// return new ExpTree(ExpTree.opMode, '+', l, r);
}
static ExpTree makeMinusTree(ExpTree l, ExpTree r)
{ return new ExpTree(ExpTree.OP, '-', l, r);
// this method should return a new minus node with children l and r
}
static ExpTree makeTimesTree(ExpTree l, ExpTree r)
{ return new ExpTree(ExpTree.OP, '*', l, r);
// this method should return a new times node with children l and r
}
static ExpTree makeDivideTree(ExpTree l, ExpTree r)
{ return new ExpTree(ExpTree.OP, '/', l, r);
// this method should return a new divide node with children l and r
}
static ExpTree makeModTree(ExpTree l, ExpTree r)
{ return new ExpTree(ExpTree.OP, '%', l, r);
// this method should return a new mod (%) node with children l and r
}
// the next three methods need to be modified for part 6 of the assignment - do not modify them if you have not attempted part 6
static ExpTree makeWhereTree(ExpTree l, ExpTree r)
{ // remove the following line if you modify this method; leave it here if you do not attempt part 6
System.out.println("Part 6 not attempted");
return null;
// this method should return a new 'where' node with children l and r
}
static ExpTree makeAndTree(ExpTree l, ExpTree r)
{ return null;
// this method should return a new 'and' node with children l and r
}
static ExpTree makeDefTree(char c, ExpTree t)
{ return null;
// this method should return a new definition node with identifier c and child t
// if your definition nodes have 2 children you should put a new id leaf in the left child and use t as the right child
}
}
class Lexer
{ static final int err = 0, num = 1, id = 2, plus = 3, minus = 4, times = 5, div = 6, mod = 7,
lp = 8, rp = 9, semico = 10, where = 11, and = 12, eq = 13;
int token;
char idval;
int numval;
private String line = "";
private BufferedReader buf;
Lexer()
{ buf = new BufferedReader(new InputStreamReader(System.in));
}
void init()
{ do
try
{ line = buf.readLine().trim();
}
catch(Exception e)
{ System.out.println("Error in input");
System.exit(1);
}
while (line.length()==0);
}
String getLine()
{ init();
return(line);
}
void getToken()
{ if (line.length()==0)
token = err;
else switch (line.charAt(0))
{ case '+':
token = plus;
line = line.substring(1).trim();
break;
case '-':
token = minus;
line = line.substring(1).trim();
break;
case '*':
token = times;
line = line.substring(1).trim();
break;
case '/':
token = div;
line = line.substring(1).trim();
break;
case '%':
token = mod;
line = line.substring(1).trim();
break;
case '(':
token = lp;
line = line.substring(1).trim();
break;
case ')':
token = rp;
line = line.substring(1).trim();
break;
case ';':
token = semico;
line = line.substring(1).trim();
break;
case '=':
token = eq;
line = line.substring(1).trim();
break;
default:
if (Character.isDigit(line.charAt(0)))
{ token = num;
numval = line.charAt(0) - '0';
int i = 1;
while (i<line.length()&&Character.isDigit(line.charAt(i)))
{ numval = numval*10+line.charAt(i)-'0';
i++;
}
line = line.substring(i).trim();
}
else if (Character.isLowerCase(line.charAt(0)))
{ char c = line.charAt(0);
if (c=='w' && line.length()>=5 && line.charAt(1)=='h' && line.charAt(2)=='e' && line.charAt(3)=='r' &&
line.charAt(4)=='e')
{ token = where;
line = line.substring(5).trim();
}
else if (c=='a' && line.length()>=3 && line.charAt(1)=='n' && line.charAt(2)=='d')
{ token = and;
line = line.substring(3).trim();
}
else if (line.length()>1 && Character.isLetter(line.charAt(1)))
{ token = err;
}
else
{ token = id;
idval = c;
line = line.substring(1).trim();
}
}
else
token = err;
}
}
}
Oh, long ago, that I made swing stuff.
In Test.main, if I replace
System.out.println(myTree.toPostfix(myTree));
TreeView view = new TreeView(myTree);
test.add(view);
view.repaint();
with:
System.out.println (myTree.toPostfix(myTree));
TreeView view = new TreeView(myTree);
test.add (view);
// view.repaint();
test.invalidate ();
I get a somehow splittet graph - probably a step to begin with.
4+2*3-9*4+2*3-9;
4 2 3 * + 9 4 * - 2 3 * + 9 -
But only after going to fullsize. Resizing demolates the graphic and the program hangs.
2 additional improvements, one critical, one user friendlyness:
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
should be added to the CTor
public Test() {
before setVisible, so you don't have to stop the Program with Ctrl-C. That was the critical one.
The second is in the lexer. If you test the input after trimming on line.endsWith (";"), you may add the semicolon silently yourself, instead of telling the user, what and how to do it.
Even better: Add a JTextField at BorderLayout (NORTH) or SOUTH, for the formula, so that the user may update it. For testing purpose it would be nice to prefill it.
Update
I meanwhile had fun, improving it, which might be mostly a question of taste and priorities, but maybe you're interested. And one step is most probably better, than the invalidate-command above.
here are the needed imports:
import javax.swing.*;
import java.awt.*;
import java.io.*;
import javax.swing.border.*;
Here the TestTreeView (I have way to much classes called 'Test'):
public class TestTreeView extends JFrame {
JTextField jtf = new JTextField (30);
JButton jb = new JButton ("go!");
public TestTreeView () {
setSize (900, 600); // a
Container cp = getContentPane (); // b
JPanel jp = new JPanel ();
jp.setLayout (new BorderLayout());
cp.add (jp);
jp.setBorder (BorderFactory.createEtchedBorder ()); // c
JPanel tp = new JPanel ();
tp.setLayout (new FlowLayout ());
tp.add (jtf);
jtf.setText ("1+2*3/4%5");
jtf.setFont ((jtf.getFont()).deriveFont (24.0f)); // I like big fonts, maybe need stronger glasses :)
tp.add (jb);
jp.add (tp, BorderLayout.NORTH);
actions (jp); // see below
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
setVisible (true);
}
public void actions (JPanel jp) {
jb.addActionListener (ae -> {
String s = jtf.getText ();
System.out.println (s);
if (s.length () > 1) {
//create parse trees from input in JTextField
Parser p = new Parser (s); // redefined, see below
ExpTree myTree;
try {
myTree = p.parseLine ();
System.out.println (myTree.toPostfix(myTree));
TreeView view = new TreeView (myTree);
jp.add (view, BorderLayout.CENTER);
// view.repaint();
// jp.invalidate ();
jp.revalidate (); // c
}
catch (ParseException e) {
System.out.println ("Invalid Expression: Ensure it ends with a semicolon");
}
}
});
}
public static void main (String[] args) {
TestTreeView test = new TestTreeView ();
}
}
Remarks:
a) I need more space, hence 900x600
b) At least to Java-1.5, you shouldn't add to the main Frame, but to the contentPane. Maybe it changed with 1.6, 1.7 or 1.8
c) revalidate is the way to go. Paints right up front, not just after first resize. This should apply, even if you don't like to use JTextField and button.
Parser found a new CTor, which expects a String, we pass from the JTextField:
class Parser
{
private Lexer lex;
public Parser()
{
lex = new Lexer();
}
public Parser (String s)
{
lex = new Lexer (s);
}
and Lexer found a new CTor, which expects a String, which is passed from the Parser:
class Lexer
void init()
{
do
try
{
line = buf.readLine ().trim ();
if (! line.endsWith (";"))
line = String.format ("%s;", line);
}
catch(Exception e)
{
System.out.println("Error in input");
System.exit (1);
}
while (line.length () == 0);
}
{
// ...
Lexer ()
{
buf = new BufferedReader (new InputStreamReader(System.in));
}
Lexer (String s)
{
buf = new BufferedReader (new StringReader (s));
}
// plus the automatic semicolon healing:
void init()
{
do
try
{
line = buf.readLine ().trim ();
if (! line.endsWith (";"))
line = String.format ("%s;", line);
}
catch(Exception e)
{
System.out.println("Error in input");
System.exit (1);
}
while (line.length () == 0);
}
Last famous words. In the net, there are a lot tutorials, how to detach the work of actions like in the ActionListener from the main event loop. You should consider working through such material. This code here is not state of the art. :)
I am programming a very basic bot for planet wars in java and I cant seem to find the errors in my code. I am receiving a few different error messages but the main issue for me is the error: class, interface, or enum expected. Ive checked my brackets about a thousand times. Any help would be appreciated. Here's my bot code:
import java.util.List;
import java.util.Random;
import shared.Planet;
import shared.PlanetWars;
public class MyNewBot {
public static void doTurn(PlanetWars pw) {
// (1) If we currently have a fleet in flight, then do nothing until
// it arrives.
if (pw.myFleets().size() >= 10) {
return;
}
// (2) Pick one of my planets based on the number of ships
Planet source = null;
int largestForce = 0;
for (Planet p : pw.myPlanets()){
int force = pw.numShips();
if( force > largestForce){
largestForce = force;
source = p;
}
}
// (3) Pick a target planet at random.
Planet dest = null;
int highestGrowthRate = 0;
int shortestDistance = 9999;
for (Planet p = pw.notMyPlanets()){
int growthRate = pw.growthRate();
if( growthRate > highestGrowthRate){
highestGrowthRate = growthRate;
dest = p;
}else if (growthRate == highestGrowthRate){
int distance = pw.distance(source,p);
if (distance < shortestDistance){
shortestDistance = distance;
dest = p;
}
}
}
// (4) Send half the ships from source to destination.
if (source != null && dest != null) {
int numShips = source.numShips() / 2;
pw.issueOrder(source, dest, numShips);
}
}
// Ignore the main method unless you know what you're doing.
// Refer to the doTurn function to code your bot.
public static void main(String[] args) {
String line = "";
String message = "";
int c;
try {
while ((c = System.in.read()) >= 0) {
switch (c) {
case '\n':
if (line.equals("go")) {
PlanetWars pw = new PlanetWars(message);
doTurn(pw);
pw.finishTurn();
message = "";
} else {
message += line + "\n";
}
line = "";
break;
default:
line += (char) c;
break;
}
}
} catch (Exception e) {
// Owned.
}
}
}
and the supporting class files:
package shared;
public class Planet implements Cloneable {
private int planetID;
private int owner;
private int numShips;
private int growthRate;
private double x, y;
public Planet(int planetID, int owner, int numShips, int growthRate,
double x, double y) {
this.planetID = planetID;
this.owner = owner;
this.numShips = numShips;
this.growthRate = growthRate;
this.x = x;
this.y = y;
}
public int planetID() {
return planetID;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int growthRate() {
return growthRate;
}
public double x() {
return x;
}
public double y() {
return y;
}
public void owner(int newOwner) {
this.owner = newOwner;
}
public void numShips(int newNumShips) {
this.numShips = newNumShips;
}
public void addShips(int amount) {
numShips += amount;
}
public void removeShips(int amount) {
numShips -= amount;
}
private Planet(Planet _p) {
planetID = _p.planetID;
owner = _p.owner;
numShips = _p.numShips;
growthRate = _p.growthRate;
x = _p.x;
y = _p.y;
}
public Object clone() {
return new Planet(this);
}
}
package shared;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
public class PlanetWars {
// Constructs a PlanetWars object instance, given a string containing a
// description of a game state.
public PlanetWars(String gameStateString) {
planets = new ArrayList<Planet>();
fleets = new ArrayList<Fleet>();
parseGameState(gameStateString);
}
// Returns the number of planets. Planets are numbered starting with 0.
public int numPlanets() {
return planets.size();
}
// Returns the planet with the given planet_id. There are NumPlanets()
// planets. They are numbered starting at 0.
public Planet getPlanet(int planetID) {
return planets.get(planetID);
}
// Returns the number of fleets.
public int numFleets() {
return fleets.size();
}
// Returns the fleet with the given fleet_id. Fleets are numbered starting
// with 0. There are NumFleets() fleets. fleet_id's are not consistent from
// one turn to the next.
public Fleet getFleet(int fleetID) {
return fleets.get(fleetID);
}
// Returns a list of all the planets.
public List<Planet> planets() {
return planets;
}
// Return a list of all the planets owned by the current player. By
// convention, the current player is always player number 1.
public List<Planet> myPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 1) {
r.add(p);
}
}
return r;
}
// Return a list of all neutral planets.
public List<Planet> neutralPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() == 0) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets owned by rival players. This excludes
// planets owned by the current player, as well as neutral planets.
public List<Planet> enemyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() >= 2) {
r.add(p);
}
}
return r;
}
// Return a list of all the planets that are not owned by the current
// player. This includes all enemy planets and neutral planets.
public List<Planet> notMyPlanets() {
List<Planet> r = new ArrayList<Planet>();
for (Planet p : planets) {
if (p.owner() != 1) {
r.add(p);
}
}
return r;
}
// Return a list of all the fleets.
public List<Fleet> fleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
r.add(f);
}
return r;
}
// Return a list of all the fleets owned by the current player.
public List<Fleet> myFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() == 1) {
r.add(f);
}
}
return r;
}
// Return a list of all the fleets owned by enemy players.
public List<Fleet> enemyFleets() {
List<Fleet> r = new ArrayList<Fleet>();
for (Fleet f : fleets) {
if (f.owner() != 1) {
r.add(f);
}
}
return r;
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(int sourcePlanet, int destinationPlanet) {
Planet source = planets.get(sourcePlanet);
Planet destination = planets.get(destinationPlanet);
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Returns the distance between two planets, rounded up to the next highest
// integer. This is the number of discrete time steps it takes to get
// between the two planets.
public int distance(Planet source, Planet destination) {
double dx = source.x() - destination.x();
double dy = source.y() - destination.y();
return (int) Math.ceil(Math.sqrt(dx * dx + dy * dy));
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(int sourcePlanet, int destinationPlanet, int
numShips) {
System.out.println("" + sourcePlanet + " " + destinationPlanet + " "
+ numShips);
System.out.flush();
}
// Sends an order to the game engine. An order is composed of a source
// planet number, a destination planet number, and a number of ships. A
// few things to keep in mind:
// * you can issue many orders per turn if you like.
// * the planets are numbered starting at zero, not one.
// * you must own the source planet. If you break this rule, the game
// engine kicks your bot out of the game instantly.
// * you can't move more ships than are currently on the source planet.
// * the ships will take a few turns to reach their destination. Travel
// is not instant. See the Distance() function for more info.
public void issueOrder(Planet source, Planet dest, int numShips) {
System.out.println("" + source.planetID() + " " + dest.planetID() + " "
+ numShips);
System.out.flush();
}
// Sends the game engine a message to let it know that we're done sending
// orders. This signifies the end of our turn.
public void finishTurn() {
System.out.println("go");
System.out.flush();
}
// Returns true if the named player owns at least one planet or fleet.
// Otherwise, the player is deemed to be dead and false is returned.
public boolean isAlive(int playerID) {
for (Planet p : planets) {
if (p.owner() == playerID) {
return true;
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
return true;
}
}
return false;
}
// If the game is not yet over (ie: at least two players have planets or
// fleets remaining), returns -1. If the game is over (ie: only one player
// is left) then that player's number is returned. If there are no
// remaining players, then the game is a draw and 0 is returned.
public int winner() {
Set<Integer> remainingPlayers = new TreeSet<Integer>();
for (Planet p : planets) {
remainingPlayers.add(p.owner());
}
for (Fleet f : fleets) {
remainingPlayers.add(f.owner());
}
switch (remainingPlayers.size()) {
case 0:
return 0;
case 1:
return ((Integer) remainingPlayers.toArray()[0]).intValue();
default:
return -1;
}
}
// Returns the number of ships that the current player has, either located
// on planets or in flight.
public int numShips(int playerID) {
int numShips = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
numShips += p.numShips();
}
}
for (Fleet f : fleets) {
if (f.owner() == playerID) {
numShips += f.numShips();
}
}
return numShips;
}
// Returns the production of the given player.
public int production(int playerID) {
int prod = 0;
for (Planet p : planets) {
if (p.owner() == playerID) {
prod += p.growthRate();
}
}
return prod;
}
// Parses a game state from a string. On success, returns 1. On failure,
// returns 0.
private int parseGameState(String s) {
planets.clear();
fleets.clear();
int planetID = 0;
String[] lines = s.split("\n");
for (int i = 0; i < lines.length; ++i) {
String line = lines[i];
int commentBegin = line.indexOf('#');
if (commentBegin >= 0) {
line = line.substring(0, commentBegin);
}
if (line.trim().length() == 0) {
continue;
}
String[] tokens = line.split(" ");
if (tokens.length == 0) {
continue;
}
if (tokens[0].equals("P")) {
if (tokens.length != 6) {
return 0;
}
double x = Double.parseDouble(tokens[1]);
double y = Double.parseDouble(tokens[2]);
int owner = Integer.parseInt(tokens[3]);
int numShips = Integer.parseInt(tokens[4]);
int growthRate = Integer.parseInt(tokens[5]);
Planet p = new Planet(planetID++, owner, numShips, growthRate,
x, y);
planets.add(p);
} else if (tokens[0].equals("F")) {
if (tokens.length != 7) {
return 0;
}
int owner = Integer.parseInt(tokens[1]);
int numShips = Integer.parseInt(tokens[2]);
int source = Integer.parseInt(tokens[3]);
int destination = Integer.parseInt(tokens[4]);
int totalTripLength = Integer.parseInt(tokens[5]);
int turnsRemaining = Integer.parseInt(tokens[6]);
Fleet f = new Fleet(owner, numShips, source, destination,
totalTripLength, turnsRemaining);
fleets.add(f);
} else {
return 0;
}
}
return 1;
}
// Store all the planets and fleets. OMG we wouldn't wanna lose all the
// planets and fleets, would we!?
private ArrayList<Planet> planets;
private ArrayList<Fleet> fleets;
}
package shared;
public class Fleet implements Comparable<Fleet>, Cloneable {
private int owner;
private int numShips;
private int sourcePlanet;
private int destinationPlanet;
private int totalTripLength;
private int turnsRemaining;
public Fleet(int owner, int numShips, int sourcePlanet,
int destinationPlanet, int totalTripLength, int turnsRemaining) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = sourcePlanet;
this.destinationPlanet = destinationPlanet;
this.totalTripLength = totalTripLength;
this.turnsRemaining = turnsRemaining;
}
public Fleet(int owner, int numShips) {
this.owner = owner;
this.numShips = numShips;
this.sourcePlanet = -1;
this.destinationPlanet = -1;
this.totalTripLength = -1;
this.turnsRemaining = -1;
}
public int owner() {
return owner;
}
public int numShips() {
return numShips;
}
public int sourcePlanet() {
return sourcePlanet;
}
public int destinationPlanet() {
return destinationPlanet;
}
public int totalTripLength() {
return totalTripLength;
}
public int turnsRemaining() {
return turnsRemaining;
}
public void removeShips(int amount) {
numShips -= amount;
}
// Subtracts one turn remaining. Call this function to make the fleet get
// one turn closer to its destination.
public void TimeStep() {
if (turnsRemaining > 0) {
--turnsRemaining;
} else {
turnsRemaining = 0;
}
}
#Override
public int compareTo(Fleet f) {
return this.numShips - f.numShips;
}
private Fleet(Fleet _f) {
owner = _f.owner;
numShips = _f.numShips;
sourcePlanet = _f.sourcePlanet;
destinationPlanet = _f.destinationPlanet;
totalTripLength = _f.totalTripLength;
turnsRemaining = _f.turnsRemaining;
}
public Object clone() {
return new Fleet(this);
}
}
for (Planet p = pw.notMyPlanets()){ should be for (Planet p : pw.notMyPlanets()){.
You've not posted the Fleet class, so as it is the code won't compile for me. However, the above is the only other error I could see.
I am making a tic tac toe program. The program needs to be able to determine a winner or a tie. I am using a "check" method and calling it after someone inputs their moves. I'm sure it's just syntax that I don't remember and can't find in the internet but I don't know how to return data from one method to another. Also is my ,logic right for finding a tie?
import javax.swing.JOptionPane;
public class tictactoe
{
public static void main(String args[])//coordinates = row:column
{
String grid[][] = new String [4][4];
int w = 0;
int j = 0;
int z = 1;
for(w = 1; w <= 3; w++)
{
for(j = 1; j <= 3; j++)
{
grid[w][j] = "[]";
}
}
JOptionPane.showMessageDialog(null,"WELCOME to Matt's Fun World of TIC TAC TOE");
JOptionPane.showMessageDialog(null, "Find the number of the box " + "\n" + "that you would like to enter you symbol." + "\n" +"DO NOT MAKE A MOVE YET!");
Board_Game(grid, w, j);
}
public static boolean Board_Game(String grid[][], int w, int j)
{
boolean test = false;
boolean done = false;
int player = 1;
while(!done)
{
String a = grid[1][1]; String b = grid[1][2]; String c = grid[1][3];
String d = grid[2][1]; String e = grid[2][2]; String f = grid[2][3];
String g = grid[3][1]; String h = grid[3][2]; String i = grid[3][3];
String board =
(" "+a+" | "+b+" | "+c+" " + "\n" +
"-------------|---------------|------------- " + "\n" +
" "+d+" | "+e+" | "+f+" " + "\n" +
"-------------|---------------|------------- " + "\n" +
" "+g+" | "+h+" | "+i+" " );
check(done, grid, a, b, c, d, e, f, g, h, i);
if(player % 2 != 0)//player 1
{
player++;
JOptionPane.showMessageDialog(null, board);
String r=JOptionPane.showInputDialog(" PLAYER 1" + "\n" +"Enter the row of your desired move.");
int row = Integer.parseInt(r);
String cm=JOptionPane.showInputDialog(" PLAYER 1" + "\n" +"Enter the column of your desired move.");
int column = Integer.parseInt(cm);
grid[row][column] = "X";
test = true;
check(done, grid, a, b, c, d, e, f, g, h, i);
boolean x = done;
}
else if(player % 2 == 0)//player 2
{
player++;
JOptionPane.showMessageDialog(null, board);
String rr=JOptionPane.showInputDialog(" PLAYER 2" + "\n" +"Enter the row of your desired move.");
int row2 = Integer.parseInt(rr);
String cc=JOptionPane.showInputDialog(" PLAYER 2" + "\n" +"Enter the column of your desired move.");
int column2 = Integer.parseInt(cc);
grid[row2][column2] = "O";
check(done, grid, a, b, c, d, e, f, g, h, i);
boolean x = done;
}
else if(test == true)
{
JOptionPane.showMessageDialog(null, "Player 1 is the winner!");
JOptionPane.showMessageDialog(null, board);
}
else if (test == false)
{
JOptionPane.showMessageDialog(null, "Player 2 is the winner!");
JOptionPane.showMessageDialog(null, board);
}
}
}
public static boolean check(boolean done, String grid[][], String a, String b, String c,String d, String e, String f, String g, String h, String i)
{
if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
else if(grid[1][1].equals(grid[1][2]) && b.equals(grid[1][3]))
{
done = true;
}
int y = 0;
for(int x = 1; x <= grid.length-1; x++)//FINDING A TIE
{
for(int z = 1; z <= grid.length-1; z++)
{
if(grid[x][z] .equals("[]"))
{
y++;
}
}
}
if(y == 0)
{
done = true;
}
else
{
done = false;
}
return Board_Game(done);//THIS IS WHERE I RETURN AND I DONT KNOW IF THE //SYNTAX IS RIGHT
}
}
To fix the issue with returning values, you could do this:
Change your method signature and let it return a boolean:
public static boolean check(String grid[][], String a, String b, String c,String d, String e, String f, String g, String h, String i) {
boolean done = false;
// ....
// do the checking now, and set done to true if its done ;-)
return done;
And then call your method like this:
done = check(grid, a, b, c, d, e, f, g, h, i);
I'm working on a method, that takes steps between 3 and -3. My program will not print out the steps in a numerical order, and I can't quite figure out how to do it, and I can't find anything elsewhere.
public static final int SENTINEL = Math.abs(3);
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Position = " + walk);
}
}
If that is what you are looking for :
int walk = 0;
int randomStep = 0;
Random rand = new Random();
while (Math.abs(walk) != 3) {
randomStep = rand.nextInt(2) > 0 ? 1 : -1; // -1 or 1 with 50% probability
walk += randomStep;
System.out.print(walk + " ");
}
//sample output: -1 -2 -1 0 1 2 1 2 3
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk += rand.nextInt(3) - 1;
if(walk>3) walk = 3;
if(walk<-3) walk = -3;
System.out.println("Position = " + walk);
}
}
I guess you want this.
while (walk != SENTINEL) {
int walk = 0;
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Walk is = " + walk);
int temp = walk;
if (walk >= -3) {
System.out.println("Wlak plus = " + (temp + 1));
System.out.println("Wlak minus =" + (temp - 1));
}
}
Could this be what you are looking for?
package com.stackoverflow.random;
import java.util.Random;
public class Walking {
private final int bounds;
public Walking(int bounds) {
this.bounds = bounds;
}
private boolean isWithinBounds(int walk) {
return Math.abs(walk) < bounds;
}
public String randomWalk() {
int walk = 0;
StringBuilder sb = new StringBuilder();
while(isWithinBounds(walk)) {
sb.append(walk);
walk = getNextStep(walk);
}
return sb.toString();
}
private Random random = null;
private int getNextStep(int walk) {
if (random == null)
random = new Random();
boolean increase = random.nextBoolean();
return increase?++walk:--walk;
}
public static void main(String[] args) {
Walking app = new Walking(3);
System.out.println("walking: " + app.randomWalk());
}
}