Connect 4 or Four IN A Row

Hello,

I'm creating a school project, the game connect 4, or four in a row. I have everything done, except for where the program checks wether the

lines are 4 in a row or not. Can anyone help? Here's the code:

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Projecto2 extends Applet implements ActionListener

{

Button botao;

boolean CanPlay = true;

Button [] [] tabela = new Button [8] [8] ;

//Button [] [] tabelaJogada = new Button [8] [8] ;

Label WhichPlayer = new Label("Please play player: X");

Label AvailableHouses = new Label("Available Houses: 63");

Label GiveSpace = new Label("");

int numPlay = 0;

int PlaysLeft = 63;

public void init()

{

botao = new Button ("Restart Game");

botao.addActionListener(this);

this.setLayout(new GridLayout(2,1));

Panel p1 = new Panel ();

p1.setLayout (new FlowLayout ());

p1.add (botao);

p1.add (GiveSpace);

p1.add (WhichPlayer);

p1.add (AvailableHouses);

Panel p2 = new Panel ();

p2.setLayout (new FlowLayout ());

Panel p3 = new Panel ();

p3.setLayout (new FlowLayout ());

for (int x = 0; x<tabela.length; x++)

{

for (int y = 0; y><tabela[x].length; y++)

{

tabela [x] [y] = new Button (x+" e "+y);

p2.add (tabela[x] [y]);

tabela [x] [y].addActionListener(this);

}

}

this.add (p1);

this.add (p2);

this.add (p3);

}

public void actionPerformed (ActionEvent ae)

{

for (int x = 0; x >< tabela.length; x++)

{

for (int y = 0; y < tabela[x].length; y++)

{

if (ae.getSource() == tabela[x] [y] )

if (CanPlay)

{

if (numPlay%2 == 0)

{

tabela[x] [y].setLabel("X");

WhichPlayer.setText("Please play player: 0");

AvailableHouses.setText("Available Houses: "+PlaysLeft);

}

if (numPlay%2 != 0)

{

tabela[x] [y].setLabel("0");

WhichPlayer.setText("Please play player: X");

AvailableHouses.setText("Available Houses: "+PlaysLeft);

}

numPlay++;

PlaysLeft--;

}

}

if (PlaysLeft < 0)

{

CanPlay = false;

WhichPlayer.setText("Game's Over!");

}

}

}

public void paint (Graphics g)

{

//Dimension tamanho = this.getSize();

setSize(750,600);

//g.drawLine(10, 10, tamanho.width-1, tamanho.height-1);

}

}

Sorry if I wasn't supposed to post this here, just need some help....

.: XonaDick :.

[2683 byte] By [xonadicka] at [2007-9-29 3:59:37]
# 1

Hi xonadick

I think this problem has been covered a few times before on this list.

A simple way to do it is each time a player makes a move check the

horizontal, vertical, and diagonals around the new position for 4 of

the same kind.

to check the horizontal start at current position and:

1) check left for one piece.

2) if it is the same as the current piece goto (1)

3) else check right of current position

4) if it is the same as the current piece goto (3)

5) check if (current + left pieces + right pieces ==4 )

You can write a chunk of code that will do this for an direction

required. Take care about the boundarys of the grid though.

matfud

matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 2
Thanks, I'll try to do that....XonaDickPS - should I use For loops?
xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 3

I cannot understand how to get the text of the button and compare it with the string or label.

What I mean is supose I already have a button with "X" or "0" in it. I don't want the player to be able to click that button again!

How do I do this?

Please help

if (numPlay%2 != 0)

{

if ((tabela[x] [y]).equals ("0"))

{

if (!(tabela[x] [y]).equals ("X"))

{

tabela[x] [y].setLabel("0");

ButtonsAvailable.setText("Plays Available: "+numPlays);

WhichPlayer.setText("Please Play Player: X");

}

}

}

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 4
Hilook at http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Button.htmlcheck the setEnable(boolean) methodcheersmatfud
matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 5

> Thanks, I'll try to do that....

>

> XonaDick

>

> PS - should I use For loops?

try using while loops. something like the following

/**

* x and y are the coordinates of the piece just played

*

* @return true if connect 4 is found. false otherwise.

*/

protected boolean checkHorizontal(int x, int y)

{

String currentPlayer = ;

int counter = 1;

// check left of current position

int positionOffset = -1;

if(isInBounds(x+positionOffset,y)

{

while(tabela[x+positionOffset][y].getLabel().equals(currentPlayer))

{

counter++

positionOffset--; // move further left

if(!isInBounds(x+positionOffset,y) break;

}

}

// check right of current position

positionOffset = 1;

if(isInBounds(x+positionOffset,y)

{

while(tabela[x+positionOffset][y].getLabel().equals(currentPlayer))

{

counter++

positionOffset++; // move further right

if(!isInBounds(x+positionOffset,y) break;

}

}

// check we have at least 4 in the row

if(counter>=4) return true;

return false;

}

matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 6
Hello again,Thanks, once again, for your help. You've been very kind. I hope I won't have to bother you again :-)XonaDick
xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 7

Hello matfud!

// check left of current position

int positionOffset = -1;

if(IsInBounds(x+positionOffset,y))

{

this part of the code gives me this error while compiling:

cannot resolve symbol

symbol: IsInBounds (int, int)

if(IsInBounds(x+positionOffset,y))

^

Do I have to create that method? And then call the checkHorizontal method, and within that one call the IsInBounds one?

XonaDick

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 8

Hello again,

I have been able to get from your precious help the program to force each player to click a button only once. Although, I have created the 2 methods you told me to do, with your code and slight modifications, and I cannot get it to work.

If you could help I would appreciate it.

I'm portuguese, so if you don't understand the name of some variable or sentences please tell me so I can trasnlate. Here's the whole code:

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Projecto2 extends Applet implements ActionListener

{

Button botao;

boolean PodeJogar = true;

Button [] [] tabela = new Button [8] [8] ;

//Button [] [] tabelaJogada = new Button [8] [8] ;

Label QualJogador = new Label("Jogue por favor jogador: X");

Label CasasDisponiveis = new Label("Casas disponiveis: 63");

Label DaEspaco = new Label("");

Label Ganhou = new Label("");

int numJogada = 0; //inteiro que serve para ver que jogador joga

int Jogadas = 63; //inteiro que serve para ver quantas jogadas faltam

int contaLinha = 0;

public void init()

{

botao = new Button ("Limpar Jogo");

botao.addActionListener(this);

this.setLayout(new GridLayout(2,1));

Panel p1 = new Panel ();

p1.setLayout (new FlowLayout ());

p1.add (botao);

p1.add (DaEspaco);

p1.add (QualJogador);

p1.add (CasasDisponiveis);

Panel p2 = new Panel ();

p2.setLayout (new FlowLayout ());

Panel p3 = new Panel ();

p3.setLayout (new FlowLayout ());

p3.add (Ganhou);

for (int x = 0; x<tabela.length; x++) //cria o array de bot齟s com

{ //label de X e Y respectivamente

for (int y = 0; y><tabela[x].length; y++)

{

tabela [x] [y] = new Button ("["+x+"]"+"["+y+"]");

p2.add (tabela[x] [y]);

tabela [x] [y].addActionListener(this);

}

//aqui tem de quebrar a linha

}

this.add (p1);

this.add (p2);

this.add (p3);

}

public void actionPerformed (ActionEvent ae)

{

for (int x = 0; x >< tabela.length; x++)

{

for (int y = 0; y < tabela[x].length; y++)

{

if (ae.getSource() == tabela[x] [y] )

if (PodeJogar) //caso ainda haja casas dispon齰eis para jogar

{

if (numJogada%2 == 0) //de der resto 0 joga o jogador X

{

if ((tabela[x] [y]).getLabel() != ("X"))//verifica conteudo do

{//bot齩 n齩 deixando

if ((tabela[x] [y]).getLabel() != ("0")) //carregar no mesmo

{//bot齩 2 vezes.

tabela[x] [y].setLabel("X");

// aqui come齛 a comparar a ver se tem 4 em linha

if(veHorizontal(x,y));

{

QualJogador.setText("Quatro em linha!");

}

CasasDisponiveis.setText("Casas dispon齰eis: "+Jogadas);

QualJogador.setText("Jogue por favor jogador: 0");

numJogada++;

Jogadas--;

}

}

}

if (numJogada%2 != 0) //de n齩 der resto 0 joga o jogador 0

{

if ((tabela[x] [y]).getLabel() != ("0"))//verifica conteudo do

{//bot齩 n齩 deixando

if ((tabela[x] [y]).getLabel() != ("X")) //carregar no mesmo

{//bot齩 2 vezes.

tabela[x] [y].setLabel("0");

//if(veHorizontal(tabela[x][y]))

//{

//QualJogador.setText("Quatro em linha!");

//}

CasasDisponiveis.setText("Casas dispon齰eis: "+Jogadas);

QualJogador.setText("Jogue por favor jogador: X");

numJogada++;

Jogadas--;

}

}

}

}

}

if (Jogadas < 0) // caso j?n齩 haja jogadas dispon齰eis o jogo acaba

{

PodeJogar = false;

QualJogador.setText("Terminou o jogo!");

}

}

}

public void paint (Graphics g)

{

//Dimension tamanho = this.getSize();

setSize(750,600);

//g.drawLine(10, 10, tamanho.width-1, tamanho.height-1);

}

protected boolean veHorizontal(int x, int y)

{

//String QualJogador;

int contador = 1;

// Ver ?esquerda da posio corrente

int posicaoOff = -1;

if(IsInBounds(x+posicaoOff,y))

{

while(tabela[x+posicaoOff][y].getLabel().equals(QualJogador))

{

contador++;

posicaoOff--; // anda mais para a esquerda

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// Ver ?direita da posio corrente

posicaoOff = 1;

if(IsInBounds(x+posicaoOff,y))

{

while(tabela[x+posicaoOff][y].getLabel().equals(QualJogador))

{

contador++;

posicaoOff++; // anda mais para a direita

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// ver se existe 4 em linha

if(contador>=4) return true;

return false;

}

// m齮odo que verifica se os 齨dices est齩 dentro da tabela

private boolean IsInBounds(int x, int y)

{

if ((x >= 0) && (x<=7))

{

if ((y >= 0) && (y<=7))

return true;

}

return false;

}

}

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 9

Yep

the isInBounds(int x, int y)

is a fictional method that you will need to implement. It should return

true if the x and y parameters passed to it are within your connect 4

grid otherwise it will return false and cause the while loop to exit

early. It this is not included the while loop condition can throw an

ArrayIndexOutOfBoundsException when you try to access (for example)

tabela[-1][3].

PS I have not checked the code example I gave you so you probably cannot

expect it to work first time (or perhaps ever)

cheers

matfud

matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 10

matfud,

Would you be willing to look over the code if I were to translate everything? I could send it to you by e-mail?

It is frustrating not to have code working..... :-(

Nonetheless you've been very helpful, and I understand you not wanting to look over code.

My e-mail is david@dvb-labs.com

XonaDick

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 11

Please help me anyone, here's my code translate to english (messages, variables, and comments)

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Testing12 extends Applet implements ActionListener

{

Button cleanGame;

boolean CanPlay = true;

Button [] [] tabela = new Button [8] [8] ;

Label WhichPlayer = new Label("Please Play Player: X");

Label AvailableHouses = new Label("Plays Still Available: 63");

Label GiveSpace = new Label(" ");

Label WonGame = new Label("");

int playNumber = 0; //integer used to see what player is playing

int playsLeft = 63; //integer to count remainding plays

int countsLines = 0;

public void init()

{

cleanGame = new Button ("Clean Game");

cleanGame.addActionListener(this);

this.setLayout(new GridLayout(2,1));

Panel p1 = new Panel ();

p1.setLayout (new FlowLayout ());

p1.add (cleanGame);

p1.add (GiveSpace);

p1.add (WhichPlayer);

p1.add (AvailableHouses);

Panel p2 = new Panel ();

p2.setLayout (new FlowLayout ());

Panel p3 = new Panel ();

p3.setLayout (new FlowLayout ());

p3.add (WonGame);

for (int x = 0; x<tabela.length; x++) //creates the array of buttons

{ //with labels that show their position in the board

for (int y = 0; y><tabela[x].length; y++)

{

tabela [x] [y] = new Button ("["+x+"]"+"["+y+"]");

p2.add (tabela[x] [y]);

tabela [x] [y].addActionListener(this);

}

}

this.add (p1);

this.add (p2);

this.add (p3);

}

public void actionPerformed (ActionEvent ae)

{

for (int x = 0; x >< tabela.length; x++)

{

for (int y = 0; y < tabela[x].length; y++)

{

if (ae.getSource() == tabela[x] [y] )

if (CanPlay) //in case there are still plays in the game available

{

if (playNumber%2 == 0) //if the remainder is 0, player X's turn to play

{

if ((tabela[x] [y]).getLabel() != ("X"))//verifies the label of the button

{//forcing the player to be able to

if ((tabela[x] [y]).getLabel() != ("0")) //click a button only once

{

tabela[x] [y].setLabel("X");

while (tabela[x+1] [y].getLabel() == ("X"));

{

countsLines++;

}

AvailableHouses.setText("Plays Still Available: "+playsLeft);

WhichPlayer.setText("Please Play Player: 0");

playNumber++;

playsLeft--;

}

}

}

if (playNumber%2 != 0) //if the remainder is not 0, player 0's turn to play

{

if ((tabela[x] [y]).getLabel() != ("0"))//verifies the label of the button

{//forcing the player to be able to

if ((tabela[x] [y]).getLabel() != ("X")) //click a button only once

{

tabela[x] [y].setLabel("0");

AvailableHouses.setText("Plays Still Available: "+playsLeft);

WhichPlayer.setText("Please Play Player: X");

playNumber++;

playsLeft--;

}

}

}

}

}

if (playsLeft < 0) // In case there are no more plays available the game is over

{

CanPlay = false;

WhichPlayer.setText("Game's Over!");

}

}

}

public void paint (Graphics g)

{

setSize(750,600);

}

protected boolean checkHorizontal(int x, int y)

{

//String WhichPlayer;

int contador = 1;

// checks left of current position

int posicaoOff = -1;

if(IsInBounds(x+posicaoOff,y))

{

while(tabela[x+posicaoOff][y].getLabel().equals(WhichPlayer))

{

contador++;

posicaoOff--; // goes further left

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// checks right of current position

posicaoOff = 1;

if(IsInBounds(x+posicaoOff,y))

{

while(tabela[x+posicaoOff][y].getLabel().equals(WhichPlayer))

{

contador++;

posicaoOff++; // goes further right

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// checks to see if there's 4 in a row horizontally

if(contador>=4) return true;

return false;

}

// method that checks if indexes of array are inside the board

private boolean IsInBounds(int x, int y)

{

if ((x >= 0) && (x<=7))

{

if ((y >= 0) && (y<=7))

return true;

}

return false;

}

}

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 12

Hi

It seems that our last messages crossed.

here is your code with some comments about why it didn't work.

import java.awt.*;

import java.applet.*;

import java.awt.event.*;

public class Projecto2 extends Applet implements ActionListener

{

Button botao;

boolean PodeJogar = true;

Button [] [] tabela = new Button [8] [8] ;

//Button [] [] tabelaJogada = new Button [8] [8] ;

// set this variable to true when a winner is found

boolean gameOver = false;

Label QualJogador = new Label("Jogue por favor jogador: X");

Label CasasDisponiveis = new Label("Casas disponiveis: 63");

Label DaEspaco = new Label(" ");

Label Ganhou = new Label(" ");

int numJogada = 0; //inteiro que serve para ver que jogador joga

int Jogadas = 63; //inteiro que serve para ver quantas jogadas faltam

int contaLinha = 0;

public void init()

{

botao = new Button("Limpar Jogo");

botao.addActionListener(this);

this.setLayout(new GridLayout(2,1));

Panel p1 = new Panel();

p1.setLayout(new FlowLayout());

p1.add(botao);

p1.add(DaEspaco);

p1.add(QualJogador);

p1.add(CasasDisponiveis);

Panel p2 = new Panel();

p2.setLayout(new FlowLayout());

Panel p3 = new Panel();

p3.setLayout(new FlowLayout());

p3.add(Ganhou);

for (int x = 0; x<tabela.length; x++) //cria o array de bot齟s com

{ //label de X e Y respectivamente

for (int y = 0; y><tabela[x].length; y++)

{

tabela [x] [y] = new Button("["+x+"]"+"["+y+"]");

p2.add(tabela[x] [y]);

tabela [x] [y].addActionListener(this);

}

//aqui tem de quebrar a linha

}

this.add(p1);

this.add(p2);

this.add(p3);

}

public void actionPerformed(ActionEvent ae)

{

for (int x = 0; x >< tabela.length; x++)

{

for (int y = 0; y < tabela[x].length; y++)

{

if (ae.getSource() == tabela[x] [y] )

if (PodeJogar) //caso ainda haja casas dispon齰eis para jogar

{

if (numJogada%2 == 0) //de der resto 0 joga o jogador X

{

if ((tabela[x] [y]).getLabel() != ("X")) //verifica conteudo do

{ //bot齩 n齩 deixando

if ((tabela[x] [y]).getLabel() != ("0")) //carregar no mesmo

{ //bot齩 2 vezes.

tabela[x] [y].setLabel("X");

// aqui come齛 a comparar a ver se tem 4 em linha

if(veHorizontal(x,y)) // <-- removed ; from this line

{

QualJogador.setText("Quatro em linha!");

////

// set boolean to say game is over

////

gameOver = true;

}

CasasDisponiveis.setText("Casas dispon齰eis: "+Jogadas);

////

// only change the label QualJogada if the game is to continue

// you were finding a winner and then changing the label again

////

if(!gameOver)

{

QualJogador.setText("Jogue por favor jogador: 0");

numJogada++;

Jogadas--;

}

}

}

}

if (numJogada%2 != 0) //de n齩 der resto 0 joga o jogador 0

// {

if ((tabela[x] [y]).getLabel() != ("0")) //verifica conteudo do

{ //bot齩 n齩 deixando

if ((tabela[x] [y]).getLabel() != ("X")) //carregar no mesmo

{ //bot齩 2 vezes.

tabela[x] [y].setLabel("0");

if(veHorizontal(x,y))

{

QualJogador.setText("Quatro em linha!");

////

// set boolean to say that the game has been won

////

gameOver = true;

}

CasasDisponiveis.setText("Casas dispon齰eis: "+Jogadas);

/////

// only change the label QualJogada if the game is to continue

/////

if(!gameOver)

{

QualJogador.setText("Jogue por favor jogador: X");

numJogada++;

Jogadas--;

}

}

}

}

}

if (Jogadas < 0) // caso j?n齩 haja jogadas dispon齰eis o jogo acaba

{

PodeJogar = false;

QualJogador.setText("Terminou o jogo!");

}

}

}

public void paint(Graphics g)

{

//Dimension tamanho = this.getSize();

setSize(750,600);

//g.drawLine(10, 10, tamanho.width-1, tamanho.height-1);

}

protected boolean veHorizontal(int x, int y)

{

//String QualJogador;

int contador = 1;

// Ver ?esquerda da posio corrente

int posicaoOff = -1;

if(IsInBounds(x+posicaoOff,y))

{

////

// note change to condition

////

while(tabela[x+posicaoOff][y].getLabel().equals(tabela[x][y].getLabel()))

{

contador++;

posicaoOff--; // anda mais para a esquerda

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// Ver ?direita da posio corrente

posicaoOff = 1;

if(IsInBounds(x+posicaoOff,y))

{

while(tabela[x+posicaoOff][y].getLabel().equals(tabela[x][y].getLabel()))

{

contador++;

posicaoOff++; // anda mais para a direita

if(!IsInBounds(x+posicaoOff,y)) break;

}

}

// ver se existe 4 em linha

if(contador>=4) return true;

return false;

}

// m齮odo que verifica se os 齨dices est齩 dentro da tabela

private boolean IsInBounds(int x, int y)

{

if ((x >= 0) && (x<=7))

{

if ((y >= 0) && (y<=7))

return true;

}

return false;

}

}

Also note the the method protected boolean veHorizontal(int x, int y)

actually checks for 4 in a row vertically as you have your x and y indices reversed.

Don't worry you are getting there.

matfud

matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 13

Matfud,

You are a great helper!

Now it does check for the 4 in a row vertically. Does that mean that if I change the x and y it will check horizontally? I tried doing that and it didn't work.

The diagonal 4 in a row should be the hardest one, but the horizontal one should be changing x for y and vice-versa. ALthough that didn't work :-(

I'll keep trying...

Thanks,

David aka XonaDick

xonadicka at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 14

Hi

It is not quite as obvious as it appears.

you need to change the while loops to look something like this:

//

//V V

if(IsInBounds(x,y+posicaoOff))

{

while(tabela[x][y+posicaoOff].getLabel().equals(tabela[x][y].getLabel()))

{

contador++;

posicaoOff--; // anda mais para a esquerda

if(!IsInBounds(x,y+posicaoOff)) break;

}

}

note how the offset is now added to the y variable not the x. make sure

that you do this in all the right places.

one of the diagonal checks will require that the posicaOff is added

to both x and y variables. The second diagonal will require adding

positionOffset to one variable and subtract from the other.

matfud

matfuda at 2007-7-13 20:43:17 > top of Java-index,Other Topics,Algorithms...
# 15

Hey,

Bingo!!!!!!!!!! It finally works, everything!!!!!!!! Thanks to you!!!

I have to thank you, you've been a GREAT helper. Thanks for spending your precious time in helping me, a total stranger.

Thanks to java.sun.com as well for providing this help forum!

David

AKA XonaDick

xonadicka at 2007-7-19 3:40:38 > top of Java-index,Other Topics,Algorithms...