How to make if chains - actionscript-3

I am making a game for my assignment in AS3.0 and this isn't working.
All the variables and buttons are defined, I get no error but it just dose not function :
frame 2 layer 1
function CheckScene():void
{
P_HP = 5
E_HP = 1
A_D = 1
if(P_HP == 5)
if(E_HP == 2)
if(A_D == 1)
q = 1
if(P_HP == 5)
if(E_HP == 1)
if(A_D == 1)
q = 2
}
frame 2 layer 2
stop();
but.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame);
function fl_ClickToGoToAndStopAtFrame(event:MouseEvent):void
{
gotoAndStop(5);
}
frame 3 layer 2
button_2.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_2);
function fl_ClickToGoToAndStopAtFrame_2(event:MouseEvent):void
{
if(q == 1)
gotoAndStop(5)
if(q == 2)
gotoAndStop(4)
}
Basically it goes to frame 4 if it works, or 5 if it doesn't. The if chain isn't working. I have no clue how to do this because this sort of thing works in excel (for checking multiple variables before execution).

See comments for help and explanation:
//use naming conventions : methods start with lower-case.
//fix method signature
private void checkScene()
{
//declare all variables
//use naming conventions : variables start with lower-case.
int p_HP = 5; // ; at the end of every statement
int e_HP = 1;
int a_D = 1;
int q = 0;
if(p_HP == 5) {
if(e_HP == 2) {
if(a_D == 1) {
q = 1;
}
}
}
//you could use an equivalent and shorter format:
//if( p_HP==5 && e_HP==2 && a_D==1) q=1;
if(p_HP == 5) {
if(e_HP == 1) {
if(a_D == 1) {
q = 2;
}
}
}
//you could use an equivalent and shorter format:
// if( p_HP==5 && e_HP==1 && a_D==1) q=2;
//add printout to check the result
System.out.println("q is "+q);
}
For future questions pleas post an MCVE

Related

Misunderstanding of the OOP in a chess game design in java

I've a problem with code that I'm writing to practice my java skills.
I'm trying to write a chess game. Anyway, in my project I have a class called ChessGUI which contains the GUI and the methods I need to play (multiplayer). I'm willing to change the code later to a MVC pattern so it can be easier to read/edit/understand.
I've an abstract class called Figure and i extended it in 12 classes (6 figures per color):
However in my ChessGui class I have a method called CheckAvailableSquares() which I call whenever a piece on the board has been selected (by a mouse click) to show me on the board the available squares which I can move my selected piece to.
private void CheckAvailableSquares(Figure figure){
for (int row = 0; row < 8; row++){
for (int col = 0; col < 8; col++){
if (row == figure.getRowPos() && col == figure.getColPos()) //bypass the actual square where my piece stands
continue;
if (figure.isValidMove(board,figure.getRowPos(), figure.getColPos(),row,col)){
board[row][col].setBackground(Color.GREEN);
}
}
}
}
In every figure sub-class there is a method called isValidMove() which becomes the current position of the piece and the wanted position and return a boolean value if the move is valid.
As you know the pawn can move 2 squares per time on it's first move, that's why I added a boolean attribute to the classes WhitePawn&BlackPawn called firstMovePlayed. It has the false value and whenever the isMoveValid() method is called and the wanted move is valid it should be changed to true. like that:
public class WhitePawn extends Figure {
private boolean firstMovePlayed = false;
public WhitePawn(){
super.setColor(Color.WHITE);
}
#Override
public boolean isValidMove(Square[][] board, int currentRow, int currentCol, int wantedRow, int wantedCol){
int rowDelta = currentRow - wantedRow; //no Math.abs because a pawn can't move backwards.
int colDelta = Math.abs(wantedCol - currentCol);
//if we have an own piece on the wanted square
if (!board[wantedRow][wantedCol].isEmpty() && board[wantedRow][wantedCol].getFigure().getColor().equals(Color.WHITE)) {
return false;
}
//on the first move a pawn can move 2 square at a time, and when moving 2 square he can't capture. A pawn can't move two square if there is another piece in the way. TODO: en passant ??????
if (rowDelta == 2 && colDelta == 0 && board[wantedRow][wantedCol].isEmpty() && board[wantedRow + 1][wantedCol].isEmpty() && !firstMovePlayed) {
firstMovePlayed = true;
return true;
}
else if (rowDelta == 1 && colDelta == 1 && !board[wantedRow][wantedCol].isEmpty()) { //capture
if (board[wantedRow][wantedCol].getFigure().getColor() != board[currentRow][currentCol].getFigure().getColor())
firstMovePlayed = true;
return true;
}
else if (rowDelta == 1 && colDelta == 0 && board[wantedRow][wantedCol].isEmpty()) { //moving one square forward without a capture
firstMovePlayed = true;
return true;
}
//those were the only possibilities to move a pawn
return false;
}}
The problem is:
whenever I call the method CheckAvailableSquares() to check the availability of the squares the firstMovePlayed boolean will be set to true!!
I'm really sorry for taking too long of your time but I really can't figure it out :/
here is the rest of the relevant code from ChessGui class:
public void actionPerformed(ActionEvent e) {
//looking for the square which fired the ActionListener:
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j++){
if(board[i][j] == e.getSource()){
processClick(i, j);
}
}
}
}
private void processClick(int i, int j){
if(bufRow == 99 && bufCol == 99){ //select a figure to move and wait for the next click
if (board[i][j].isEmpty()) { //if there is no figure on the square that has benn clicked
System.out.println("no Figures on this square");
return;
}
else {//save the chosen square (button) in buffers so that we can move it later.
//decide who's turn it is:
if (board[i][j].getFigure().getColor().equals(Color.WHITE) && !whiteToPlay)
System.out.println("It's black's turn to play!");
else if (board[i][j].getFigure().getColor().equals(Color.BLACK) && !blackToPlay)
System.out.println("It's white's turn to play!");
if ((board[i][j].getFigure().getColor().equals(Color.WHITE) && whiteToPlay) || board[i][j].getFigure().getColor().equals(Color.BLACK) && blackToPlay) {
board[i][j].setHighleightedIcon(board[i][j].getFigure().getHilightedIcon()); //change the icon of the chosen square
bufRow = i; //save the chosen figure to move it later
bufCol = j;
System.out.println("Selectd figure on Raw: " + bufRow + " Column: " + bufCol);
switchTurns();
CheckAvailableSquares(board[bufRow][bufCol].getFigure());
}
}
}
else
moveFigure(i, j);
}
private void moveFigure(int wantedRow, int wantedCol) {
if (board[bufRow][bufCol].getFigure().isValidMove(board, bufRow, bufCol, wantedRow, wantedCol)) { // check if the move is valid for the figure
// if (board[wantedRow][wantedCol].isEmpty()) { //if the wanted square is empty (not a capture)
//move the figure to the wanted square after deleting it from the old square
board[wantedRow][wantedCol].setFigure(board[bufRow][bufCol].getFigure());
board[wantedRow][wantedCol].setSquareIcon(board[bufRow][bufCol].getFigure().getIcon());
board[bufRow][bufCol].emptySquare();
//update the location of the piece
board[wantedRow][wantedCol].getFigure().setNewPos(wantedRow,wantedCol);
System.out.println("Moved [" + bufRow + ", " + bufCol + "] To: [" + wantedRow + ", " + wantedCol + "].");
//reset the buffers
bufRow = 99;
bufCol = 99;
resetSquaresColors();
/*}
else if (!board[wantedRow][wantedCol].isEmpty()){ //if it's a capture
if(board[wantedRow][wantedCol].getFigure().getColor() != board[bufRow][bufCol].getFigure().getColor()) { //can't capture own pieces!
board[wantedRow][wantedCol].setFigure(board[bufRow][bufCol].getFigure());
board[wantedRow][wantedCol].setSquareIcon(board[wantedRow][wantedCol].getFigure().getIcon());
board[bufRow][bufCol].emptySquare();
//update the location of the piece
board[wantedRow][wantedCol].getFigure().setRowPos(wantedRow);
board[wantedRow][wantedCol].getFigure().setColPos(wantedCol);
System.out.println("Moved [" + bufRow + ", " + bufCol + "] To: [" + wantedRow + ", " + wantedCol + "].");
//reset the buffers
bufRow = 99;
bufCol = 99;
}
}*/
} else { //if it's not a valid move
board[bufRow][bufCol].setIcon(board[bufRow][bufCol].getFigure().getIcon());
//reset the buffers
bufRow = 99;
bufCol = 99;
resetSquaresColors();
System.out.println("Not a valid move");
switchTurns();
}
}
private void CheckAvailableSquares(Figure figure){
for (int row = 0; row < 8; row++){
for (int col = 0; col < 8; col++){
if (row == figure.getRowPos() && col == figure.getColPos()) //bypass the actual square where my piece stands
continue;
if (figure.isValidMove(board,figure.getRowPos(), figure.getColPos(),row,col)){
Square sqr = board[row][col];
if (sqr.isEmpty()) //if the square is empty
sqr.setAvailableIcon(new ImageIcon("Icons/available_square.png"));
else //if there is a piece on the square
sqr.setAvailableIcon(sqr.getFigure().getAvailableIcon());
}
}
}
}
Thanks alot & forgive any mistakes in my poor English!

ActionScript 3 Scoring/Math

I've been attempting to implement a score inside of a game that I'm creating in AS3. So far, I've managed to create a score system that adds/subtracts points based on actions in-game. I've decided that it'd be simpler to have the scoring system just add points instead of subtract them and on reaching a certain number, end the game.
The problem I'm having is that on the one hand, the game is performing checks to see if the pieces are in the right place. If they are, the player wins. On the other, the counter needs to count and reach a certain number (10) before deciding the player loses. At the moment there's some weird behaviour going on where I'm able to drag the pieces around without putting them in their right place and the counter still goes over 10. I've tried a few variations of changing the math so that it totals differently, but the functionality is the same. What would I have to change so that it would behave as first described?
stop();
//Create the score counter
import flash.text.TextField;
var score = 0;
scorecounter.text = score;
function init(): void
{
score = 0;
scorecounter.text = "SCORE:" + score.toString();
}
function updateScore(): void
{
scorecounter.text = ++score;
}
function evaluateScore(): void //this is meant to stop the score going below 0
{
scorecounter.text = --score;
if(score < 0) {
score -= score;
}
}
/*Omitted some functions and var's for object positions and events*/
function stopDragging(e:MouseEvent):void {
e.currentTarget.stopDrag();
switch (e.currentTarget){
case apple:
if (apple.x < appleEndX - offset || apple.x > appleEndX + offset ||
apple.y < appleEndY - offset || apple.y > appleEndY + offset) {
apple.x = appleStartX;
apple.y = appleStartY;
soundOne();
updateScore();
} else {
apple.x = appleEndX;
apple.y = appleEndY;
soundTwo();
updateScore();
checkGame();
}
break;
//Lots of other cases, using the same method
//The end of the game - here, I've been trying to set it to
//check whether the player will win or lose
}
}
function checkGame(): void {
if (apple.x == appleEndX && apple.y == appleEndY && pear.x == pearEndX &&
pear.y == pearEndY && guava.x == guavaEndX && guava.y == guavaEndY &&
pineapple.x == pineappleEndX && pineapple.y == pineappleEndY &&
plum.x == plumEndX && plum.y == plumEndY &&
purple.x == purpleEndX && purple.y == purpleEndY)
{
trace("You win!");
gotoAndStop(149);
soundFive();
} else if (score == 10) {
gotoAndStop(150);
soundSix();
trace("You lose.");
}
}
I think that the logic is a little confusing, but as I understand it from your code, the idea is to move a drag-gable item to the correct x,y position, with a tolerance of "offset"? The aim is to to this with the lowest possible "score" (or number of moves) and if the number of moves (score) is greater than 10 then you lose the game?
Currently the only place that checks to see if you have made 10 moves is "checkGame" and this method is only called if your "apple" is correctly positioned. If it is incorrectly positioned then the number of moves is incremented, but the score is not checked. So when you finally get to "checkGame" but correctly positioning the "apple" the score could already be greater than 10. So your "score == 10" check will fail also.
So what you need is to check the game on every move with something like this:
function stopDragging(e:MouseEvent):void {
...
switch (e.currentTarget){
case apple:
if (apple.x < appleEndX - offset || apple.x > appleEndX + offset ||
apple.y < appleEndY - offset || apple.y > appleEndY + offset) {
apple.x = appleStartX;
apple.y = appleStartY;
soundOne();
} else {
apple.x = appleEndX;
apple.y = appleEndY;
soundTwo();
}
break;
...
}
//Check the game on every turn.
checkGame();
}
function checkGame(){
//Update the score
score++;
if (apple.x == appleEndX && apple.y == appleEndY && pear.x == pearEndX &&
pear.y == pearEndY && guava.x == guavaEndX && guava.y == guavaEndY &&
pineapple.x == pineappleEndX && pineapple.y == pineappleEndY &&
plum.x == plumEndX && plum.y == plumEndY &&
purple.x == purpleEndX && purple.y == purpleEndY)
{
//Do the game win.
}
else if (score>=10)
{
//Else if you have a score greater then or equal to 10 do the game lose.
}
}

actionscript break if statement to check next one

I'm making a bot for a simple tic tac toe game. Here is the problem, at botCheck function, when row 0 col 0 and row 0 col 1 is "O", then the "X" appear at the row 0 col 2, and when I tried to make another combination of "O" (ex. row 0 col 0 and row 1 col 1), it should check at different if statement, but my code seems to still check only at the first if statement which will keep tracing ("D") and stuck at that part.
So here is the question, at else{trace("D");} , is there any code that I can replace with to skip the first if statement and go to the second one so it can check for the other combinations of "O" ?
P.S. I've tried to use continue; but it only goes to the next loop and still stuck at the first if statement.
Thanks!
package
{
public class Bot
{
private var n:int = 0;
private var rndm:int;
private var v:int;//vertical
private var h:int;//horizontal
private var moving:Boolean = false;;
private var _main:Main;
public function Bot(main:Main):void
{
_main = main;
}
private function randomNumber(min:Number, max:Number):Number
{
return Math.floor(Math.random()*(1+max-min)+min);
}
public function botMove():void
{
botCheck();
if(n == 0 && moving == false)
{
rndm = randomNumber(0,2);
v = rndm;
rndm = randomNumber(0,2);
h = rndm;
if(_main.squareArray[v][h] == 0)
{
_main.squareArray[v][h] = 1;
_main.xoArray[v][h].push(_main.xo);
moving = true;
fillX();
n = 0;
_main.xo = "O";
}
else
{
botMove();
}
}
if(n == 1 && moving == false)
{
if(_main.squareArray[v][h] == 0)
{
_main.squareArray[v][h] = 1;
_main.xoArray[v][h].push(_main.xo);
moving = true;
fillX();
n = 0;
_main.xo = "O";
}
}
}
private function fillX():void
{
_main.x_ = new X ;
_main.xoContainer.addChild(_main.x_);
_main.x_.x = _main.gameWidth / _main.lebar *(1+(h))+ _main.gameWidth/(_main.lebar*4);
_main.x_.y = _main.gameHeight / _main.panjang * (1+(v))+_main.gameHeight/(_main.panjang*4);
_main.x_.width = _main.square.width / 2;
_main.x_.height = _main.square.height / 2;
}
private function botCheck():void
{
for(var a:int = 0; a<_main.panjang;a++)
{
if(n != 0)
{
break;
}
for(var b:int = 0;b<_main.lebar;b++)
{
if(_main.xoArray[a][b]=="O" && _main.xoArray[a][b+1] == "O")
{
if(b+2 < _main.lebar && _main.xoArray[a][b+2] == 0)
{
n = 1;
v = a;
h = b+2;
moving = false;
break;
}
else if(_main.xoArray[a][b-1] == 0)
{
n = 1;
v = a;
h = b-1;
moving = false;
break;
}
else
{
trace("D");
}
}
else if(_main.xoArray[a][b] == "O" && _main.xoArray[a+1][b] =="O")
{
if(a+2 < _main.panjang && _main.xoArray[a+2][b] == 0)
{
n = 1;
v = a+2;
h = b;
moving = false;
break;
}
else if(a != 0)
{
if(_main.xoArray[a-1][b] == 0)
{
n = 1;
v = a-1;
h = b;
moving = false;
break;
}
}
else
{
}
}
else if(_main.xoArray[a][b]=="O" && _main.xoArray[a+1][b+1] == "O")
{trace("B");
if(a+2 < _main.panjang && b+2 < _main.lebar && _main.xoArray[a+2][b+2] == 0)
{
n = 1;
v = a+2;
h = b+2;
moving = false;
break;
}
else if(a != 0)
{
if(_main.xoArray[a-1][b-1] == 0)
{
n = 1;
v = a-1;
h = b-1;
moving = false;
break;
}
}
else
{
}
}
else if(_main.xoArray[a][b+2]=="O" && _main.xoArray[a+1][b+1] == "O")
{trace("A");
if(a+2 < _main.lebar && _main.xoArray[a+2][b] == 0)
{
n = 1;
v = a+2;
h = b;
moving = false;
break;
}
}
else if(_main.xoArray[a][b] == "O" && _main.xoArray[a+1][b-1] == "O")
{
if(a != 0 && b+1 < _main.lebar && _main.xoArray[a-1][b+1] == 0)
{
n = 1;
v = a-1;
h = b+1;
moving = false;
break;
}
}
else
{
n = 0;
moving = false;
}
}
}
}
}
}
If you would like to check through all the if statements within the for loop, simply remove the "else"s from the other if statements.
Thus, your first if statement is fine, but the next if statement would go from
else if(_main.xoArray[a][b] == "O" && _main.xoArray[a+1][b] =="O")
to simply
if(_main.xoArray[a][b] == "O" && _main.xoArray[a+1][b] =="O")
(just omitting the else).
Repeat that for all of the other outermost "else if"'s in your loop.
Now, I see at the bottom you have a final "else" that sets n to 0 and moving to false. If you make the changes listed above, you may remove that else block, and instead put those statements in the else block (n = 0; moving = false) at the very beginning of the for loop. Therefore, unless any of the if statements are triggered, n will equal 0 and moving will equal false, which is the intended result.
You can also get rid of all of the empty else {} blocks within the for loop; they don't contribute anything anyway. Let me know if you have any questions :)

Flash AS3 - Timer goes crazy after a few loops

I've been making a "slideshow" where 4 images are animated in random order.
To prevent multiple animations to one image for example 3 times successively, I've write a little logic.
My problem : after a few times all the 4 images are animated (after the query 'array' is cleared the second time I think), the timer goes crazy and trace() random numbers in a high sequence rate without to animate the images, with would look creepy I think.
My code :
var myTimer:Timer = new Timer(2500);
myTimer.addEventListener(TimerEvent.TIMER, animate);
myTimer.start();
var array:Array = new Array();
var lastNum:int;
function animate(e:TimerEvent):void {
var num:int = getRandomNumber( 1, 4 );
trace( num );
if( array.indexOf( num ) < 0 && num != lastNum ) {
myTimer.delay = 2500;
if( num == 1 ) {
sideImg_start_1.play(); // comment this*
} else if( num == 2 ) {
sideImg_start_2.play(); // comment this*
} else if( num == 3 ) {
sideImg_start_3.play(); // comment this*
} else if( num == 4 ) {
sideImg_start_4.play(); // comment this*
}
array.push( num );
if( array.length == 4 ) {
array.splice(0, 4);
trace(" array cleared - " + array.length);
lastNum = num;
}
} else {
myTimer.delay = 100; // I've also tryed so make a higher delay
// like 500 but its the same problem...
}
}
function getRandomNumber( min:int, max:int ):int {
return Math.floor( Math.random() * ( 1 + max - min ) ) + min;
}
stop();
So guys, thanks for all your answers and your help :D
UPDATE:
First I've tried to simply call the 'animate()' function instead of defining a higher speed to the timer to call the next number fast, without to loose time, which would make the random animation look weird.
I've used animate(null); instead of myTimer.delay = 100; before, but then I was getting a STACKOVERFLOW error :P
For example if your lastNum is equal to 4, and you have 1,2 and 3 as new values, than you will end up with an infinite loop,
because you can't insert 4 (because it's equal to the lastNum) and you can't insert 1,2 or 3 because they are already in the array.
What you need to do is:
if (array.length == 4) {
array.splice(0, 4);
lastNum = num;
} else {
lastNum = 0; //<-- HERE
}

AS3: Large number of timers lagging flash

I have a large number of objects (472) that require a timer used to check how long it takes between state changes of a variable. The code below is what I have so far but that many timers running definitely impacts the performance of the application, is there a better optimised way of measuring this?
import flash.utils.Timer;
var active_:Boolean;
var matched:Boolean;
var vacated:Boolean;
var circ:Shape=new Shape();
this.addChild(circ);
circ.x = 0;
circ.y = 0;
var circRad:Number = 5;
var mat= new Matrix();
var busyColors = [0xFFFF00,0xFFCC00];
var idleColors = [0xCCCCCC,0x000000];
var matchedColors = [0x0099FF,0x0066FF];
var vacatedColors = [0xFF0000,0x990000];
var busyAlphas = [1,1];
var idleAlphas = [0.5,0.5];
var ratios = [0,255];
var prev:int = 0;
var time:Timer = new Timer(1000,0);
//time.start();
mat.createGradientBox(2*circRad,2*circRad,0,-circRad,-circRad);
circ.graphics.lineStyle();
if (active_ == false)
{
if (prev != 0)
{
setAverage(prev,false);
prev = 0;
}
circ.graphics.clear();
circ.graphics.beginGradientFill(GradientType.RADIAL,idleColors,idleAlphas,ratios,mat);
circ.graphics.drawCircle(0,0,circRad);
circ.graphics.endFill();
}
else if (active_ == true && matched == true)
{
if (prev != 1)
{
setAverage(prev,true);
prev = 1;
}
circ.graphics.clear();
circ.graphics.beginGradientFill(GradientType.RADIAL,matchedColors,busyAlphas,ratios,mat);
circ.graphics.drawCircle(0,0,circRad);
circ.graphics.endFill();
}
else if (active_ == true && vacated == false && matched == false)
{
if (prev != 2)
{
setAverage(prev,true);
prev = 2;
}
circ.graphics.clear();
circ.graphics.beginGradientFill(GradientType.RADIAL,busyColors,busyAlphas,ratios,mat);
circ.graphics.drawCircle(0,0,circRad);
circ.graphics.endFill();
}
else if (active_ == true && vacated == true)
{
if (prev != 3)
{
setAverage(prev,true);
prev = 3;
}
circ.graphics.clear();
circ.graphics.beginGradientFill(GradientType.RADIAL,vacatedColors,busyAlphas,ratios,mat);
circ.graphics.drawCircle(0,0,circRad);
circ.graphics.endFill();
}
function setAverage(i:int, a:Boolean)
{
time.stop();
switch (i)
{
case 0 :
break;
case 1 :
MovieClip(root).avgMat.push(uint(time.currentCount));
break;
case 2 :
MovieClip(root).avgBusy.push(uint(time.currentCount));
break;
case 3 :
MovieClip(root).avgVac.push(uint(time.currentCount));
break;
}
if(a == true){
//time.reset();
//time.start();
}
}
Commented out the timer starts because of the issue.
You can make public function like "tick()" at yours objects and call it in loop from 1 general timer outside.
Consider doing the following:
in the top, import getTimer
import flash.utils.Timer;
Create a variable containing the starting time (instead of doing timer.start) do this:
var timerStart : int = getTimer();
and instead of doing this: time.currentCount
Simply do this:
(getTimer() - timerStart) / 1000
Good luck.
you could change all the timers with addEventListener of type EVENT FRAME
var counter:Number = 0;
addEventListener(Event.ENTER_FRAME, counting);
function counting (e:Event):void
{
counter++
}
So counter will increment on every frame. Now you have to find fps. Now multiply fps by time that you want timer to run after. So it's should look like this:
var counter:Number = 0;
addEventListener(Event.ENTER_FRAME, counting);
function counting (e:Event):void
{
counter++
if(counter == 60) //60 fps means this line will run after 1 sec.
{
//do something
}
If(counter == 120) //60 fps; 2 sec
{
//do something
}
}
This method is much more accurate and the system will not be so overloaded. This can especcially help you for setting up the stage using addChild, when you need a delay after the animation is started.
You can make more of this 'timers', but that depends on the demands of the game, but i'm sure that it will work faster than hundreths of timers.