Java TicTacToe - comparing lots of values - java

I am writing this TicTacToe game. We all know how TicTacToe works, either somebody wins or nobody wins and the board gets full.
board.playable() checks to see if somebody has won the game or if the board is full. This code runs fine but I'm just wondering if there is a tidier way to write my while loop. It just seems a bit redundant to have the same condition twice. But I need to run the board.playable() check before the computer makes his move.
public void runGame()
{
while(board.playable()==true)
{
// Outputs a visual representation to console window
this.displayBoard();
// Asks player to enter a valid number
this.playerMove();
// Check if it still playable for the next
if(board.playable() == true)
{
computerMove()
}
}
this.displayBoard();
// Outputs the final status of the game and the winner if any
if(board.wonBoard()==true) {
System.out.println(board.whoWon() + " has won the game");
} else {
System.out.println("The board is full. Nobody has won the game");
}
}

Your program doesn't seem to have a "turn" state. If it had such an entity, then it could play a turn and check for winner after each turn. Also, get rid of == true in all of your code.
while (gameNotOver) {
// assuming an enum called Turn
if (turn == Turn.PLAYER) {
doPlayersTurn();
} else {
doComputerTurn();
}
checkForWin();
turn = turn.nextTurn();
}

while(board.playable())
{
// Outputs a visual representation to console window
this.displayBoard();
// Asks player to enter a valid number
this.playerMove();
// Check if it still playable for the next
if(board.playable())
{
computerMove();
}
}
remove ==true

You can use the flag to know whose move is : Like this
boolean playerTurn = Boolean.TRUE;
while(board.playable()==true)
{
// Outputs a visual representation to console window
this.displayBoard();
// Asks player to enter a valid number
if(playerTurn){
this.playerMove();
playerTurn=Boolean.FALSE;
}
else{
computerMove();
playerTurn = Boolean.TRUE;
}
}

Related

How to call upon and execute a method

I have a question that may be very basic, but I cant seem to find it on stack (and what I do find is very complicated) so I'm very sorry if it's already out there somewhere.
I'm writing a card game in java, and I want to move the piece of code that draws a new card into a separate method, so that I may call on it whenever, instead of having the same piece of code appear again and again whenever I need it.
The only problem is I don't know what type of method to use or how to call on it, since it's not going to return anything, just do a bunch of code.
Here is the piece of my code that draws a card, if that helps to show what I'm aiming to do.
if (event.getSource() == hit && endOfRound == false) {
Continue = true;
while (Continue == true) //If the random number has been drawn before, loop the random number generator again
{
cardID = (int) RandomNumber.GetRandomNumber(52);
if (cardsLeft[cardID] == true) //If a new card is drawn, continue normally
{
Continue = false; //Stop the loop that draws a new card
cardsLeft[cardID] = false; //save that the card was drawn
stay.setBackground(Color.green);
plyrSum += BlackJack.value(cardID); //add value to sum
plyrSumLabel.setText("Your sum: " + plyrSum); //display new sum
cardLabel[plyrCardCounter].setIcon(cardImage[cardID]); //Display card
plyrCardCounter++;
if (cardID >= 48) //record how many aces are in the hand so the program knows how many times it can reduce the sum.
plyrAceCounter++;
while (plyrSum > 21 && plyrAceCounter > 0) //If bust, reduce the value of an ace by 10 (from 11 to 1).
{
plyrSum -= 10;
plyrSumLabel.setText("Your sum: " + plyrSum);
plyrAceCounter--;
}
if (plyrSum > 21) //Automatically end the round if someone busts (player)
{
stay.doClick();
}
}
}
}
Declare a method drawCard() that returns void. Now copy the block inside if and paste it inside the method.
Then rewrite the if part:
if (event.getSource() == hit && endOfRound == false) drawCard();

Why does nothing happen when a "if ... <=0" criteria is met?

I have a player controlled object which is set to 100 health. With each hit from an enemy it goes down. The problem is, after it reaches 0 health, it still keeps going further into the negatives. I have a popup set
private void playerHealth(){
if (player.health <= 0)
JOptionPane.showMessageDialog(null, "you lose");
System.exit(0);
}
so that in theory, it should pop up after health is <=0. However, when I try to run it, it just opens and closes immediately. I can see the window for a split second. If I delete the
JOptionPane.showMessageDialog(null, "you lose");
System.exit(0);
and replace it with say,
player.isAlive = false;
(isAlive is set true for player, enemies and all bullets), the health will continue to decrease past the negatives.
This part might help as well: Its the code to delete the dead enemies and bullets, there is nothing similar for player, so that may be the problem.
private void removeDead(){
for (int i = 0; i <bullets.size(); i++){
if (bullets.get(i).isAlive == false )
bullets.remove(i);
}
for (int i = 0; i <mobs.size(); i++){
if (mobs.get(i).isAlive == false )
mobs.remove(i);
}
for (int i = 0; i <mobBullets.size(); i++){
if (mobBullets.get(i).isAlive == false )
mobBullets.remove(i);
}
bullets.trimToSize();
mobs.trimToSize();
mobBullets.trimToSize();
}
So any help is appreciated. Thank you. (all the code is from an online tutorial, which is why I dont know anything.)
If you want both statements to be executed, surround them in a block :
private void playerHealth() {
if (player.health <= 0) {
JOptionPane.showMessageDialog(null, "you lose");
System.exit(0);
}
}
Without the curly braces, System.exit(0); is not part of the if statement and will always be executed, which explains the it just opens and closes immediately.
I agree with the previous answer.
However, you need to know how to avoid such problems in the future. Use an IDE or other editor that will automatically indent your code for you. Here is what one did to the failing if-statement:
private void playerHealth() {
if (player.health <= 0)
JOptionPane.showMessageDialog(null, "you lose");
System.exit(0);
}
The problem becomes much more obvious.
It looks like you missed a { on your if statement, if you want to execute a block of code in an if statement you need to do
if(something){
response;
}
So it should be this:
private void playerHealth() {
if (player.health <= 0) {
JOptionPane.showMessageDialog(null, "you lose");
System.exit(0);
}
}

My Java code wont spawn the next wave?

So I am making a game where there are waves of enemies. The Wave class contains an update method that updates all the enemies in an arraylist of enemies contained in the Wave class. The Wave class also has a boolean called beat that decides whether or not the player has beaten the current wave. I am now have been trying however to start the next wave after the player beats the first. All waves in the arraylist start out with their beat variable as true except for the first. There are currently only two waves. I do not know why this is not working. Thank You for any help.
for(int i = 0; i < 1;i++)
{
if(!w.get(i).beat)
w.get(i).update(g2d);
else if(w.get(i).beat)
{
if(i-1 != -1)
{
if(w.get(i-1).beat && w.get(i).beat)
{
w.get(i).beat = false;
}
}
}
}
Your loop will increment i to the next wave after setting the current wave's beat setting to false, and miss calling the update method for that case. It looks like you should either call its update method immediately after setting beat = false, or perform the if test in the opposite order like this:
for(int i = 0; i < numWaves;i++) // upper range should be the number of waves
{
if(w.get(i).beat)
{
if(i>0) // this can be simplified to "if (i>0)"
{
if(w.get(i-1).beat) // no need to check w.get(i).beat here
{
w.get(i).beat = false;
}
}
}
else
w.get(i).update(g2d);
}
I don't know why you'd initialize a wave's beat state to true then set it to false when its turn comes. Why not just initialize all to false since they really haven't been beat yet?
I'm not sure that I understand your code but I can tell you 2 things. First of all, your loop never loops because as soon as the index is 1, it ends without executing the code a second time. Secondly
if(i-1 != -1)
{
if(w.get(i-1).beat && w.get(i).beat)
{
w.get(i).beat = false;
}
}
is always false due to what I said.

while loop not ending when required

So some background information, I'm new to programming and am still learning, so I apologize for my trivial error making. I am making my own text based game just to further practice etc.
Here is the link to everything on dropbox for more context:
https://www.dropbox.com/sh/uxy7vafzt3fwikf/B-FQ3VXfsR
I am currently trying to implement the combat system for my game, and I am running into the issue of the combat sequence not ending when required. The 'combat sequence' is a while loop as follows:
public void startCombat()
{
inCombat = true;
while(inCombat != false)// && herohealth > 0 && monsterhealth > 0)
{
checkAlive();
heroHitMonster();
checkAlive();
monsterHitHero();
}
attackinghero.setHeroHealth(herohealth);
attackedmonster.setMonsterHealth(monsterhealth);
}
where the checkAlive() method is as follows:
public void checkAlive()
{
if(herohealth <= 0)
{
System.out.println("You have died.");
attackinghero.clearInventory();
inCombat = false;
}
else if(monsterhealth <= 0)
{
System.out.println("You have killed the "+attackedmonster.getmonsterName()+"!");
inCombat = false;
combatlocation.removeMonster(attackedmonster.getmonsterName());
}
else
{
//
}
}
I am trying to get it to end the combat sequence when either the 'hero' or 'monster' health become <= 0,
however it is currently finishing the while loop and therefore producing the result of the hero being hit even if he killed the monster in his first hit.
This is what is currently being 'printed to screen'
rat loses 5 health!
You have killed the rat!
Hero loses 1 health!
Any help is much appreciated, thanks in advance.
checkAlive shouldn't be void it should be Boolean and should return inCombat, and in your function startCombat you should do inCombat=checkAlive();
The while loop will only evaluate after both actions. You need a way to break the loop after the hero hits the monster. I would personally change the checkAlive method to return a boolean, and put the hit methods in if statements in the while loop:
if(checkAlive())
{
heroHitMonster();
}
if(checkAlive())
{
monsterHitHero();
}
You should end the loop at the end of the checkAlive instead of changing the boolean value.
If you killed the monster at first hit, you still execute the monsterHitHero() even, if the monster is killed. The function to hit should be conditioned to the life of heroes/monster.

Input only working once in Android

A question (ID 1606993) like this was posted, but didn't really answer mine, so here goes:
In an app for Android that I am creating, the user must input numbers from the keypad for the app to continue. When they are done entering their numbers, they can either press the return key or the main button. Problem is, its only working once.
Here is my listening method:
public boolean onKeyDown(int key, KeyEvent event)//Listens for key events
{
if(key==KeyEvent.KEYCODE_0)
add(0);
else if(key==KeyEvent.KEYCODE_1)
add(1);
else if(key==KeyEvent.KEYCODE_2)
add(2);
else if(key==KeyEvent.KEYCODE_3)
add(3);
else if(key==KeyEvent.KEYCODE_4)
add(4);
else if(key==KeyEvent.KEYCODE_5)
add(5);
else if(key==KeyEvent.KEYCODE_6)
add(6);
else if(key==KeyEvent.KEYCODE_7)
add(7);
else if(key==KeyEvent.KEYCODE_8)
add(8);
else if(key==KeyEvent.KEYCODE_9)
add(9);
else if(key==KeyEvent.KEYCODE_ENTER)
setNum();
else if(key==KeyEvent.KEYCODE_DPAD_CENTER)
setNum();
return true;
}
The add(int numb) method adds num to the text field that takes up the screen, its not causing any problems.
Here is setNum() :
protected void setNum()//Sets the number and tells the Runner it is set.
{
if(ray.size()==1)
num=ray.get(0);
else if(ray.size()==0)
num=0;
else
num=(ray.get(0)*10)+ray.get(1);
ray=new ArrayList<Integer>();//or ray.clear(), I've tried both
ready=true;
}
ArryayList ray is where the numbers are stored. The computation is working fine.
Int num is the number that the code uses. Boolean ready is there because in the runner class there is a while loop waiting for ready to be true to continue the code.
while(!a.ready)
{
for(int x=0;x<100;x++);
}
Any ideas?
Edit: Here is the method in Runner that is called:
while(!go)
{
addText("It is White's move");
addText("Possible pieces to move");
for(int x=0;x<b.getWhite().getPiecesWithMoves(b).size();x++)//Loop to print White's pieces that can move
{
addText(""+(x+1)+") "+b.getWhite().getPiecesWithMoves(b).get(x));
}
got=false;
p=0;
while(!got)//Loop to enter number
{
addText("Input the number of the piece you want to move");
while(!a.ready)
{
for(int x=0;x<100;x++);
}
p=a.num-1;
if(p<b.getWhite().getPiecesWithMoves(b).size()&&p>=0)//Checks to make sure that p is valid
got=true;
a.num=0;
a.ready=false;
}
gl=b.getWhite().getPiecesWithMoves(b).get(p).getLocation();//Makes a location that is where the piece currently is
addText("Possible moves");
for(int x=0;x<b.getPiece(gl).getMoves(b).size();x++)//Loop to print where the piece can go
{
addText(""+(x+1)+") "+b.genL(b.getPiece(gl).getMoves(b).get(x)));
}
got=false;//reset
while(!got)//Loop to enter number
{
addText("Input the number of one of these moves.");
addText("If you wish to change, enter 0.");
while(!a.ready)
{
for(int x=0;x<100;x++);
}
p=a.num-1;
if(p==-1)
got=true;
else if(p<b.getPiece(gl).getMoves(b).size()&&p>=0)//Checks to make sure that p is valid
{
got=true;
go=true;
}
a.num=0;
a.ready=false;
}
}
gk=b.getPiece(gl).getMoves(b).get(p);//The location that the piece is going to
b.move(gk, b.getPiece(gl),gk.isTaken(),gk.isCastle());//Moves the piece
public class MyView {
int num;
int currentState = 1; //much, much more pretty if you'd use Enum,
//but I'll keep it simple now.
public boolean onKeyDown(int key, KeyEvent event) {
//no changes here
}
protected void setNum(){
if(ray.size()==1)
num=ray.get(0);
else if(ray.size()==0)
num=0;
else
num=(ray.get(0)*10)+ray.get(1);
ray=new ArrayList<Integer>();
if (currentState == 1) //(TODO:should really use Enum here....)
part1();
else if (currentState == 2)
part2();
else if (...
}
void part1() {
addText("It is White's move");
addText("Possible pieces to move");
for(int x=0;x<b.getWhite().getPiecesWithMoves(b).size();x++)
{
addText(""+(x+1)+") "+b.getWhite().getPiecesWithMoves(b).get(x));
}
addText("Input the number of the piece you want to move");
currentState = 2;//now we do nothing, we wait untill user finishes input
}
void part2()
{//will be called after part1 finishes and a number has been entered
p=a.num-1;
if(p<b.getWhite().getPiecesWithMoves(b).size()&&p>=0) {
gl=b.getWhite().getPiecesWithMoves(b).get(p).getLocation();
addText("Possible moves");
//and more code
//Need input? stop and set next entry point
currentState = 3;//continue to part 3
}
else
{
addText("Input the number of the piece you want to move");
currentState = 2;//oops, stay at part2, we didn't get a good number!
}
}
}
The idea is to do nothing when the user has to input. There is no code running at that moment, for example after part1() finishes. When the user finishes input and presses a key, you have to make sure the correct code then executes, part2 gets called then. And then just stop running code when you need input again.
Good luck!

Categories

Resources