Java Reversi Game Flipping Tiles - java

I am creating a reversi (othello) game on Java. Included below are my functions for when tiles need to flip to the left, right, below, or above the selected piece. For some reason, whenever a vertical flip is initiated, it ALWAYS works correctly. But, when a horizontal flip is initiated, sometimes it does nothing (when it should do something), or flips over blank tiles that are not supposed to be flipped. The gameboard is an 8 by 8 matrix using an extended JButton called BlankPiece. I will post that in addition to the functions. Can anyone suggest a more efficient / better way to run this game without bugs? Any help is greatly appreciated! If you need clarification, just ask.
public void checkFlipDown(BlankPiece temp)
{
for(int j = temp.getRow() - 1; j>=0; j--){
// j equals the square right above the clicked one, and it keeps going up until it hits the top of the board
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement
}
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getRow(); i >= j; i--)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[i][temp.getCol()].change(temp.pieceType());
}
}
else
{
// if no other border pieces exist, go out of the loop
break;
}
}
}
public void checkFlipUp(BlankPiece temp)
{
for(int j = temp.getRow() + 1; j<=7; j++){
// j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getRow(); i <= j; i++)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[i][temp.getCol()].change(temp.pieceType());
}
}
else
{
break;
}
}
}
public void checkFlipLeft(BlankPiece temp)
{
for(int j = temp.getCol() + 1; j<=7; j++){
// j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getCol(); i <= j; i++)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[temp.getRow()][i].change(temp.pieceType());
}
}
else
{
break;
}
}
}
public void checkFlipRight(BlankPiece temp)
{
for(int j = temp.getCol() - 1; j>=0; j--){
// j equals the square to the right of the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getCol(); i >= j; i--)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[temp.getRow()][i].change(temp.pieceType());
}
}
else if (gameboard[j][temp.getRow()].pieceType() == 0)
{
break;
}
}
}
So those are my four functions (one for west, east, north, and south). BlankPiece is below:
import java.awt.Color;
import javax.swing.*;
public class BlankPiece extends JButton
{
private final ImageIcon bbutton = new ImageIcon("bbutton.png");
private final ImageIcon gbutton = new ImageIcon("gbutton.jpg");
private final ImageIcon pbutton = new ImageIcon("pbutton.png");
private int x;
private int y;
BlankPiece(int x, int y)
{
this.setBackground(Color.BLACK);
this.setIcon(bbutton);
this.x = x;
this.y = y;
}
public void setGreen()
{
this.setBackground(Color.BLACK);
this.setIcon(gbutton);
}
public void setPurple()
{
this.setBackground(Color.BLACK);
this.setIcon(pbutton);
}
public int getRow() {
// TODO Auto-generated method stub
return x;
}
public int getCol() {
return y;
}
public void resetImage(int count)
{
if (count % 2 == 0)
{
this.setIcon(gbutton);
}
else
{
this.setIcon(pbutton);
}
}
public boolean isSet()
{
String image = "" + this.getIcon();
if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
{
}
return false;
}
public int pieceType()
{
if(getIcon().equals(pbutton)) // purple
{
return -1;
}
else if(getIcon().equals(bbutton)) // blank
{
return 0;
}
else // green
{
return 1;
}
}
public void change(int i) {
if (i == -1)
{
setIcon(pbutton);
}
else if(i == 1)
{
setIcon(gbutton);
}
else
{
setIcon(bbutton);
}
}
}
The problem is not that any checkflip isn't called (they are all called with the same correct parameters), but something in checkFlipRight or CheckFlipLeft functions...
EDIT: full working example by request.
Make a folder with TWO files
One is called Reversi.java
and the other is BlankPiece.java
REVERSI.JAVA:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Reversi extends JPanel {
BlankPiece [][] gameboard = new BlankPiece[8][8];
JPanel toparea = new JPanel();
JPanel gamearea = new JPanel();
JPanel greenarea = new JPanel();
JPanel purplearea = new JPanel();
JPanel logo = new JPanel();
JLabel logoarea = new JLabel();
JLabel greenlogo = new JLabel();
JLabel purplelogo = new JLabel();
ImageIcon blackicon = new ImageIcon("bbutton.png");
ImageIcon icon = new ImageIcon("reversilogo.png");
ImageIcon dgreen = new ImageIcon("DarkGreen.png");
ImageIcon lgreen = new ImageIcon("LightGreen.png");
ImageIcon dpurple = new ImageIcon("DarkPurple.png");
ImageIcon lpurple = new ImageIcon("LightPurple.png");
int count = 0;
int jplus = 0;
public Reversi()
{
gamearea.setLayout(new GridLayout(8,8));
for (int row = 0; row < gameboard.length; row++)
{
for(int col = 0; col < gameboard.length; col++)
{
gameboard[row][col] = new BlankPiece(row, col);
gamearea.add(gameboard[row][col]);
gameboard[row][col].addActionListener(new ButtonListener());
}
}
logoarea.setPreferredSize(new Dimension(304,73));
toparea.setLayout(new BorderLayout());
this.setLayout(new BorderLayout());
toparea.setBackground(new Color(97,203,242));
gamearea.setBackground(new Color(83,35,215));
logo.setBackground(new Color(97,203,242));
logoarea.setIcon(icon);
greenlogo.setIcon(dgreen);
purplelogo.setIcon(lpurple);
toparea.add(greenlogo, BorderLayout.WEST);
toparea.add(purplelogo, BorderLayout.EAST);
toparea.add(logo, BorderLayout.CENTER);
logo.add(logoarea);
this.add(toparea, BorderLayout.NORTH);
this.add(gamearea, BorderLayout.CENTER);
gameboard[3][3].setGreen();
gameboard[3][4].setPurple();
gameboard[4][3].setPurple();
gameboard[4][4].setGreen();
}
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
BlankPiece temp = (BlankPiece)e.getSource(); // #1
int row = temp.getRow(); // #2
System.out.println(row);
int col = temp.getCol();
System.out.println(col);
temp.isSet();
// col and row are the column and row of blankpiece that was clicked
String image = "" + temp.getIcon();
if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
{
JOptionPane.showMessageDialog(null, "This spot is already occupied by " +
"a piece. Please pick an empty tile.");
}
else
{
temp.resetImage(count++);
System.out.println("About to check");
checkFlipDown(gameboard[row][col]);
checkFlipUp(gameboard[row][col]);
checkFlipLeft(gameboard[row][col]);
checkFlipRight(gameboard[row][col]);
}
if (count % 2 == 0)
{
greenlogo.setIcon(dgreen);
purplelogo.setIcon(lpurple);
}
else
{
greenlogo.setIcon(lgreen);
purplelogo.setIcon(dpurple);
}
}
}
public void checkFlipDown(BlankPiece temp)
{
for(int j = temp.getRow() - 1; j>=0; j--){
// j equals the square right above the clicked one, and it keeps going up until it hits the top of the board
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement
}
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getRow(); i >= j; i--)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[i][temp.getCol()].change(temp.pieceType());
}
}
else
{
// if no other border pieces exist, go out of the loop
break;
}
}
}
public void checkFlipUp(BlankPiece temp)
{
for(int j = temp.getRow() + 1; j<=7; j++){
// j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getCol()].pieceType() != 0) && (gameboard[j][temp.getCol()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getRow(); i <= j; i++)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[i][temp.getCol()].change(temp.pieceType());
}
}
else
{
break;
}
}
}
public void checkFlipLeft(BlankPiece temp)
{
for(int j = temp.getCol() + 1; j<=7; j++){
// j equals the square right below the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getCol(); i <= j; i++)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[temp.getRow()][i].change(temp.pieceType());
}
}
else
{
break;
}
}
}
public void checkFlipRight(BlankPiece temp)
{
for(int j = temp.getCol() - 1; j>=0; j--){
// j equals the square to the right of the clicked one, and it keeps going down until it hits the bottom of the board
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() != temp.pieceType())){
//if the spot right above the clicked one is not black AND it is the other player's color,
continue;
// keep going with the block statement 2,4 jj = 3,4,5,6,7
}
if ((gameboard[j][temp.getRow()].pieceType() != 0) && (gameboard[j][temp.getRow()].pieceType() == temp.pieceType())){
// if the spot right above is not black AND it is the same player's color,
for(int i = temp.getCol(); i >= j; i--)
// i equals the row of the clicked spot, it goes until it finds J, where the other green / purple end piece is
{
// change the colors of all colors in the clicked color's column and rows in between the other border piece
gameboard[temp.getRow()][i].change(temp.pieceType());
}
}
else if (gameboard[j][temp.getRow()].pieceType() == 0)
{
break;
}
}
}
}
BLANKPIECE.JAVA
import java.awt.Color;
import javax.swing.*;
public class BlankPiece extends JButton
{
private final ImageIcon bbutton = new ImageIcon("bbutton.png");
private final ImageIcon gbutton = new ImageIcon("gbutton.jpg");
private final ImageIcon pbutton = new ImageIcon("pbutton.png");
private int x;
private int y;
BlankPiece(int x, int y)
{
this.setBackground(Color.BLACK);
this.setIcon(bbutton);
this.x = x;
this.y = y;
}
public void setGreen()
{
this.setBackground(Color.BLACK);
this.setIcon(gbutton);
}
public void setPurple()
{
this.setBackground(Color.BLACK);
this.setIcon(pbutton);
}
public int getRow() {
// TODO Auto-generated method stub
return x;
}
public int getCol() {
return y;
}
public void resetImage(int count)
{
if (count % 2 == 0)
{
this.setIcon(gbutton);
}
else
{
this.setIcon(pbutton);
}
}
public boolean isSet()
{
String image = "" + this.getIcon();
if((image.equals("pbutton.png")) || (image.equals("gbutton.jpg")))
{
}
return false;
}
public int pieceType()
{
if(getIcon().equals(pbutton)) // purple
{
return -1;
}
else if(getIcon().equals(bbutton)) // blank
{
return 0;
}
else // green
{
return 1;
}
}
public void change(int i) {
if (i == -1)
{
setIcon(pbutton);
}
else if(i == 1)
{
setIcon(gbutton);
}
else
{
setIcon(bbutton);
}
}
}

Unfortunately I wasn't able to run your code since it uses images and without them it is impossible to tell what part is working or not. However I have a suggestion for a different approach which I think it would help you to solve the problem (please pay attention to the ideas described and not necessarily to the code).
Problem description: (as I understand it) When a player puts a piece of one color on the board (there are two colors in the game, one for each player), the system needs to traverse all blocks along all directions (there are 8 of them) until it encounters one of the following:
a piece of the same color: in this case all in-between pieces of opposite color are flipped to the player's color (i.e. they are "captured")
a blank piece/block: in this case no color flipping occurs
an edge of the board: again no flipping occurs.
The above description implies that the problem can be divided further to smaller problems that we need to solve first.
Problems to solve:
how can we identify "directions"
how can we traverse along a direction considering each time the next block
how can we identify pieces that are supposed to be captured
how can we identify the edge of the board
Your approach tries to solve all the above problems together. This makes it complicated. Furthermore the same work is repeated for different directions which does not need to be the case. As per the above description, no special action is required for a specific direction. If we solve the problem for a single direction then it should be solved for all.
Suggested approach: Below you can find the algorithm to use (pseudo-code) to find all the pieces to capture. Note how the piece itself tries to solve the problem and propagates the work to the next piece until all captured pieces are found. This way you don't solve the problem yourself. You just describe it correctly to your objects. I have put comments inline to explain what each class is supposed to be. I hope it is clear and useful to you.
// Convenient class to hold together a row and a column pair
public class Index { ... }
// Checks if an index falls out of board edges
public static boolean isValid(Index index) {...}
// Holds the array of pieces. Has method to get a piece by index
public class Board { ... }
public enum ColorType { BLANK, WHITE, BLACK; } // the types of a Piece
// The possible directions to traverse
public enum Direction {
UP_LEFT, UP, UP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT;
// given an index it returns the next index along the same direction
public Index next(Index index) {
switch (this) {
case UP_LEFT:
return new Index(index.row() - 1, index.column() - 1);
case BOTTOM:
return new Index(index.row() + 1, index.column());
... // similar for the rest of cases
}
}
}
public class Piece {
private Board board;
private ColorType color = ColorType.BLANK;
private Index index;
....
// Should be called privately when the piece is put on the board and from BLANK becomes WHITE or BLACK
private void checkCaptures() {
Direction[] directions = Direction.values();
for (Direction direction : directions) {
// get next piece's index along the direction
Index nextIndex = direction.next(this.index);
if ( isValid(nextIndex) ) { // if the index is not valid (i.e. edge of the board) ignore it
// get next piece in the same direction
Piece piece = board.getPiece(nextIndex);
// find all pieces that should be captured in this direction
List<Piece> candidatesToCapture = new ArrayList<Piece>();
piece.findCaptureCandidates(candidatesToCapture, this.color, direction);
for (Piece candidate : candidatesToCapture) {
// flip the color (WHITE to BLACK and vice-versa)
candidate.capture();
}
}
}
}
private void findCaptureCandidates(List<Piece> captured, ColorType firstColor, Direction d) {
Index next = d.next(this.index);
if (this.color == firstColor) {
// This piece has the same color with the first one.
// No need to search further for this direction. All pieces collected in the list
// between the first one and this one, have opposite color and should be captured.
} else if (this.color == ColorType.BLANK) {
// found a blank piece. Stop the search and clear any captured pieces found so far
captured.clear();
} else {
// this piece has the opposite color of the first
if ( isValid(next) ) {
// this is not the last piece in this direction.
// Since it has a flipped color it is a candidate for capturing
captured.add(this);
// ask the next piece recursively to also check itself
Piece piece = board.getPiece(next);
piece.findCaptureCandidates(captured, firstColor, d);
} else {
// next index is not valid i.e. we have reached board edge.
// Stop the search and clear any captured pieces found so far
captured.clear();
}
}
}
}

Related

How would I create a HashMap for a TicTacToe game

I am creating a TicTacToe game with 2 boards, only one is playable to the user. If a user clicks on cell[2][3] on grid 1 a token will be drawn on grid 1 and on cells[2][3] on grid 2. I was thinking of using a HashMap to assign indexes to each cell. Like cell[2][3] and cells[2][3] would each be assigned to index 9. How would I implement this is my code? Would I even use a Hashmap for what I am trying to do? I am unfamiliar with this concept so I might just be overthinking this.
Note: Cell[][] is the cells for grid 1 and Cells[][] are for grid 2. Cells[][] have randomized indexes in it so it can be randomly assigned to the board.
Edit: If I want to link cell(2)(3) and cells(2)(3) I would change integer to Cell when I initialize hashmap. Then I would do HMap. put(cell[2][3], cells[2][3]) right?
Code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.border.LineBorder;
import java.util.Random;
import java.util.HashMap;
public class Bull extends JFrame{
private char currentPlayer = ' ';
// Creates array of cells called Cell[][] cell
private Cell[][] cell = new Cell[3][3];
// Creates array of cells called Sale[][] cells
private Cells[][] cells = new Cells[3][3];
// Creates a boolean array
private boolean t[][] = new boolean[3][3];
// Creates index array
private int z[] = new int[8];
//Initializes Random
Random rand = new Random();
// Initializes variables which will be used to create random ints
int f;
int g;
// Initializes JlblStatus
private JLabel jlblStatus = new JLabel(" ");
private JLabel jlblIndex = new JLabel(" ");
// Method that builds the JFrame and JPanels
public Bull(){
// Do I change Integer to array?
HashMap<Integer, Integer> HMap = new HashMap<Integer, Integer>();
// Title of the JFrame
JFrame frame = new JFrame("Shadow Tic Tac Toe Game");
// Makes the JFrame full screen
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
// If x button is clicked than the JFrame closes
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Initializes JPanel1
JPanel panel1 = new JPanel();
// Initializes JPanel2
JPanel panel2 = new JPanel();
// Adds panel1 which will hold the first TicTacToe game.
panel1.setLayout(new GridLayout(3,3,0,0));
for(int d = 0; d < 3; d++){
for(int c = 0; c < 3; c++){
panel1.add(cell[d][c] = new Cell());
// Sets size of the cells in JPanel1
cell[d][c].setPreferredSize(new Dimension(250,250));
}
}
panel2.setLayout(new GridLayout(3,3,0,0));
int n = 0;
while(n < 9){
f=rand.nextInt(3);
g=rand.nextInt(3);
while(t[f][g] == false){
t[f][g] = true;
panel2.add(cells[f][g] = new Cells());
cells[f][g].setPreferredSize(new Dimension(250,250));
System.out.println(f);
System.out.println("\t" + g);
n++;
}
}
// Adds Panel1 to the JFrame
frame.add(panel1, BorderLayout.WEST);
// Adds Panel2 to the JFrame
frame.add(panel2, BorderLayout.EAST);
// Updates the status of the game here (win/lose/draw/whose turn it is
frame.add(jlblStatus, BorderLayout.SOUTH);
// Sets size of the message area at the bottom of the frame
jlblStatus.setPreferredSize(new Dimension(100,100));
// Shows the Instructions of the game
Instructions();
// Calls method Chose() which allows the player to chose which token they will play as
Chose();
frame.pack();
// Sets it so the JFrame is visible to the user
frame.setVisible(true);
}
// Method that creates the Instructions for the game. Will be shown to the user prior to the user picking his token
public void Instructions(){
JOptionPane.showMessageDialog(null,"INSTRUCTIONS" + "\nThis game is called a 'Shadow Tic Tac Toe Game'. In this game there will be two Tic Tac Toe game boards, though only one is playable. \nBut you can win on either board. Lets say you place your token on the center tile at cell(2,3). \nAn X will be drawn on that spot on board 1 and on a randomized spot on the second game board at cell(2,3). \nYou will be able to see the cell indexes before you click on a cell so you can form a strategy");
}
// Method that lets the user chose his/her token
public void Chose(){
int f = 2;
// While f == 2 the loop will run
while(f == 2){
String input = JOptionPane.showInputDialog("CHOSE" + "\nPlease select your token. \nPress 1 for X and 2 for O.");
// Reads in the user input. Input put into a variable called pawn
int pawn = Integer.parseInt(input);
// If user input 1 his/her token will be X. F will equal 3 so the loop does not run again
if(input.equals("1")){
currentPlayer = 'X';
f = 3;
// If user input 2 his/her token will be O. F will equal 3 so the loop does not run again
}else if(input.equals("2")){
currentPlayer = 'O';
f = 3;
// If user does not enter in either a 1 or 2 an error message will appear. f wil equal 2 so the loop runs again and asks the user to chose his/her token again
}else{
JOptionPane.showMessageDialog(null,"ERROR INVALID RESPONSE");
f = 2;
}
}
}
public class Cells extends JPanel{
private char tok = ' ';
public Cells(){
// Sets the border for the cells to the color black
setBorder(new LineBorder(Color.black,1));
}
public void setTok(char d){
tok = d;
repaint();
}
public char getTok(){
return tok;
}
protected void Paint(Graphics g){
super.paint(g);
if(tok == 'X'){
g.drawLine(10,10,getWidth() - 10, getHeight()-10);
g.drawLine(getWidth()-10,10,10,getHeight()-10);
}else if (tok == 'O'){
g.drawOval(10,10,getWidth()-20, getHeight()-20);
}
}
}
public class Cell extends JPanel{
private char token = ' ';
public void setToken(char c){
token = c;
repaint();
}
public char getToken(){
return token;
}
public Cell(){
// Sets the border for the cells to the color black
setBorder(new LineBorder(Color.black, 1));
addMouseListener(new MyMouseListener());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (token == 'X') {
g.drawLine(10,10, getWidth() - 10, getHeight() - 10);
g.drawLine(getWidth() - 10,10,10, getHeight() - 10);
}
else if (token == 'O') {
g.drawOval(10, 10, getWidth() - 20, getHeight() - 20);
}
}
private class MyMouseListener extends MouseAdapter{
public void mouseClicked(MouseEvent e){
// If cell is empty and game is not over
if (token == ' ' && currentPlayer != ' ') {
setToken(currentPlayer); // Set token in the cell
for(int d = 0; d < 3; d++){
for(int c = 0; c < 3; c++){
if(cell[d][c].getToken() == 'X'){
cells[d][c].setTok('X');
}else if(cell[d][c].getToken() == 'O'){
cells[d][c].setTok('O');
}else if(cell[d][c].getToken() == ' '){
cells[d][c].setTok(' ');
}
}
}
//setTok(currentPlayer);
if(Won(currentPlayer)){
jlblStatus.setText("The game is over! " + currentPlayer + " won the game! Congragulations " + currentPlayer + " !");
currentPlayer = ' ';
}else if(Full()){
jlblStatus.setText("The game is over, it ends in a draw!");
currentPlayer = ' ';
}else{
if(currentPlayer == 'X'){
currentPlayer = 'O';
}else{
currentPlayer = 'X';
}
jlblStatus.setText("It is " + currentPlayer + " 's turn");
}
}
}
}
}
public boolean Full(){
for(int d = 0; d < 3; d++)
for(int c = 0; c < 3; c++)
if(cell[d][c].getToken() == ' ')
return false;
return true;
}
public boolean Won(char token){
for(int d = 0; d < 3; d++){
if(cell[d][0].getToken() == token && cell[d][1].getToken() == token && cell[d][2].getToken() == token){
return true;
}
}
for(int c = 0; c < 3; c++){
if(cell[0][c].getToken() == token && cell[1][c].getToken() == token && cell[2][c].getToken() == token){
return true;
}
}
if(cell[0][0].getToken() == token && cell[1][1].getToken() == token && cell[2][2].getToken() == token){
return true;
}
if(cell[0][2].getToken() == token && cell[1][1].getToken() == token && cell[2][0].getToken() == token){
return true;
}
return false;
}
public static void main(String [] args){
new Bull();
}
}
So essentially you want to map a cell on one grid (that the player can play on) to some cell on another grid (the shadow grid)?
You could do this just using another 2D array that stores what indices a cell maps to in the other grid, but you would need to return a point object containing x and y coordinates. But that method is sorta annoying to keep track of and has its limitations.
If you want to do it with a HashMap<Point, Point> of one Point in one grid to a Point in another grid, then you would have to override hashCode() and equals() of Point and do something like this:
HashMap<Point, Point> mapPointToPoint = new HashMap<>();
// (0,0) maps to shadow grid (1,2)
mapPointToPoint.put(new Point(0,0), new Point(1,2));
mapPointToPoint.put(new Point(0,1), new Point(2,1));
// ... more mappings for all the cells
// to get
Point pointInPlayableGrid = new Point(0,0);
Point pointInShadowGrid = mapPointToPoint.get(pointInPlayableGrid);
// pointInShadowGrid == (1,2) since that's what it was mapped to
However, if you wanted to have multiple shadow grids then you'd need to have a map from points in the playable grid to the points in the shadow grids for each shadow grid.
So instead, since you already have the Cell class, why not just have each Cell store a List<Cell> of all the cells that it maps to. This is also very flexible because you could even have a single playable Cell map to multiple cells in a single shadow grid, and on hover of the playable Cell you could just go through the list of shadow Cells it maps to and highlight them too.
public class Cell extends JPanel{
private Cell shadowCell;
public void setCellThisMapsTo(Cell otherCell){ this.shadowCell = otherCell; }
public Cell getCellThisMapsTo(){ return shadowCell; }
// ... all the other stuff
}
// ... wherever you initialize the playable and shadow grid
// get a list of the shadow Cells, randomized order
Cell[][] shadowGrid; // however you init this
Cell[][] playableGrid; // however you init this
LinkedList<Cell> shadowCells = new LinkedList<>();
for(int x = 0; x < 3; x++){
for(int y = 0; y < 3; y++){
shadowCells.add(shadowGrid[x][y]);
}
}
Collections.shuffle(shadowCells);
for(int x = 0; x < 3; x++){
for(int y = 0; y < 3; y++){
Cell playableCell = playableGrid[x][y];
Cell shadowCell = shadowCells.removeFirst();
playableCell.setCellThisMapsTo(shadowCell );
}
}
// Now all the playable cells map to a random shadow cell
Cell playableCell = playableGrid[0][0];
Cell shadowCell = playableCell.getCellThisMapsTo();
The shadow Cells will not map to any other cells, so shadowCell.getCellThisMapsTo() would return null. But this method would makes it easy to map playable cells to shadow cells and keep track of them, without even using a HashMap nor having to keep track of Points mapping to Points.
Here is my definition for Point. If you want to put something in a hash map based on its values (rather than its object reference), then it is important to override hashCode() and equals():
class Point {
public final int x;
public final int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
// !!! OVERRIDE hashCode() and equals() so you can use this properly in a HashMap !!!
#Override
public int hashCode() {
int hash = 7;
hash = 71 * hash + this.x;
hash = 71 * hash + this.y;
return hash;
}
#Override
public int equals(Object o) {
if (obj == null)
return false;
if (this == obj)
return true;
if (getClass() != o.getClass())
return false;
Point p = (Point) o;
return this.x == p.x && this.y == p.y;
}
}

Moving 2D Array For Space Invaders Game

So the title pretty much explains it all, recently I have learned about 2D arrays but I am a little confused on how to make the 2D array move correctly in this Space Invaders game I am creating.
Right now I have Aliens moving left to right (and vice versa), however, they don't all move down at the same time, they move down column by column. Anyone know where to edit the code?
Here is my code for the Aliens:
class Aliens {
int x = 100, y = 75, deltaX = 1;
Aliens (int x, int y) {
this.x = x;
this.y = y;
}
void drawAlien() {
fill(255);
rect(x, y, 25, 25);
}
void moveAlien() {
x = x + deltaX;
if (x >= width) {
y = y + 20;
deltaX = - deltaX;
} else if (x <=0) {
y = y + 20;
deltaX = - deltaX;
}
}
void updateAlien() {
drawAlien();
moveAlien();
}
}
and my main class:
import ddf.minim.*;
//Global Variables
PImage splash;
PFont roboto;
Defender player;
Aliens[][] alienArray = new Aliens[15][3];
Missile missile;
int gameMode = 0;
int score = 0;
void setup() {
size(1000, 750);
rectMode(CENTER);
textAlign(CENTER, CENTER);
splash = loadImage("Splash.png");
player = new Defender();
for (int row = 0; row < 15; row++) {
for (int column = 0; column < 3; column++) {
alienArray[row][column] = new Aliens((row + 1) * 50, (column + 1) * 50);
}
}
roboto = createFont("Roboto-Regular.ttf", 32);
textFont(roboto);
}
void draw() {
if (gameMode == 0) {
background(0);
textSize(75);
text("Space Invaders", width/2, height/8);
textSize(25);
text("Created by Ryan Simms", width/2, height/4);
textSize(45);
text("Press SPACE to Begin", width/2, height - 100);
image(splash, width/2-125, height/4 + 75);
} else if (gameMode == 1) {
background(0);
score();
player.updateDefender();
for (int row = 0; row < 10; row ++) {
for (int column = 0; column < 3; column++) {
alienArray[row][column].updateAlien();
}
}
if (missile != null) {
missile.updateMissile();
}
if (keyPressed) {
if (key == ' ') {
if (missile == null) {
missile = new Missile(player.x);
}
}
}
if (missile != null) {
if (missile.y <= 0) {
missile = null;
}
}
}
}
void score() {
textSize(20);
text("Score: " + score, 40, 15);
}
void keyPressed() {
if (key == ' ') {
gameMode = 1;
}
}
The logic flaw is in the moveAlien() method. You move the x position of an alien by a certain delta. If it is detected that the alien has passed some screen boundary (the x >= width and x <=0 checks), you invert the delta to reverse the movement of the alien, and also update the y position to have it move down.
Since the aliens are oriented in vertical columns, one column will always reach such a boundary while the others haven't yet. So that column will go down, and also begin reverting its movement. The other columns will then "catch up" later. So not only do they move down per column, the columns will also end up moving through one another.
You'll have to implement some logic to have your aliens move as a block, by detecting when the rightmost remaining alien has reached the right boundary, or the leftmost remaining alien has reached the left boundary, and then doing an update on all aliens to move down.
The idea of having each alien have its own state, putting the logic for controlling it in the alien class and calling that is actually good object-oriented design. It just so happens that for Space Invaders, the aliens all affect one another because they move in a block. As a result, your design results in them having too much individuality. Perhaps you can add some class that maintains state for the invader array as a whole (such as the leftmost and rightmost column still having an alien, direction of the entire block), control that in your movement loop and have it update the alien's location in turn.

Differentiating between highlighted and regular chessboard squares

I have a chessboard, made by overriding the paint() method of a class extending Panel. I highlight all the possible squares a chess piece can go to on the board, and store the pixel values of the upper left corners of the highlighted squares in the:
private ArrayList<Integer> highlightedSquares = new ArrayList<Integer>();
topLeftVal is an array with all of the top left corner values of the squares. In the mouseClicked method of the mouseAdapter, I want to know when a highlighted square (and only a highlighted square) is clicked, and then call repaint(). However, for some reason the program also accepts many squares that are not highlighted.
Here is the code (I apologize for the formatting):
public void mouseClicked(MouseEvent e){
clickPointX = e.getX();
clickPointY = e.getY();
//iterate through highlightedSquares and if the clicked pt is in one of them, repaint
int q = 0;
int xCoor = 0, yCoor = 0;
for(int a : highlightedSquares){
if(q % 2 == 0)
xCoor = a;
else{
yCoor = a;
if((xCoor <= clickPointX) && (clickPointX <= (xCoor + 80)) && (yCoor <= clickPointY) && (clickPointY <= (yCoor + 80))){ //I think this line is causing the problem?
_pixX=xCoor;
_pixY=yCoor;
for(int i = 0; i < topLeftVal.length;i++){
if(topLeftVal[i] == _pixX)
_x = i;
if(topLeftVal[i] == _pixY)
_y = i;
}
repaint();
break;
} //end of if inside else
} //end of else
q++;
} //end of foreach
} //end of mouseClicked
Here is an example implementation where I defined two classes -- Board and Square. Board is derived from JPanel. Square represents a single square on the board. My mouse click listener displays a message which indicates whether or not the clicked upon square is highlighted. Hopefully this will give you a good idea of how to modify your code to achieve the desired result.
public class TestMain {
public static void main(String[] args) throws Exception {
new TestMain().run();
}
public void run() {
// create and show a JFrame containing a chess board
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Board board = new Board();
board.getSquare(2, 4).setHighlighted(true);
board.getSquare(3, 4).setHighlighted(true);
window.getContentPane().add(board, BorderLayout.NORTH);
window.pack();
window.setVisible(true);
}
// *** Board represents the chess board
private class Board extends JPanel {
// *** the constructor creates the squares and adds a mouse click listener
public Board() {
setPreferredSize(new Dimension(squareSize * 8, squareSize * 8));
// create the squares
boolean rowStartRedFlag = true;
for (int row = 0; row < 8; row++) {
boolean redFlag = rowStartRedFlag;
for (int column = 0; column < 8; column++) {
squares [row] [column] = new Square(this, row, column, redFlag);
redFlag = !redFlag;
}
rowStartRedFlag = !rowStartRedFlag;
}
// add mouse click listener
this.addMouseListener(new MouseClickListener());
}
// *** mouse click listener
private class MouseClickListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
Square square = getSquareAt(e.getX(), e.getY());
String msg = square.isHighlighted() ? "Square is highlighted" : "Square is not highlighted";
JOptionPane.showMessageDialog(null, msg);
}
}
// ** override paint
#Override
public void paint(Graphics g) {
draw ((Graphics2D) g);
}
// *** draw every square on the board
public void draw(Graphics2D g) {
for (int row = 0; row < squares.length; row++) {
for (int column = 0; column < squares [row].length; column++) {
squares [row] [column].draw(g);
}
}
}
// *** get square given row and column
public Square getSquare(int row, int column) {
return squares [row] [column];
}
// *** get square from coords
public Square getSquareAt(int x, int y) {
int column = getColumnAtX(x);
int row = getRowAtY(y);
return squares [row] [column];
}
// *** get column # given x
public int getColumnAtX(int x) {
int column = x / squareSize;
return Math.min(Math.max(column, 0), 7);
}
// *** get row # given x
public int getRowAtY(int y) {
int row = y / squareSize;
return Math.min(Math.max(row, 0), 7);
}
// ** get left x given column
public int getLeftFromColumn(int column) {
return column * squareSize;
}
// ** get top y give row
public int getTopFromRow(int row) {
return row * squareSize;
}
// *** get size of square side
public int getSquareSize() {
return squareSize;
}
private int squareSize = 25; // length of square side
private Square [][] squares = new Square [8][8];
}
// *** Squalre represents one square on the board
private class Square {
// ** constructor creates the square
public Square(Board board, int row, int column, boolean redFlag) {
this.board = board;
this.column = column;
this.row = row;
if (redFlag) {
color = Color.RED;
colorHighlighted = Color.PINK;
} else {
color = Color.BLACK;
colorHighlighted = Color.LIGHT_GRAY;
}
}
// ** set highlight flag
public void setHighlighted(boolean value) {
highlighted = value;
}
// *** see if square is highlighted
public boolean isHighlighted() {
return highlighted;
}
// *** draw the square
public void draw(Graphics2D g) {
Color fillColor = highlighted ? colorHighlighted : color;
g.setColor(fillColor);
int x = board.getLeftFromColumn(column);
int y = board.getTopFromRow(row);
int size = board.getSquareSize();
g.fillRect(x, y, size, size);
}
private Board board;
private Color color;
private Color colorHighlighted;
private int column;
private boolean highlighted = false;
private int row;
}
}

Android Sprite Animation Move To position X (should be simple but, I'm stuck)

I'm trying to move sprites to stop the frames in center(or move them to certain x position) when right or left pressed on screen. There are 3 sprites created using box.java in the view, placed one after another with padding, stored in arraylist.
The problem: No smooth movement and doesn't stop in the center of each frames after movement has begun, sometimes all boxes are moving on top of each others, padding is totally lost. Please let me know what I'm doing wrong, thanks a lot!
//BEGINING OF BOX.JAVA >> The problem is in this class!
//This goes in Update();
private void boxMove()
{
int get_moved_pos = getMovedPos(); //get moved pos
int sprite_size = view.getSpriteSize(); //get sprite arraylist size
currentDirection = view.getDirection(); //get direction "left" or "right" from view
if(currentDirection == "right" && isMoving == false)
{
setSpriteMovedNext();
}else
if(currentDirection == "left" && isMoving == false)
{
setSpriteMovedPrev();
}
if(currentDirection != lastDirection)
{
lastDirection = currentDirection;
//MOVE RIGHT
if(currentDirection == "right" && get_moved_pos > 0) //move left and make sure that moved pos isn't overlapping / or moving to empty space
{
//Animate left until it reaches the new x position
if(x > get_new_pos_left)
{
x -= pSpeedX;
}
Log.d("RIGHT","POS: " + get_moved_pos);
}else
//MOVE LEFT
if(currentDirection == "left" && get_moved_pos < sprite_size-1) //move left and make sure that moved pos isn't overlapping / or moving to empty space
{
//Animate right until it reaches the new x position
if(x < get_new_pos_right)
{
x += pSpeedX;
}
}
}
}
//Call when screen is touched (in View.java), to set a new position to move to.
public void resetMoving()
{
isMoving = false;
this.lastDirection = "";
Log.d("RESET", "MOVING RESET");
}
public int getMovedPos()
{
return this.smoved_pos;
}
private void setSpriteMovedNext()
{
int get_max_moved = getMovedPos();
int s_size = view.getSpriteSize();
if (isMoving == false) //take a break between movements
{
if(get_max_moved < s_size-1)
{
Log.d("NEXT", "CALLED");
this.get_new_pos_right = x + view.getNextPosX(); //current x and next stop position
this.smoved_pos += 1;
this.isMoving = true; //set to avoid double touch
Log.d("NEXT", "X POS SET: " + get_max_moved);
}
}
}
private void setSpriteMovedPrev()
{
int get_max_moved = getMovedPos();
if (isMoving == false) //take a break between movements
{
if(get_max_moved > 0)
{
Log.d("PREV", "CALLED");
this.get_new_pos_left = x - view.getNextPosX(); //get current x pos and prev stop position
this.smoved_pos -= 1; //to limit the movements
this.isMoving = true; //set to avoid double touch
Log.d("PREV", "X POS SET: " + get_max_moved);
}
}
}
//END OF BOX.JAVA
//VIEW
//Add boxes
public void addBox()
{
int TOTAL_BOXES = 3;
int padding_left = 200;
int padding_tmp = this.getWidth()/2;
box.clear(); //clear old
//Box 1
box.add(new Boxes(box, this, "box1",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 0, 0));
padding_tmp += boxSpriteImage.getWidth()/TOTAL_BOXES + padding_left;
//Box 2
box.add(new Boxes(box, this, "box2",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 1, 1));
padding_tmp += boxSpriteImage.getWidth()/TOTAL_BOXES + padding_left;
//Box 3
box.add(new Boxes(box, this, "box3",
padding_tmp,
this.getHeight()/2,
boxSpriteImage, 1, 2, 2, 1));
}
public boolean onTouchEvent(MotionEvent event){
if (System.currentTimeMillis() - lastClick > 100){
lastClick = System.currentTimeMillis();
float x = event.getX();
float y = event.getY();
synchronized (getHolder())
{
if(isBoxWindow() == true)
{
if(x >= this.getWidth()/2)
{
Direction = "right";
}else
{
Direction = "left";
}
}
}
}
//called in box.java to get next x pos to move
public float getNextPosX()
{
int PADDING = 200; //padding between frames
next_pos_x = boxSprite.getWidth()/TOTAL_COLUMNS + PADDING;
return next_pos_x;
}
I think your error is in the if statements, where you compare currentDirection and lastDirection (I'm assuming that lastDirection is a String) with other Strings using the == operator. The == almost operator never works when you want to compare Objects for equality. You should use the equals() method.
For eg.
if(currentDirection != lastDirection)
should be written as:
if(!currentDirection.equals(lastDirection)
Make such changes in your code(They are needed at many places!) and I think your problem should be solved.
A good debugging practice would be logging data about your app, from each of the if blocks, to see if each of them is executed. You could have found out if your if statements are being executed.
EDIT: Why have you put this code?
if (System.currentTimeMillis() - lastClick > 100)
This means onTouchEvents are only interpreted after 100ms. remove it and check, probably that's what is causing the problem.
Alrite, decided to use onFling() method and call via View instead of adding the animations separately into the class itself, works really well when called box.get(i).update() in a loop of all added boxes, all of them animated equally. Thanks udiboy.

getting my ovals to stack up on each column [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
issue with my main method in my connect4 game
Hi,
on my connect4 game, whenever i click on any square it places the oval on that specific square, how do i get it so that it places the oval on the lowest square in that column so that it can stack up?
package Game;
import java.util.ArrayList;
public class ConnectFourBoard {
// This constant is used to indicate the width and height, in cells,
// of the board. Since we want an 8x8 board, we'll set it to 8.
private static final int WIDTH = 8;
private static final int HEIGHT = 8;
private ConnectFourCell[][] currentPlayer;
// The current state the Othello board is defined with these two
// fields: a two-dimensional array holding the state of each cell,
// and a boolean value indicating whether it's the black player's
// turn (true) or the white player's turn (false).
private ConnectFourCell[][] cells;
private boolean isBlueTurn;
// Since the board is a model and it needs to notify views of changes,
// it will employ the standard "listener" mechanism of tracking a list
// of listeners and firing "events" (by calling methods on those
// listeners) when things change.
private ArrayList<ConnectFourListener> listeners;
public ConnectFourBoard()
{
// Arrays, in Java, are objects, which means that variables of
// array types (like cells, which has type OthelloCell[][]) are
// really references that say where an array lives. By default,
// references point to null. So we'll need to create an actual
// two-dimensional array for "cells" to point to.
cells = new ConnectFourCell[WIDTH][HEIGHT];
listeners = new ArrayList<ConnectFourListener>();
reset();
isBlueTurn = true;
}
public void reset(){
for (int i = 0; i<WIDTH ; i++){
for (int j = 0; j<HEIGHT; j++){
cells[i][j] = ConnectFourCell.NONE;
}
}
isBlueTurn = true;
}
public void addConnectFourListener(ConnectFourListener listener)
{
listeners.add(listener);
}
public void removeConnectFourListener(ConnectFourListener listener)
{
if (listeners.contains(listener))
{
listeners.remove(listener);
}
}
// These are fairly standard "fire event" methods that we've been building
// all quarter, one corresponding to each method in the listener interface.
private void fireBoardChanged()
{
for (ConnectFourListener listener : listeners)
{
listener.boardChanged();
}
}
private void fireGameOver()
{
for (ConnectFourListener listener : listeners)
{
listener.gameOver();
}
}
// isBlackTurn() returns true if it's the black player's turn, and false
// if it's the white player's turn.
public boolean isBlueTurn()
{
return isBlueTurn;
}
public int getWidth()
{
return WIDTH;
}
public int getHeight(){
return HEIGHT;
}
// getBlackScore() calculates the score for the black player.
public int getBlackScore()
{
return getScore(ConnectFourCell.BLUE);
}
// getWhiteScore() calculates the score for the white player.
public int getWhiteScore()
{
return getScore(ConnectFourCell.RED);
}
// getScore() runs through all the cells on the board and counts the
// number of cells that have a particular value (e.g., BLACK or WHITE).
// This method uses the naive approach of counting them each time
// it's called; it might be better to keep track of this score as we
// go, updating it as tiles are added and flipped.
private int getScore(ConnectFourCell cellValue)
{
int score = 0;
for (int i = 0; i < WIDTH; i++)
{
for (int j = 0; j < HEIGHT; j++)
{
if (cells[i][j] == cellValue)
{
score++;
}
}
}
return score;
}
// getWhiteScore() calculates the score for the white player.
public int getRedScore()
{
return getScore(ConnectFourCell.RED);
}
public int getBlueScore() {
// TODO Auto-generated method stub
return getScore(ConnectFourCell.BLUE);
}
public ConnectFourCell getCell(int x, int y)
{
if (!isValidCell(x, y))
{
throw new IllegalArgumentException(
"(" + x + ", " + y + ") is not a valid cell");
}
return cells[x][y];
}
/**
* The drop method.
*
* Drop a checker into the specified HEIGHT,
* and return the WIDTH that the checker lands on.
*/
int drop(int HEIGHT) {
if (hasWon()) {
return -1;
}
for ( ; WIDTH<6 && HEIGHT != 0; WIDTH++) { };
if (WIDTH==6) {
// if the WIDTH is 6, it went through all 6 WIDTHs
// of the cells, and couldn't find an empty one.
// Therefore, return false to indicate that this
// drop operation failed.
return -1;
}
// fill the WIDTH of that HEIGHT with a checker.
cells[HEIGHT][WIDTH] = currentPlayer[HEIGHT][WIDTH];
// alternate the players
//currentPlayer = (currentPlayer%2)+1;
return WIDTH;
}
/**
* The toString method
*
* Returns a String representation of this
* Connect Four (TM) game.
*/
public String toString() {
String returnString = "";
for (int WIDTH=5; WIDTH>=0; WIDTH--) {
for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
returnString = returnString + cells[HEIGHT][WIDTH];
}
returnString = returnString + "\n";
}
return returnString;
}
/**
* The hasWon method.
*
* This method returns true if one of the
* players has won the game.
*/
public boolean hasWon()
{
// First, we'll establish who the current player and the opponent is.
//ConnectFourCell
ConnectFourCell myColor =
isBlueTurn() ? ConnectFourCell.BLUE : ConnectFourCell.RED;
ConnectFourCell otherColor =
isBlueTurn() ? ConnectFourCell.RED : ConnectFourCell.BLUE;
return true;
}
public void validMove( ){
}
public void makeAMove(int x, int y){
//System.out.println(x+" "+y);
// cells[x][y] = ConnectFourCell.BLUE;
//Check who's turn it is. Set to that color.
ConnectFourCell myColor = null;
if ( isBlueTurn == true){
myColor = myColor.BLUE;
}
else {
myColor = myColor.RED;
}
cells[x][y] = myColor;
//Check if it's a valid move. If there is a piece there. can't
// Look at the column. play piece in the highest available slot
//Check if there are 4 in a row.
for (int WIDTH=0; WIDTH<6; WIDTH++) {
for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH]) {
}
}
}
// check for a vertical win
for (int WIDTH=0; WIDTH<3; WIDTH++) {
for (int HEIGHT=0; HEIGHT<7; HEIGHT++) {
if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+1] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+2] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT][WIDTH+3]) {
}
}
}
// check for a diagonal win (positive slope)
for (int WIDTH=0; WIDTH<3; WIDTH++) {
for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH+1] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH+2] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH+3]) {
}
}
}
// check for a diagonal win (negative slope)
for (int WIDTH=3; WIDTH<6; WIDTH++) {
for (int HEIGHT=0; HEIGHT<4; HEIGHT++) {
if (!(cells[HEIGHT][WIDTH] == ConnectFourCell.NONE) &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+1][WIDTH-1] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+2][WIDTH-2] &&
cells[HEIGHT][WIDTH] == cells[HEIGHT+3][WIDTH-3]) {
}
}
}
fireBoardChanged();
isBlueTurn = !isBlueTurn;
}
private boolean isValidCell(int x, int y)
{
return x >= 0 && x < WIDTH
&& x>= 0 && x<HEIGHT
&& y >= 0 && y < WIDTH
&& y>= 0 && y<HEIGHT;
}
}
package UI;
import java.awt.*;
import javax.swing.*;
import UI.ConnectFourBoardPanel;
import Game.ConnectFourBoard;
import Game.ConnectFourListener;
public class ConnectFourFrame extends JFrame implements ConnectFourListener {
// Variables
private ConnectFourBoard board;
private JLabel scoreLabel;
private ConnectFourBoardPanel boardPanel;
private JLabel statusLabel;
public ConnectFourFrame()
{
// The frame builds its own model.
board = new ConnectFourBoard();
// We want the frame to receive notifications from the board as its
// state changes.
System.out.println(this);
board.addConnectFourListener(this);
setTitle("Informatics 45 Spring 2011: ConnectFour Game");
setSize(700, 700);
setResizable(true);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
getContentPane().setBackground(Color.BLACK);
buildUI();
refreshUI();
}
private void buildUI()
{
GridBagLayout layout = new GridBagLayout();
getContentPane().setLayout(layout);
Font labelFont = new Font("SansSerif", Font.BOLD, 18);
scoreLabel = new JLabel();
scoreLabel.setForeground(Color.WHITE);
scoreLabel.setFont(labelFont);
layout.setConstraints(
scoreLabel,
new GridBagConstraints(
0, 0, 1, 1, 1.0, 0.0,
GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets(10, 10, 10, 10), 0, 0));
getContentPane().add(scoreLabel);
boardPanel = new ConnectFourBoardPanel(board);
layout.setConstraints(
boardPanel,
new GridBagConstraints(
0, 1, 1, 1, 1.0, 1.0,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets(10, 10, 10, 10), 0, 0));
getContentPane().add(boardPanel);
statusLabel = new JLabel();
statusLabel.setForeground(Color.WHITE);
statusLabel.setFont(labelFont);
layout.setConstraints(
statusLabel,
new GridBagConstraints(
0, 2, 1, 1, 1.0, 0.0,
GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets(10, 10, 10, 10), 0, 0));
getContentPane().add(statusLabel);
}
private void refreshUI()
{
// Refreshing the UI means to change the text in each of the
// two labels (the score and the status) and also to ask the
// board to repaint itself.
scoreLabel.setText(
"Blue: " + board.getBlueScore() +
" Red: " + board.getRedScore());
if ( board.isBlueTurn() == false){
statusLabel.setText("Blue's Turn: ");
}
if ( board.isBlueTurn() == true){
statusLabel.setText("Red's Turn: ");
}
boardPanel.repaint();
}
// These are the ConnectFourBoardListener event-handling methods.
public void boardChanged()
{
// When the board changes, we'll refresh the entire UI. (There
// are times when this approach is too inefficient, but it will
// work fine for our relatively simple UI.)
refreshUI();
}
public void gameOver()
{
// When the game is over, we'll pop up a message box showing the final
// score, then, after the user dismisses the message box, dispose of
// this window and end the program.
JOptionPane.showMessageDialog(
this,
"Game over!\nFinal score: " + scoreLabel.getText(),
"Game Over",
JOptionPane.INFORMATION_MESSAGE);
dispose();
}
}
Welcome to StackOverflow. You're question is fine - but pasting your whole program, in general, is a bad idea. You should describe your program, and include the snippet where you calculate how the ovals are filled in.
Having said that, here's a crack at the answer :
- You want to look at the tile thats currently selected, and if the tile underneath it is occupied, fill in that cell. If its not occupied, set the current tile to the underneath tile, and repeat. You want to do this until you get to the bottom row.
The answer above doesn't incude checking if the selected tile is already occupied, but I'm sure you can easily figure that out.

Categories

Resources