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]

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
Thanks, I'll try to do that....XonaDickPS - should I use For loops?
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");
}
}
}
Hilook at http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Button.htmlcheck the setEnable(boolean) methodcheersmatfud
> 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;
}
Hello again,Thanks, once again, for your help. You've been very kind. I hope I won't have to bother you again :-)XonaDick
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
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 posio 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 posio 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;
}
}
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
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
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;
}
}
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 posio 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 posio 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
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
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
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