16.31 (Game: connect four)
Programming Exercise 8.20 enables two players to play the
connect-four game on the console. Rewrite a GUI version
for the program, as shown in Figure 16.49c. The program
enables two players to place red and yellow discs in turn.
To place a disk, the player needs to click an available cell.
An available cell is unoccupied and its downward neighbor is
occupied. The program flashes the four winning cells
if a player wins and reports no winners if all cells
are occupied with no winners.
Programming Exercise 8.20 enables two players to play the
connect-four game on the console. Rewrite a GUI version
for the program, as shown in Figure 16.49c. The program
enables two players to place red and yellow discs in turn.
To place a disk, the player needs to click an available cell.
An available cell is unoccupied and its downward neighbor is
occupied. The program flashes the four winning cells
if a player wins and reports no winners if all cells
are occupied with no winners.
import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Rectangle; import javafx.scene.text.Font; import javafx.stage.Stage; import javafx.util.Duration; public class Exercise_31 extends Application { @Override public void start(Stage primaryStage) throws Exception { ConsecutiveFourPane pane = new ConsecutiveFourPane(100); BorderPane borderPane = new BorderPane(pane); HBox bottomPane = new HBox(pane.lblGameStatus); bottomPane.setAlignment(Pos.CENTER); bottomPane.setPadding(new Insets(10)); borderPane.setBottom(bottomPane); primaryStage.setScene(new Scene(borderPane)); primaryStage.setTitle("Consecutive Four"); primaryStage.show(); } private class ConsecutiveFourPane extends GridPane { double w; double h; int columns = 7; int rows = 6; Circle[][] circles = new Circle[rows][columns]; boolean isPlayer1Turn = true; boolean hasWon; int[] c4Indexes = new int[8]; Label lblGameStatus = new Label(getPlayerString()); private ConsecutiveFourPane(int size) { w = size * columns; h = size * rows; drawBackground(); lblGameStatus.setFont(Font.font(30)); } private void drawBackground() { for (int i = 0; i < circles.length; i++) { for (int j = 0; j < circles[i].length; j++) { Rectangle rec = new Rectangle(w / columns, w / columns); rec.setFill(Color.BLUE); circles[i][j] = new Circle(rec.getWidth() * 0.45); circles[i][j].setFill(Color.WHITE); final int row = i; final int column = j; circles[i][j].setOnMouseClicked(e-> { if (checkLocation(row, column) && !hasWon) { circles[row][column].setFill((isPlayer1Turn) ? Color.RED : Color.YELLOW); if (isConsecutiveFour()) { hasWon = true; flashConsecutiveFour(); lblGameStatus.setText((isPlayer1Turn) ? "Player 1 has WON" : "Player 2 has WON"); } else if (isDraw()) { lblGameStatus.setText("It's a DRAW"); } else { isPlayer1Turn = !isPlayer1Turn; lblGameStatus.setText((isPlayer1Turn) ? "Player's 1 turn" : "Player's 2 turn"); } } }); StackPane pane = new StackPane(rec, circles[i][j]); add(pane, j, i); } } } private void flashConsecutiveFour() { Timeline timeline = new Timeline(new KeyFrame(Duration.millis(500), e-> { flashCircles(); })); timeline.setCycleCount(Timeline.INDEFINITE); timeline.play(); } private boolean isDraw() { for (Circle[] circle : circles) { for (Circle c : circle) { if (c.getFill() == Color.WHITE) return false; } } return true; } private void flashCircles() { for (int i = 0; i < 8; i += 2) { Circle c = circles[c4Indexes[i]][c4Indexes[i + 1]]; Color playerColor = (isPlayer1Turn) ? Color.RED : Color.YELLOW; c.setFill((c.getFill() != Color.ORANGE) ? Color.ORANGE : playerColor); } } private String getPlayerString() { return (isPlayer1Turn) ? "Player's 1 turn" : "Player's 2 turn"; } // returns true if grid location is clear private boolean checkLocation(int row, int column) { // if at the bottom row and the circle is white return true else false if (row == circles.length - 1) { return circles[row][column].getFill() == Color.WHITE; } // if circle below the clicked circle is not white return true return (circles[row + 1][column].getFill() != Color.WHITE); } public boolean isConsecutiveFour() { Color color = (isPlayer1Turn) ? Color.RED : Color.YELLOW; int occurrence = 0; // (m[0].length - 3) --> reason: only checking occurrences of 4 for (int j = 0; j < circles[0].length - 3; j++) { int y = circles.length - 1; // row always starts on last row int x = j; while (x < circles[0].length && y >= 0) { if (circles[y][x].getFill() == color) { occurrence++; if (occurrence == 4) { // | | | | | |R|R| saveOccurrence(y, x, false, true); // | | | | |R|R|R| return true; // | | | |R|R|R|R| } // | | |R|R|R|R| | } else { // | |R|R|R|R| | | occurrence = 0; } x++; y--; } } // (m.length - 2) --> reason: only checking occurrences of 4 // and last row has already been checked for (int i = circles.length - 2; i > 2; i--) { int x = 0; // column always starts on the left side int y = i; occurrence = 0; // | | | |R|R| | | while (x < circles[0].length && y >= 0) { // | | |R|R| | | | // | |R|R| | | | | // |R|R| | | | | | if (circles[y][x].getFill() == color) { // |R| | | | | | | occurrence++; // | | | | | | | | if (occurrence == 4) { saveOccurrence(y, x, false, true); return true; } } else { occurrence = 0; } x++; y--; } } // j >= 3 --> reason: only checking occurrences of 4 for (int j = circles[0].length - 1; j >= 3; j--) { int y = circles.length -1; // row always starts on last row int x = j; occurrence = 0; // |L|L| | | | | | while (x >= 0 && y >= 0) { // |L|L|L| | | | | // |L|L|L|L| | | | if (circles[y][x].getFill() == color) { // | |L|L|L|L| | | occurrence++; // | | |L|L|L|L| | if (occurrence == 4) { // | | | |L|L|L|L| saveOccurrence(y,x,false,false); return true; } } else { occurrence = 0; } x--; y--; } } // i > 2 --> reason: only checking occurrences of 4 // | | |L|L| | | | for (int i = circles.length - 2; i > 2; i--) { // | | | |L|L| | | int x = circles[0].length - 1; // | | | | |L|L| | int y = i; // | | | | | |L|L| occurrence = 0; // | | | | | | |L| while (x >= 0 && y >= 0) { // | | | | | | | | if (circles[y][x].getFill() == color) { occurrence++; if (occurrence == 4) { saveOccurrence(y, x, false, false); return true; } } else { occurrence = 0; } x--; y--; } } // Check rows for (int y = 0; y < circles.length; y++) { for (int x = 0; x < circles[y].length; x++) { if (circles[y][x].getFill() == color) { occurrence++; if (occurrence == 4) { int sequence = 0; for (int i = 0; i < 8; i += 2) { c4Indexes[i] = y; c4Indexes[i + 1] = x - sequence++; } return true; } } else { occurrence = 0; } } occurrence = 0; } // Check columns for (int x = 0; x < circles[0].length; x++) { for (int y = 0; y < circles.length; y++) { if (circles[y][x].getFill() == color) { occurrence++; if (occurrence == 4) { int sequence = 0; for (int i = 0; i < 8; i += 2) { c4Indexes[i] = y - sequence++; c4Indexes[i + 1] = x; } return true; } } else { occurrence = 0; } } occurrence = 0; } return false; } private void saveOccurrence(int y, int x, boolean yIsIncrement, boolean xIsIncrement) { int yIncrement = (yIsIncrement) ? -1 : 1; int xIncrement = (xIsIncrement) ? -1 : 1; for (int i = 0; i < 8; i += 2) { c4Indexes[i] = y; c4Indexes[i + 1] = x; y += yIncrement; x += xIncrement; } } } public static void main(String[] args) { Application.launch(args); } }
can you upload the manual publicly?
ReplyDeletei am afraid thats not possible as these exercise solving is a on going process for me.
ReplyDeleteDo you mean that you solve this exercises only by your self?
Deletenot all but some i do it by myself
Deleteand the others where do you get them from?
Deletewhich chapter and question you need solution for?
ReplyDeletei need the whole manual just in case you stop posting solutions
DeleteThank you but I will be completing the whole book. Right now I am on chapter 20 and book has 33 chapters. And I will complete it. I know will take me few months to do it but I will do it.
ReplyDeleteSorry to bother you
DeleteYour answer of Exercise 3.27 is wrong, so please can you check it ???!!
Thank you i really appreciate you going through solutions and help me to improve these solutions. I will fix it today. And will message here so you can review it.
DeleteTry this point (1,70) which is in the triangle.
DeleteThank you for your kind input please If you have time please check if the update has fixed the issues or not.
DeleteI checked and it works, Thank you for your immediate response really appreciate it.
DeleteNo problem glad I could be of any service. I really appreciate the time you put in to make solutions better.
Deletewhy you didn't solve problems btw Chapter 5.7 to Chapter 6.21?
ReplyDeleteFor that i need some time i will be completing most question which wont take me much time and come back to unfinished one after that. Currently there are 5 unsolved ones which are as following:
ReplyDeleteChapter 24 Exercise 15, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.
Chapter 24 Exercise 16, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.
Chapter 25 Exercise 15, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.
Chapter 28 Exercise 13, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.
Chapter 28 Exercise 15, Introduction to Java Programming, Tenth Edition Y. Daniel LiangY.
If anyone has already solved them please let me know. I will add there names to credit of that answer. Thank you
i am currently solving problems of chapter 5 which is unsolved, how can i send it to you?
ReplyDeleteYou can send me the solution at saintsinner3@gmail.com and thank you for your support. Please mention you name in the comment so I give you credit for the solutions.
ReplyDeleteok when i finish them i will send them to you.
ReplyDeletethank you.
ReplyDeletecheck your inbox
ReplyDeletethank you Zakaria Hashi I have received your email. I wil be posting your solutions of missing parts and mention you name in credits.
ReplyDeleteyou are welcome
ReplyDelete