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;
}
}
Related
Relatively new to Java, coding for a school project.
I'm using JFrame and JComponent, drawing patterns and strings and all that fun stuff.
Currently, I have a class written that extends JComponent. This is the class where I am defining most of my shapes. The issue is that I initialized my Jframe
(Code: JFrame myFrame = new JFrame() ) in the main of one class, but I need to access myFrame.getWidth() in the JComponent class that I'm working in.
How can I access variables getWidth() and getHeight() in "public class MyJComponent extends JComponent" , when I defined myFrame in 'public class Lab2' ??
Edit for code:
public class Lab2 {
public static void main(String[] args) {
System.out.println("Hello Java");
JFrame myFrame = new JFrame();
myFrame.setSize(500, 500);
myFrame.setTitle("Color Test");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyJComponent myComponent = new MyJComponent(500, 500);
myFrame.add(myComponent);
myFrame.getContentPane().setBackground(Color.white); //sets background color.
myFrame.setVisible(true); // setVisible() *after* add() is the norm
//Deciding geometry of hidden shape. paintComponent is called once per run, this is called afterwards.
}
}
/**/
public class MyJComponent extends JComponent {
int[] circleX;
int[] circleY;
int[] circleR;
final int MIN_RADIUS = 5;
final int MAX_RADIUS = 15;
final int MIN_SEPARATION = 1;
final int MAX_ATTEMPTS = 5000;
final int MAX_CIRCLES = 1000;
Random rand;
int initialWidth;
int initialHeight;
int numCircles; // actual number of circles drawn
// are circles at index i and index j separated by *<= tolerance* pixels?
boolean twoCirclesOverlap(int i, int j, int tolerance) {
double distanceBetweenCenters =
Math.sqrt((circleX[i] - circleX[j]) * (circleX[i] - circleX[j]) +
(circleY[i] - circleY[j]) * (circleY[i] - circleY[j]));
return (distanceBetweenCenters <= (circleR[i] + circleR[j] + tolerance));
}
// are any existing circles separated from the proposed one at index i by *<= tolerance* pixels?
boolean anyCirclesOverlap(int i, int tolerance) {
for (int j = 0; j < i; j++) {
if (twoCirclesOverlap(i, j, tolerance)) {
return true;
}
}
return false;
}
// attempt to randomly place the largest-possible circle that does not overlap any existing one
boolean tryToPlaceCircle(int i) {
for (int j = 0; j < MAX_ATTEMPTS; j++) {
// pick a random position, set initial radius to minimum
circleX[i] = rand.nextInt(initialWidth);
circleY[i] = rand.nextInt(initialHeight);
circleR[i] = MIN_RADIUS;
// grow circle until it touches another or reaches max size
while (!anyCirclesOverlap(i, MIN_SEPARATION) && circleR[i] < MAX_RADIUS)
circleR[i]++;
// it was touching from the start -- must try again
if (circleR[i] == MIN_RADIUS) {
continue;
}
// grew to max size -- well done
else if (circleR[i] == MAX_RADIUS) {
return true;
}
// grew some, but then touched
else {
circleR[i]--; // retract to the step before touch
return true;
}
}
// all attempts failed
return false;
}
MyJComponent(int width, int height) {
circleX = new int[MAX_CIRCLES];
circleY = new int[MAX_CIRCLES];
circleR = new int[MAX_CIRCLES];
initialWidth = width;
initialHeight = height;
rand = new Random();
numCircles = 0;
while (numCircles < MAX_CIRCLES && tryToPlaceCircle(numCircles)) {
numCircles++;
}
}
//Override paintComponent
public void paintComponent(Graphics g) {
for (int i = 0; i < numCircles; i++) {
g.drawOval(circleX[i] - circleR[i], circleY[i] - circleR[i], 2 * circleR[i], 2 * circleR[i]);
}
}
//Shape decision
public void shapeDecision() {
double randomShapeDecider = Math.random();
if (randomShapeDecider > .50) {
//shape is circle, define it's properties
hiddenCircleDiameter = myFrame.getWidth();
}
else {
//shape is rectangle
hiddenRectangleWidth = myFrame.getWidth();
}
}
}
How do use methods for the elements of a 2d array?
I have a class board, and initialized a 2d array with type cell. Essentially, I want to use the cell elements, and use the methods from that class.
However, I am unsure how to implement that, because I get an error when I try
board[1][1].cellmethod()
CODE for BOARD:
public class Board {
private int col = 1, row= 1;
private cell[][] board;
private RandomNumberGenerator rand = new RandomNumberGenerator();
public Board(){
board = new cell[col][row];
//Initialize board with cells
for (int r = 0 ; r<=row; r++){
for(int c = 0; c<= col; c++){
board[c][r] = new cell(rand.getRandIntBetween(1,6), translateOffsetToPixel(c,r).getX(), translateOffsetToPixel(c,r).getY());
}
}
}
CELL CLASS
public class cell {
//which shape the cell will consist
private int shape;
//offset of where the cell is located by cell number -> need to translate the given coordinates to pixel
private int x, y;
private int SHAPE_WIDTH = 50; //Width of each shape (pixels)
private int SHAPE_HEIGHT = 50; //Height of each shape (pixels)
private Rect rect;
private boolean visible;
public cell(int shape, int x, int y){
this.shape = shape;
this.x = x;
this.y = y;
rect = new Rect( x, y, x + SHAPE_WIDTH, y + SHAPE_HEIGHT);
visible = false;
}
public int getX() {return x;}
public int getY() {return y;}
public int getShape() {return shape;}
}
WHERE I CALL the BOARD OBJECT
public class PlayState extends State{
private Board board;
#Override
public void init() {
board = new Board();
}
#Override
public void update(float delta) {
}
#Override
public void render(Painter g) {
for(int r = 0; r<=board.getRow(); r++){
for(int c = 0; c<=board.getCol(); c++){
board[0][0]. // ERROR, can't implement any cell methods
}
}
}
Your board array is of size one (row and column).
private int col = 1, row= 1;
So, your board has only one element available at board[0][0], the first row and first column. Accessing board[1][1] hence throws an ArrayIndexOutOfBoundsException.
Remember that an array index can have a maximum value of array.length - 1 only.
In your actual implementation
board = new Board();
board is not an array; it's a Board object. So, obviously you can't access it with indices [][]. You need to expose the underlying board[][] through a getter method.
public cell[][] getBoard() {
return board;
}
Then you can use the getter in your render() method as
#Override
public void render(Painter g) {
cell[][] boardArr = board.getBoard();
for(int r = 0; r<=board.getRow(); r++){
for(int c = 0; c<=board.getCol(); c++){
boardArr[r][c].cellMethod();
}
}
}
You need to use:
board.board[0][0].cellMethod();
while first board is an instance of Board class, board.board refers to the two dimensional array.
I have used board.board but you can use a getter method to access it if you need to keep it private.
With an array size of 1x1, you can only store one element, at [0][0]. I've changed the array size for you in your code, try this code and see if this works.
CODE for BOARD:
public class Board
{
private int col = 50, row= 50;
private cell[][] board;
private RandomNumberGenerator rand = new RandomNumberGenerator();
public Board()
{
board = new cell[col][row];
//Initialize board with cells
for (int r = 0 ; r<=row; r++)
{
for(int c = 0; c<= col; c++)
{
board[c][r] = new cell(rand.getRandIntBetween(1,6), translateOffsetToPixel(c,r).getX(), translateOffsetToPixel(c,r).getY());
}
}
}
Just a quick tip
Also, I've found that it makes the readability of code easier if the brackets are placed on the next line after the function for a more aligned look. Like this (and I've also fixed your code accordingly):
int fibonacci(int n)
{
//code...
}
Hey everyone thanks for all the help so far !. I have finally finished this project and it runs fine in eclipse but when I export it I get this error from stack trace also any help on how this could be improved in terms of architecture is much appreciated.
Exception is Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeExcepti
on: com.badlogic.gdx.utils.GdxRuntimeException: File not found: assets\font.fnt
It runs fine in eclipe but fails when exported
public class ConnectFourApplication extends Game implements ApplicationListener {
private Screen screen;
private Game game;
public static void main(String[] args) {
new LwjglApplication(new ConnectFourApplication(), "PennyPop", 1280, 720,
true);
}
public ConnectFourApplication(){
game = this;
}
#Override
public void create() {
screen = new MainScreen(game);
setScreen(screen);
screen.show();
}
#Override
public void dispose() {
screen.hide();
screen.dispose();
}
/** Clears the screen with a white color */
private void clearWhite() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
}
#Override
public void pause() {
screen.pause();
}
#Override
public void render() {
clearWhite();
super.render();
}
#Override
public void resize(int width, int height) {
screen.resize(width, height);
}
#Override
public void resume() {
screen.resume();
}
public class MainScreen implements Screen {
private final Stage stage;
private final SpriteBatch spriteBatch;
//Parameter for drawing the buttons
private final BitmapFont font;
private final TextureAtlas buttons;
private final Button SFXButton;
private final Button APIButton;
private final Button GameButton;
private final Skin images;
//Parameter for Sound
private final com.badlogic.gdx.audio.Sound SFXClick;
//Parameter for the api call
private final String WeatherUrl;
private final HttpRequest request;
private final City SanFrancisco;
//The screen to load after the game button is hit
private Screen gamescreen;
private Game game;
public MainScreen(Game game) {
this.game = game;
//Set up our assets
spriteBatch = new SpriteBatch();
stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, spriteBatch);
font = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
buttons = new TextureAtlas("assets/GameButtons.pack");
images = new Skin(buttons);
images.addRegions(buttons);
SFXButton = new Button(images.getDrawable("sfxButton"));
SFXButton.setPosition(295, 310);
APIButton = new Button(images.getDrawable("apiButton"));
APIButton.setPosition(405, 310);
GameButton = new Button(images.getDrawable("gameButton"));
GameButton.setPosition(515, 310);
SFXClick = Gdx.audio.newSound(Gdx.files.internal("assets/button_click.wav"));
//Add our actors to the stage
stage.addActor(SFXButton);
stage.addActor(APIButton);
stage.addActor(GameButton);
//Set up our Url request to be used when clicking the button
WeatherUrl = "http://api.openweathermap.org/data/2.5/weather?q=San%20Francisco,US";
request = new HttpRequest(HttpMethods.GET);
request.setUrl(WeatherUrl);
SanFrancisco = new City("Unavailable","Unavailable","0","0"); //init san fran to be displayed before they have clicked the button
}
#Override
public void dispose() {
spriteBatch.dispose();
stage.dispose();
}
#Override
public void render(float delta) {
stage.act(delta);
stage.draw();
//Begin sprite batch
spriteBatch.begin();
//Set our on click listeners for our buttons
if (SFXButton.isPressed())
SFXClick.play();
if(APIButton.isPressed())
{
CallApi();
}
if(GameButton.isPressed())
LoadGame();
//Set font color and render the screen
font.setColor(Color.RED);
font.draw(spriteBatch, "PennyPop", 455 - font.getBounds("PennpyPop").width/2,
460 + font.getBounds("PennyPop").height/2);
font.setColor(Color.BLACK);
font.draw(spriteBatch, "Current Weather", 900 - font.getBounds("PennpyPop").width/2,
460 + font.getBounds("PennyPop").height/2);
font.setColor(Color.LIGHT_GRAY);
font.draw(spriteBatch, SanFrancisco.Name, 940 - font.getBounds("PennpyPop").width/2,
420 + font.getBounds("PennyPop").height/2);
font.setColor(Color.RED);
font.draw(spriteBatch, SanFrancisco.CurrentCondition, 950 - font.getBounds("PennpyPop").width/2,
300 + font.getBounds("PennyPop").height/2);
font.draw(spriteBatch, SanFrancisco.Temperature + " Degrees,", 920 - font.getBounds("PennpyPop").width/2,
270 + font.getBounds("PennyPop").height/2);
font.draw(spriteBatch, SanFrancisco.WindSpeed, 1200 - font.getBounds("PennpyPop").width/2,
270 + font.getBounds("PennyPop").height/2);
//End or sprite batch
spriteBatch.end();
}
//Handles calling our API
public void CallApi(){
//Sends our stored HTTPRequest object
Gdx.net.sendHttpRequest(request, new HttpResponseListener() {
#Override
public void handleHttpResponse(HttpResponse httpResponse) {
//Uses our private response reader object to give us a the JSON from the api call
JSONObject json = HttpResponseReader(httpResponse);
//Gets the name of the city
SanFrancisco.Name = (String) json.get("name");
//Parsed through our returned JSON for the weather key
JSONArray WeatherArray = (JSONArray) json.get("weather");
//Gets the actual weather dictionary
JSONObject Weather = (JSONObject) WeatherArray.get(0);
//Finally get the value with the key of description and assign it
//To the San Fran current conditions field
SanFrancisco.CurrentCondition = (String) Weather.get("description");
//Gets the actual main dictionary
JSONObject main = (JSONObject) json.get("main");
//Finally get the values based on the keys
SanFrancisco.Temperature = (String) Double.toString((double) main.get("temp"));
//Finally get the wind speed
JSONObject wind = (JSONObject) json.get("wind");
SanFrancisco.WindSpeed = (String) Double.toString((double) wind.get("speed"));
}
#Override
public void failed(Throwable t) {
Gdx.app.log("Failed ", t.getMessage());
}
});
}
//When the button game button is clicked should load the connect four game
public void LoadGame(){
game.setScreen(new GameScreen(game));
}
//Converts our HttpResponse into a JSON OBject
private static JSONObject HttpResponseReader(HttpResponse httpResponse){
BufferedReader read = new BufferedReader(new InputStreamReader(httpResponse.getResultAsStream()));
StringBuffer result = new StringBuffer();
String line = "";
try {
while ((line = read.readLine()) != null) {
result.append(line);
}
JSONObject json;
try {
json = (JSONObject)new JSONParser().parse(result.toString());
return json;
} catch (ParseException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
public void resize(int width, int height) {
stage.setViewport(width, height, false);
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void show() {
Gdx.input.setInputProcessor(stage);
render(0);
}
#Override
public void pause() {
// Irrelevant on desktop, ignore this
}
#Override
public void resume() {
// Irrelevant on desktop, ignore this
}
public class GameScreen implements Screen {
//Our stage and sprites
private final Stage gamestage;
private final SpriteBatch gamesprites;
//Parameter for drawing the pieces
private final BitmapFont gamefont;
private final TextureAtlas pieces;
private final Skin piecesskin;
//this will be the sprite and texture for our red connect four buttons
private Texture redtexture;
private Sprite redsprite;
//this will be the sprite and texture for our red connect four buttons
private Texture yellowtexture;
private Sprite yellowsprite;
//Setup the board
//renders the line
private ShapeRenderer boardlineshape;
//setup the line locations
private int linestartx;
private int linestarty;
private int lineendx;
private int lineendy;
private int linexdistance;
private int lineydistance;
//for this game we will define a board size as the amount of lines the board should contain
private double boardsize;
//Lines required to win
private int linestowin;
private String playersturnstring;
private OrthographicCamera camera;
//Holds all the parameters for our players
//Keeps track of who's turn it is, if 0 player one if 1 player two
private int playersturn;
//Holds the location of all of player ones pieces
//Needs to be two Dimensional to hold x and y values
private int[][] playeronepieces;
private int playeronepieceindex;
//Holds the location of all of player twos pieces
//Needs to be two Dimensional to hold x and y values
private int[][] playertwopieces;
private int playertwopieceindex;
//make the number of pieces per player variable so it can be changed for the future
private int numberofpiecesperplayer;
private Game game;
public boolean gameover;
private boolean isready;
private int[][] RowsAndColumns;
private int columnvalue = 538;
public GameScreen(Game game){
this.game = game;
//Set up our assets
gamesprites = new SpriteBatch();
gamestage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, gamesprites);
//Sets up our font
gamefont = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
pieces = new TextureAtlas("assets/GameButtons.pack");
piecesskin = new Skin(pieces);
piecesskin.addRegions(pieces);
//set up our camera
camera= new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.setToOrtho(true, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.update();
//sets up our red connect four piece
redtexture = new Texture(Gdx.files.internal("assets/red.png"));
redsprite = new Sprite(redtexture);
//sets up our yellow connect four piece
yellowtexture = new Texture(Gdx.files.internal("assets/yellow.png"));
yellowsprite = new Sprite(yellowtexture);
//setup the board
SetUpGameBoard(8,4,Color.BLACK);
linestartx = 300;
linestarty = 100;
lineendx = 300;
lineendy = 600;
linexdistance = 100;
lineydistance = 100;
//setup the pieces
numberofpiecesperplayer = 60;
//initialize anything else we need for the game
playersturnstring = "";
//start with player one's turn
playersturn = 0;
//setup or pieces locations as blank
playeronepieces = new int[2][numberofpiecesperplayer]; //create two arrays one for x values one for y
playeronepieceindex = 0;
playertwopieces = new int[2][numberofpiecesperplayer]; //create two arrays one for x values one for y
playertwopieceindex = 0;
gameover = false;
isready = false;
linestowin = 4;
}
//Should initialize our game board
public void SetUpGameBoard(int boardsize,int linestowin, Color linecolor){
this.boardsize = boardsize;
this.linestowin = linestowin;
boardlineshape = new ShapeRenderer();
boardlineshape.setProjectionMatrix(camera.combined);
boardlineshape.setColor(linecolor);
//holds the board cells
RowsAndColumns = new int[2][(int) boardsize];
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void render(float delta) {
//set the stage
gamestage.act(delta);
gamestage.draw();
//if the mouse is clicked and the game is not over send us back to the main screen
if (Gdx.input.justTouched() && gameover == true){
//if the game is over and the user clicks send us back to the main screen
game.setScreen(new MainScreen(game));
}
if(isready){
//if the mouse is clicked and the game is not over add a piece to player one
if (Gdx.input.justTouched() && gameover != true){
AddPiece(Gdx.input.getX(), Gdx.input.getY());
}
}
//Draw our board
boardlineshape.begin(ShapeType.Line);
///Draw all of the lines for our board
DrawBoard(linestartx,linestarty,lineendx,lineendy);
boardlineshape.end();
//Starts our game sprite batch
gamesprites.begin();
//Draw all of player ones pieces
DrawPlayerOnePieces();
//Draw all of player twos pieces
DrawPlayerTwoPieces();
gamefont.draw(gamesprites, playersturnstring, 515, 650);
//End our game sprite batch
gamesprites.end();
//Lastly check to make sure our the game is not over
CheckForGameOver();
isready = true;
}
//draw the board
private void DrawBoard(int linestartx, int linestarty, int lineendx, int lineendy){
camera.update();
boardlineshape.setProjectionMatrix(camera.combined);
//For each line in our board draw a line
for(int i =0; i < boardsize; i++)
{
//first we will draw the vertical lines then we will change to the horizontal lines
boardlineshape.line(linestartx, linestarty,lineendx, lineendy);
//if the x value exceeds a certian amount then change to the horizontal lines
//increment the start x position to draw another line
linestartx += linexdistance;
lineendx += lineydistance;
//if the x start is over 1200 we have drawn the last vertical line so switch to th
//horizontal lines
if(linestartx > 1000)
{
//set our x values and render our horizontal lines
lineendx = linestartx - linexdistance;
linestartx = this.linestartx;
linestarty = this.linestarty;
lineendy = this.linestarty;
for(int index =0; index < boardsize -2; index++){
//increment the start y position to draw another line
boardlineshape.line(linestartx, linestarty,lineendx, lineendy);
linestarty += lineydistance;
lineendy += lineydistance;
}
}
}
}
//Draws all the current pieces for player one
private void DrawPlayerOnePieces(){
//For all of player one's pieces
for(int i = 0; i < playeronepieces[1].length;i++)
{
//of its not an empty piece draw it
if(playeronepieces[0][i] != 0){
gamesprites.draw(redtexture, playeronepieces[0][i], playeronepieces[1][i]);
}
}
}
//Draws all the current pieces for player two
private void DrawPlayerTwoPieces(){
//For all of player two's pieces
for(int i = 0; i < playertwopieces[1].length;i++)
{
//of its not an empty piece draw it
if(playertwopieces[0][i] != 0){
gamesprites.draw(yellowtexture, playertwopieces[0][i], playertwopieces[1][i]);
}
}
}
//Adds a piece to whichever players current turn it is
private void AddPiece(int clickx, int clicky){
RestPlayersTurn(playersturn);
int computedx = GetComputedX(clickx,linestartx);
int computedy = GetComputedY(clicky,linestarty);
if(playeronepieceindex != 60)
{
//makes sure they are clicking inside our board and that there is not already a piece on that part of the board
if(
(clickx > linestartx && clickx < linestartx + ((boardsize - 1) * linexdistance))&&
(clicky > linestarty && clicky < lineendy)&&
(CheckIfPieceExists(computedx,computedy,playeronepieces) == false) &&
(CheckIfPieceExists(computedx,computedy,playertwopieces) == false)
)
{
if(playersturn == 0)
{
playeronepieces[0][playeronepieceindex] = computedx; //set the x value
playeronepieces[1][playeronepieceindex] = 700 - computedy; //set the y value
playeronepieceindex++;
playersturnstring = "Player Two's turn";
gamefont.setColor(Color.YELLOW);
}
else if(playersturn == 1)
{
playertwopieces[0][playertwopieceindex] = computedx; //set the x value
playertwopieces[1][playertwopieceindex] = 700 - computedy; //set the y value
playertwopieceindex++;
playersturnstring = "Player One's turn";
gamefont.setColor(Color.RED);
}
//every time we add a piece change the players turn
playersturn++;
}
}
}
//puts our x value in the center of its cell
public int GetComputedX(int touchx, int linestartx){
//compute our x depending on the nearest line
int lineendx = linestartx + linexdistance;
//for the images width
int imagewidth = redtexture.getWidth();
for(int i = 0; i < boardsize; i++)
{
//if the touched x is in this range than assign the computed x value to
//half the cell
if(touchx > linestartx && touchx < lineendx){
touchx = (lineendx - (linexdistance/2)) - (imagewidth/2);
break;
}
linestartx += linexdistance;
lineendx += linexdistance;
}
return touchx;
}
//puts our y value in the center of the cell
public int GetComputedY(int touchy, int linestarty)
{
//compute our x depending on the nearest line
int lineendy = linestarty + lineydistance;
//for the images width
int imageheight = redtexture.getHeight();
//computer our x depending on the nearest line
for(int i =0; i < boardsize; i++)
{
//if the touched x is in this range than assign the computed x value to
//half the cell
if(touchy > linestarty && touchy < lineendy){
touchy = ((lineendy - (lineydistance/2)) + (imageheight/4));
break;
}
linestarty += lineydistance;
lineendy += lineydistance;
}
return touchy;
}
//Sets the next players turn
private void RestPlayersTurn(int playerturn){
if(playerturn == 2){
playersturn = 0;
}
}
//check for game over
private void CheckForGameOver(){
//check if player one has a connect four
CheckForConnectFourHorizontal();
CheckForConnectFourVertical();
CheckForConnectFourDiagonal();
}
private void CheckForConnectFourHorizontal(){
int rowvalue = 318;
int columnvalue = 534;
//for each column on the board check the row for a horizontal connect four for player one
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckRowForConnectFour(rowvalue,columnvalue,playeronepieces);
rowvalue = 318;
columnvalue = columnvalue - 100;
}
rowvalue = 318;
columnvalue = 534;
//for each column on the board check the row for a horizontal connect four for player two
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckRowForConnectFour(rowvalue,columnvalue,playertwopieces);
rowvalue = 318;
columnvalue = columnvalue - 100;
}
}
private void CheckForConnectFourVertical(){
int rowvalue = 318;
int columnvalue = 534;
//for each column on the board check the row for a horizontal connect four
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckColumnForConnectFour(rowvalue,columnvalue,playeronepieces);
rowvalue = rowvalue + 100 ;
columnvalue = 534;
}
rowvalue = 318;
columnvalue = 534;
//for each column on the board check the row for a horizontal connect four
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckColumnForConnectFour(rowvalue,columnvalue,playertwopieces);
rowvalue = rowvalue + 100 ;
columnvalue = 534;
}
}
private void CheckForConnectFourDiagonal(){
int rowvalue = 318;
int columnvalue = 534;
int originalrowvalue = 318;
//finally do this for every column
for(int index = 0; index < RowsAndColumns[0].length; index++ ){
//for each row on the board check the next four diagonal
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckDiagonalSegment(rowvalue,columnvalue,playeronepieces);
rowvalue = rowvalue + 100;
}
rowvalue = originalrowvalue;
columnvalue -= 100;
}
rowvalue = 318;
columnvalue = 534;
originalrowvalue = 318;
//finally do this for every column
for(int index = 0; index < RowsAndColumns[0].length; index++ ){
//for each row on the board check the next four diagonal
for(int i = 0; i < RowsAndColumns[1].length; i++)
{
CheckDiagonalSegment(rowvalue,columnvalue,playertwopieces);
rowvalue = rowvalue + 100;
}
rowvalue = originalrowvalue;
columnvalue -= 100;
}
}
private void CheckRowForConnectFour(int rowvalue, int columnvalue, int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//for all the rows in this column
for(int index = 0; index < playerpieces[0].length; index++){ //go through the row
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[0].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
//check the next cell
rowvalue += 100;
}
}
private void CheckColumnForConnectFour( int rowvalue, int columnvalue, int[][] playerpieces)
{
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//for all the rows in this column
for(int index = 0; index < RowsAndColumns[1].length; index++){ //go through the column
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[1].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
//check the next cell
columnvalue -= 100;
}
}
private void CheckDiagonalSegment(int rowvalue, int columnvalue, int[][] playerpieces){
CheckForForwardDiagonal(rowvalue,columnvalue,playerpieces);
CheckForBackwardDiagonal(rowvalue,columnvalue,playerpieces);
}
private void CheckForForwardDiagonal(int rowvalue, int columnvalue,int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//check for four to the right
for(int index = 0; index < RowsAndColumns[0].length; index++){ //for every square in the diagonal
for(int i = 0; i < playeronepieces[0].length;i++) // for every player peice check for a red
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
rowvalue += 100;
columnvalue -= 100;
}
}
public void CheckForBackwardDiagonal(int rowvalue, int columnvalue,int[][] playerpieces){
int consecutivepiecesinrow = 0;
int nonmatchedpieces = 0;
//checks the diagonal to the left
for(int index = 0; index < RowsAndColumns[0].length; index++){ //for every square in the diagonal
for(int i = 0; i < playerpieces[0].length;i++) // for every player peice check for a red
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == rowvalue && playerpieces[1][i] == columnvalue )
{
//add to the counter
consecutivepiecesinrow++;
nonmatchedpieces = 0;
break; //we found a piece here so break to the outer loop
}
else{ //if we found one add them to our counter otherwise if none of the items
//match then it doesnt exist in this array
nonmatchedpieces++;
}
}
//if the red player has no piece on this cell
if(nonmatchedpieces == playerpieces[0].length)
{
consecutivepiecesinrow = 0;
nonmatchedpieces = 0;
}
//if we hit for matched then end the game
if(consecutivepiecesinrow == 4){
playersturnstring = "Game Over";
gamefont.setColor(Color.RED);
gameover = true;
}
rowvalue -= 100;
columnvalue -= 100;
}
}
//checks if a piece is already in this position on the board
public boolean CheckIfPieceExists(int row,int column,int[][] playerpieces){
//for all of the pieces check to see if one matches this spot on the grid
for(int i = 0; i < playerpieces[0].length;i++)
{
//if both of these match this is a cell is occupied by a red peiece
if(playerpieces[0][i] == row && playerpieces[1][i] == column )
{
//there is already a piece here
return true;
}
}
return false;
}
#Override
public void resize(int arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void show() {
//set the processor to the new screen
Gdx.input.setInputProcessor(gamestage);
//render our game screen
render(0);
}
The Problem is related to that line
font = new BitmapFont(Gdx.files.internal("assets/font.fnt"),
Gdx.files.internal("assets/font.png"), false);
The file search patch (and classpath) is handled in a different way when starting applications from within your eclipse workspace.
The font is not exported (or not present) in your installed application.
1)
Try to print the file path to console or debug your application. I assume that the file-root is different.
2)
the font is not exported correctly and has to be aded to the build.properties
It runs fine in eclipe but fails when exported
The correct way to export is:
File -> Export -> Java -> Runnable JAR file.
Be sure to check:
Package required libraries into Generated JAR.
That way, your assets will be packaged in the jar and the font will be found.
I'm begining a little project to create a simple checkers game. However it's been a long time since I've used the java GUI tools. The goal of the code at this point is to draw the initial board (red pieces at top, black at bottom). However all I get when I run the code is a blank frame. I'm also a little uncertain if my circle drawing code will do what I want (ie create solid red or black circles inside certain squares) Here is the code. Thanks in advance for any help/suggestions
EDIT: I should probably alternate drawing blue and gray squares or else the thing will probably just be a giant blue blob, however I'll settle for a giant blue blob at this point :p
import javax.swing.*;
import java.awt.*;
public class CheckersServer
{
public static class Board
{
private JFrame frame = new JFrame();
private JPanel backBoard = new JPanel();
Board()
{
frame.setSize(905,905);
backBoard.setSize(900,900);
frame.setTitle("Checkers");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
backBoard.setVisible(true);
boardSquare bs;
String type = null;
//Filling in Red Side
for (int i = 0; i <=1; i++)
{
for(int j = 0; j < 9; j++)
{
if(j % 2 == 0)
{
type = "Red";
}
else
{
type = "Blank";
}
bs = new boardSquare(100*j,100*i,type);
backBoard.add(bs);
}
}
//Filling in empty middle
type = "Blank";
for (int i = 2; i < 7; i++)
{
for(int j = 0; j < 9; j++)
{
bs = new boardSquare(100*j,100*i,type);
backBoard.add(bs);
}
}
//Filling in Black side
for (int i = 7; i < 9; i++)
{
for(int j = 0; j < 9; j++)
{
if(j % 2 != 0)
{
type = "Black";
}
else
{
type = "Blank";
}
bs = new boardSquare(100*j,100*i,type);
backBoard.add(bs);
}
}
backBoard.repaint();
frame.add(backBoard);
frame.repaint();
}
private class boardSquare extends JComponent
{
private int x; //x position of the rectangle measured from top left corner
private int y; //y position of the rectangle measured from top left corner
private boolean isBlack = false;
private boolean isRed = false;
public boardSquare(int p, int q, String type)
{
x = p;
y = q;
if (type.equals("Black"))
{
isBlack = true;
isRed = false;
}
else if (type.equals("Red"))
{
isRed = true;
isBlack = false;
}
else if (type.equals("Blank"))
{
isBlack = false;
isRed = false;
}
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Rectangle box = new Rectangle(x,y,100,100);
g2.draw(box);
g2.setPaint(Color.BLUE);
g2.fill(box);
if(isBlack)
{
g2.fillOval(x, y,100 ,100 );
g2.setColor(Color.black);
g2.drawOval(x, y, 100, 100);
}
else if(isRed)
{
g2.fillOval(x, y,100 ,100 );
g2.setColor(Color.red);
g2.drawOval(x, y, 100, 100);
}
}
}
}
public static void main(String[] args)
{
Board game = new Board();
}
}
You have several issues.
Java UI is layout-based, which means that when you add a component to a parent, the parent's layout determines where the child component will be placed. You don't have any code to set up the layout, and so your application is using the defaults (FlowLayout is the default, and this may work in your case, as long as your JFrame and children are the appropriate size).
The bigger problems are in your boardSquare class. By default, JPanels have a dimension of 10x10. You aren't specifying the size, and so all your squares are 10x10. You need to tell the squares how big they are. You can do this in the boardSquare constructor:
setPreferredSize(new Dimension(100, 100));
Finally, in your drawing code, you are doing an offset of x,y when drawing the squares and circles. This is an offset from the top-left corner of the component. Your components (after setting the size) will be 100x100 pixels. But if your x,y are greater than these values, you will be drawing outside of the bounds of the component. Instead, these values should be set to 0,0 because that is the top-left corner of the component you are drawing in.
By just setting the preferred size of the squares and setting x,y to 0, I was able to get the squares drawing in the frame, though it wasn't pretty. You will need to work on setting the correct layout before it will be laid out correctly.
Here are some hints:
Your BoardSquares have dimension 0x0. Not a good size for something you want to be visible to the user.
To help visualize what's going on, cause each BoardSquare to be 100x100 pixels in size, and give them a border. Now you can see where they are showing up in your GUI. Your GUI code still needs significant changes, but this will at least let you start seeing what you're dealing with.
public BoardSquare(int p, int q, String type)
{
this.setBorder(new LineBorder(Color.CYAN, 2));
this.setPreferredSize(new Dimension(100, 100));
// ... etc ...
BoardSquare seems to be coded to draw its contents based on coordinates from the absolute topmost leftmost point in the window, but they should be coded to draw themselves from the topmost leftmost point of the BoardSquare itself. That is, components should only draw within their own boundaries, and they should use coordinates that assume 0,0 designates the top,left of the component, not of the window.
If you want to use BoardSquares (JComponents) and add them to the frame, you probably should use a different layout manager, like GridLayout. FlowLayout won't give you the kind of precise positioning you want.
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
public class CheckersServer2
{
public static String type_BLANK = "BLANK";
public static String type_RED = "RED";
public static String type_BLACK = "BLACK";
public static int width = 100;
public static int height = 100;
public static class Board
{
private JFrame frame = new JFrame();
private JPanel backBoard = new JPanel();
Board()
{
int numRows = 8;
int numCols = 8;
frame.setSize(905,905);
backBoard.setSize(900,900);
frame.setTitle("Checkers");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
backBoard.setVisible(true);
String type;
for(int r=0; r<numRows; r++){
for(int c=0; c<numCols; c++){
//
type = type_BLANK;
if(c%2==0){
if(r==0 || r==2) {
type = type_RED;
}else if(r==6){
type = type_BLACK;
}
}else{
if(r==1){
type = type_RED;
} else if(r==5 || r==7) {
type = type_BLACK;
}
}
backBoard.add(new BoardSquare(r,c,type));
}
}
backBoard.repaint();
frame.add(backBoard);
frame.repaint();
}
private class BoardSquare extends JComponent
{
/**
*
*/
private static final long serialVersionUID = 1L;
private int x; //x position of the rectangle measured from top left corner
private int y; //y position of the rectangle measured from top left corner
private boolean isBlack = false;
private boolean isRed = false;
public BoardSquare(int p, int q, String type)
{
//this.setBorder(new LineBorder(Color.CYAN, 2));
this.setPreferredSize(new Dimension(width, height));
x = p;
y = q;
if (type.equals(type_BLACK))
{
isBlack = true;
isRed = false;
}
else if (type.equals(type_RED))
{
isRed = true;
isBlack = false;
}
else if (type.equals(type_BLANK))
{
isBlack = false;
isRed = false;
}
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Rectangle box = new Rectangle(x,y,width,height);
g2.draw(box);
g2.setPaint(Color.BLUE);
g2.fill(box);
int ovalWidth = width - 15;
int ovalHeight = ovalWidth;
if(isBlack)
{
g2.setColor(Color.black);
g2.fillOval(x, y, ovalWidth, ovalHeight);
g2.drawOval(x, y, ovalWidth, ovalHeight);
}
else if(isRed)
{
g2.setColor(Color.red);
g2.fillOval(x, y, ovalWidth, ovalHeight);
g2.drawOval(x, y, ovalWidth, ovalHeight);
}
}
}
}
public static void main(String[] args)
{
Board game = new Board();
}
}
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.