tie breaker condition in Java for tennis game app - java

I am working on android tennis app and now I need to keep conditions for a tie breaker scores in tennis game.
For example, if the set 1 scores are at 6-6, then the tie breaker game starts from 1-1, 2-2, 3-3 and so on.
Or in other ways, How I can implement the tie-breaker rule in tennis game for the below code
I am thinking about how to keep this condition working on my app but not able to get it. I am new to Java, so any help will be appreciated.
/*
* The method for the Player1 starts below
* */
assert countBtn1 != null;
countBtn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CountA++;
textViewScore.setText(CountA+"--"+textViewCount1.getText()+"--"+textViewCount2.getText());
if (CountA == 1) {
textViewCount1.setText("15");
} else if (CountA == 2 ) {
textViewCount1.setText("30");
} else if (CountA == 3) {
textViewCount1.setText("40");
}
/*
* After the game is reached to the level of 40-0 for player 1, it checks all the rules of the tennis before finishing the Game
* */
else if (CountA == 4) {
if (CountB == 3 && textViewCount2.getText().toString().equals("40") && textViewCount1.getText().toString().equals("40")) {
textViewCount1.setText("AD");
CountA--;
}
if (CountB == 4 && textViewCount2.getText().toString().equals("40") && textViewCount1.getText().toString().equals("40")) {
textViewCount1.setText("AD");
CountA--;
}
if (CountA == 4 && textViewCount1.getText().toString().equals("40") && textViewCount2.getText().toString().equals("15")) {
textViewCount1.setText("0");
textViewCount2.setText("0");
CountA--;
if(set1 != 7) {
set1 = set1 + 1;
textView1.setText("" + set1);
CountA=0;
}
}
if (CountA == 4 && textViewCount1.getText().toString().equals("40") && textViewCount2.getText().toString().equals("30")) {
textViewCount1.setText("0");
textViewCount2.setText("0");
CountA--;
if(set1 != 7) {
set1 = set1 + 1;
textView1.setText("" + set1);
CountA=0;
}
}
else if (CountA == 4 && textViewCount1.getText().toString().equals("AD") && textViewCount2.getText().toString().equals("40")) {
textViewCount1.setText("0");
textViewCount2.setText("0");
CountA--;
if(set1 != 7) {
set1 = set1 + 1;
textView1.setText("" + set1);
CountA=0;
CountB=0;
}
}
else if (CountA == 4 && textViewCount1.getText().toString().equals("40") && textViewCount2.getText().toString().equals("AD")) {
textViewCount1.setText("40");
textViewCount2.setText("40");
CountA--;
}
else if (CountA == 4 && textViewCount1.getText().toString().equals("40") && textViewCount2.getText().toString().equals("0")) {
textViewCount1.setText("0");
textViewCount2.setText("0");
CountA--;
/*
* The below functions checks the incrementation clause of the game for the sets
* */
if((set1 <= 4 && set4 != 6 && set2 == 0 && set5 == 0)
|| (set1 == 5 && set4 !=7 && set2 == 0 && set5 == 0)
|| (set1 == 5 && set4 == 6 && set2 == 0 && set5 == 0)
// || (set1 == 6 && set4 == 6 && set2 == 0 && set5 == 0)
|| (set1 == 6 && set4 == 5 && set2 == 0 && set5 == 0))
{
set1 = set1 + 1;
// tie1++;
// textViewCount1.setText(""+tie1);
textView1.setText("" + set1);
CountA=0;
if((set1 ==6 && set4 <=4 && set2 == 0 && set5 == 0)|| (set1 ==7 && set4 <= 6 && set2 ==0 && set5 == 0))
{
builder.setMessage("Player 1 wins the 1st set")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {}
});
AlertDialog theAlertDialog = builder.create();
theAlertDialog.show();
}
}
else if ( set1 == 6 && set4 == 6 && set2 == 0 && set5 == 0){
for (tie1=100; tie1 <= 1; tie1++){
textViewCount1.setText("" + tie1);
CountA=0;
}
}
else if((set2 <= 5 && set5 != 6 && set3 == 0 && set6 == 0)
|| (set2 == 5 && set5 != 7 && set3 == 0 && set6 == 0)
|| (set2 == 6 && set5 == 5 && set3 == 0 && set6 == 0)
|| (set2 == 6 && set5 == 6 && set3 == 0 && set6 == 0))
{
set2 = set2 + 1;
textView2.setText("" + set2);
CountA=0;
if((set1 == 6 && set4 <=4 && set2 ==6 && set5 <=4 && set3 == 0 && set6 == 0) || (set2 ==7 && set5 <= 6 && set3 ==0 && set6 == 0))
{
//builder.setTitle("Game Over");
builder.setMessage("Player 1 won the Match by winning both the Sets")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
CountA = 0;
CountB = 0;
textView1.setText("0");
textView2.setText("0");
textView3.setText("0");
textView4.setText("0");
textView5.setText("0");
textView6.setText("0");
textViewCount1.setText("0");
textViewCount2.setText("0");
set1 = set2 = set3 = set4 = set5 = set6 = 0;
}
});
AlertDialog theAlertDialog = builder.create();
theAlertDialog.show();
}
else if((set4 ==6 && set1 <=4 && set2 ==6 && set5 <=4 && set3 == 0 && set6 == 0)|| (set2 ==7 && set5 <= 6 && set3 ==0 && set6 == 0))
{
builder.setMessage("Player 1 wins the 2nd Set")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog theAlertDialog = builder.create();
theAlertDialog.show();
}
}
else if((set3 <= 4 && set6 != 6)
|| (set3 == 5 && set6 !=7 )
|| (set3 == 5 && set6 == 6 )
|| (set3 == 6 && set6 == 6 )
|| (set3 == 6 && set6 == 5 ))
{
set3 = set3 + 1;
textView3.setText("" + set3);
CountA=0;
if((set3 ==6 && set6 <=4) || (set3 ==7 && set6 <= 6 ))
{
//builder.setTitle("Game Over");
builder.setMessage("Player 1 won the Match by winning both the Sets")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
CountA = 0;
CountB = 0;
textView1.setText("0");
textView2.setText("0");
textView3.setText("0");
textView4.setText("0");
textView5.setText("0");
textView6.setText("0");
textViewCount1.setText("0");
textViewCount2.setText("0");
set1 = set2 = set3 = set4 = set5 = set6 = 0;
}
});
AlertDialog theAlertDialog = builder.create();
theAlertDialog.show();
}
}
else{
CountA = 0;
}
}
else if (CountA == 5 && textViewCount1.getText().toString().equals("40") && textViewCount2.getText().toString().equals("40")) {
textViewCount1.setText("AD");
textViewCount2.setText("40");
}
}
}
}
);

Well if you have a proper implementation of score like 40-0, 15-15 etc. then it should be straightforward to mirror it into a helper method that handles tiebreak.
As your code is very verbose I can't tell you how to do it line by line, but simply think of the tiebreak as another additional set and implement it the same way you'd implement a set:
i.e. have a counterA and a counterB and if player A wins a point increment his counter, otherwise increment counter for B - and as soon as one of the player's counter reaches the number that has him win the tiebreak (e.g. condition for A to win would be: either counterA == 6 and counterA - counterB >= 2 or counterA == 7 (via if, else if) - that is if I remember tennis rules correctly)
Then only call your tiebreak method as soon as the set score has reached 6-6 (however you choose to do this check is fine) and return the winner of the tiebreak to the method that handles the set functionality.

Related

checking for specific indexes in a 2D array to announce winner

I have a bingo game I am trying to code, I got hit with some logic problems and I am also looking for a way to tidy up the following code.
(a Bingo game is won by crossing out the numbers in a straight line (diagonally straight line also counts.))
My current code for the 5x5 grid to check for straight "XX"s. Checks for all 5 straight rows and 2 diagonally straights.
public static void bingoCheck(String[][] card1, String[][] card2) {
//check for player 1 bingo.
if ((card1[0][0] == "XX") && (card1[0][1] == "XX") && (card1[0][2] == "XX") && (card1[0][3] == "XX") && (card1[0][4] == "XX")) {
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[1][0] == "XX") && (card1[1][1] == "XX") && (card1[1][2] == "XX") && (card1[1][3] == "XX") && (card1[1][4] == "XX")){
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[2][0] == "XX") && (card1[2][1] == "XX") && (card1[2][2] == "XX") && (card1[2][3] == "XX") && (card1[2][4] == "XX")){
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[3][0] == "XX") && (card1[3][1] == "XX") && (card1[3][2] == "XX") && (card1[3][3] == "XX") && (card1[3][4] == "XX")){
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[4][0] == "XX") && (card1[4][1] == "XX") && (card1[4][2] == "XX") && (card1[4][3] == "XX") && (card1[4][4] == "XX")){
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[0][4] == "XX") && (card1[1][3] == "XX") && (card1[2][2] == "XX") && (card1[3][1] == "XX") && (card1[4][0] == "XX")){
System.out.print("Bingo! Player 1 wins!");
} else if ((card1[4][4] == "XX") && (card1[3][3] == "XX") && (card1[2][2] == "XX") && (card1[1][1] == "XX") && (card1[0][0] == "XX")){
System.out.print("Bingo! Player 1 wins!");
}
// player 2 check
else if ((card2[0][0] == "XX") && (card2[0][1] == "XX") && (card2[0][2] == "XX") && (card2[0][3] == "XX") && (card2[0][4] == "XX")) {
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[1][0] == "XX") && (card2[1][1] == "XX") && (card2[1][2] == "XX") && (card2[1][3] == "XX") && (card2[1][4] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[2][0] == "XX") && (card2[2][1] == "XX") && (card2[2][2] == "XX") && (card2[2][3] == "XX") && (card2[2][4] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[3][0] == "XX") && (card2[3][1] == "XX") && (card2[3][2] == "XX") && (card2[3][3] == "XX") && (card2[3][4] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[4][0] == "XX") && (card2[4][1] == "XX") && (card2[4][2] == "XX") && (card2[4][3] == "XX") && (card2[4][4] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[0][4] == "XX") && (card2[1][3] == "XX") && (card2[2][2] == "XX") && (card2[3][1] == "XX") && (card2[4][0] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else if ((card2[4][4] == "XX") && (card2[3][3] == "XX") && (card2[2][2] == "XX") && (card2[1][1] == "XX") && (card2[0][0] == "XX")){
System.out.print("Bingo! Player 2 wins!");
} else {
//back to getting user input
userIn(card1, card2);
}
}
The logic problem. I want to be able to announce 2 winners at the same time if both grids get the straight line.
This is how the output is right now, both cards got straight lines at the same time but the code only announces Player 2 as the winner only.
Player 1's card:
24 XX 8 1 25
12 XX 7 17 15
5 XX 20 19 13
14 XX XX 4 3
10 XX 11 21 9
Player 2's card:
24 21 17 15 XX
10 3 8 XX 20
14 7 XX 12 5
25 XX 13 19 11
XX 4 9 1 XX
Bingo! Player 2 wins!
Expecting output :
Player 1's card:
24 XX 8 1 25
12 XX 7 17 15
5 XX 20 19 13
14 XX XX 4 3
10 XX 11 21 9
Player 2's card:
24 21 17 15 XX
10 3 8 XX 20
14 7 XX 12 5
25 XX 13 19 11
XX 4 9 1 XX
Bingo! Player 1 wins!
Bingo! Player 2 wins!
If there is any way to tidy up/easier to write code then that'd be great too.
How to check for repeated numbers? If user already used a number then it should print out a message telling them that and then giving them back the input to type again. Here's my current code.
public static void userIn(String[][] card1, String[][] card2) {
public static void userIn(String[][] card1, String[][] card2) {
String str = "";
System.out.print("Game host call (0 to exit): ");
choice = sc.nextInt();
// for user to exit the game
if (choice == 0) {
System.exit(0);
} else {
//check for out of bounds numbers
while (choice < 0 || choice > 25) {
System.out.println("The number must be between 1 to 25, please call again!");
System.out.print("Game host call (0 to exit): ");
choice = sc.nextInt();
}
//change user input to String
str = Integer.toString(choice);
//check if user input matches that on cards
for (i = 0;i <=4; i++) {
for (j = 0;j <=4; j++) {
if (str.equals(card1[i][j])) {
card1[i][j] = "XX";
}
if (str.equals(card2[i][j])) {
card2[i][j] = "XX";
}
}
}
//print player 1 card
System.out.println(player1);
for (i = 0; i < card1.length; i++) {
for (j = 0; j < card1.length; j++) {
System.out.printf(" %2s ", card1[i][j]);
}
System.out.print("\n");
}
// line break
System.out.print("\n");
//print player 2 card
System.out.println(player2);
for (i = 0; i < card2.length; i++) {
for (j = 0; j < card2.length; j++) {
System.out.printf(" %2s ", card2[i][j]);
}
System.out.print("\n");
}
// go to check if any player won.
bingoCheck(card1, card2);
}
}
This will do the job
Edited: For vertical checks & declaring 2 winners at once
public static void bingoCheck(String[][] card1, String[][] card2) {
boolean player1 = checkWinner(card1);
boolean player2 = checkWinner(card2);
if (player1) {
System.out.println("Bingo! Player 1 wins!");
}
if (player2) {
System.out.println("Bingo! Player 2 wins!");
}
if (!(player1 || player2)) {
userIn(card1, card2);
}
}
private static boolean checkWinner(String[][] cards) {
boolean isAllCrossed = true;
int row = 0, col = 0;
// check horizontals
for (row = 0; row < cards.length; row++) {
isAllCrossed = true;
// check if whole row have XX
for (col = 0; col < cards[0].length; col++) {
if (!card[row][col].equals("XX")) {
isAllCrossed = false;
break;
}
}
if (isAllCrossed) return true;
}
// check verticals
for (col = 0; col < cards[0].length; col++) {
isAllCrossed = true;
// check if whole column have XX
for (row = 0; row < cards.length; row++) {
if (!card[row][col].equals("XX")) {
isAllCrossed = false;
break;
}
}
if (isAllCrossed) return true;
}
// check digonal from top left to bottom right
isAllCrossed = true;
row = col = 0;
while (row < cards.length) {
if (!card[row][col].equals("XX")) {
isAllCrossed = false;
break;
}
}
row++;
col++;
}
if (isAllCrossed) return true;
// check digonal from top right to bottom left
isAllCrossed = true;
row = 0;
col = cards[0].length - 1;
while (row < cards.length) {
if (!card[row][col].equals("XX")) {
isAllCrossed = false;
break;
}
row++;
col--;
}
return isAllCrossed;
}
General rule in writing a code is that you should extract code that repeats into separate function and use it, instead of repeating its body many times.
In your case many things repeat.
Notice that you have exactly the same code for checking each player's board. That's the first thing that you should extract to a separate method and just call it with board of each user.
You are repeating logic for checking each row. You are also repeating code that's checks each column. You should extract two methods, i.e. checkRow and checkColumn and call it in the for loop for each row/column. Diagonal case can be handled as 3rd method.
Checking all elements in one row/column should be done with a for loop, instead of manually checking each position individually.
Just to summarize: the core rule, that you should have applied here is: don't repeat yourself (DRY).

How do I get my program to identify a the string and integer within a given string? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 2 years ago.
So here's the homework question:
"Write a program that takes a date as input and outputs the date's season. The input is a string to represent the month and an int to represent the day.
Ex: If the input is:
April 11
the output is:
Spring
In addition, check if the string and int are valid (an actual month and day).
Ex: If the input is:
Blue 65
the output is:
Invalid
"
My code is as follows:
'''
String inputMonth;
int inputDay;
inputMonth = scnr.next();
inputDay = scnr.nextInt();
if( ((inputMonth == "March") || (inputMonth == "march")) && ((inputDay >= 20) && (inputDay <= 31))){
System.out.println("Spring");
}
else if( ((inputMonth == "April") || (inputMonth == "april")) && ((inputDay >= 1) && (inputDay <= 30))){
System.out.println("Spring");
}
else if( ((inputMonth == "May") || (inputMonth == "may")) && ((inputDay >= 1) && (inputDay <= 31))){
System.out.println("Spring");
}
else if( ((inputMonth == "June") || (inputMonth == "june")) && ((inputDay >= 1) && (inputDay <= 20))){
System.out.println("Spring");
}
else if( ((inputMonth == "June") || (inputMonth == "june")) && ((inputDay >= 21) && (inputDay <= 30))){
System.out.println("Summer");
}
else if( ((inputMonth == "July") || (inputMonth == "july")) && ((inputDay >= 1) && (inputDay <= 31))){
System.out.println("Summer");
}
else if( ((inputMonth == "August") || (inputMonth == "august")) && ((inputDay >= 1) && (inputDay <= 31))){
System.out.println("Summer");
}
else if( ((inputMonth == "September") || (inputMonth == "september")) && ((inputDay >= 1) && (inputDay <= 21))){
System.out.println("Summer");
}
else if( ((inputMonth == "September") || (inputMonth == "september")) && ((inputDay >= 22) && (inputDay <= 30))){
System.out.println("Autumn");
}
else if( ((inputMonth == "October") || (inputMonth == "october")) && ((inputDay >= 1) && (inputDay <= 31))){
System.out.println("Autumn");
}
else if( ((inputMonth == "November") || (inputMonth == "november")) && ((inputDay >= 22) && (inputDay <= 30))){
System.out.println("Autumn");
}
else if( ((inputMonth == "December") || (inputMonth == "december")) && ((inputDay >= 1) && (inputDay <= 20))){
System.out.println("Autumn");
}
else if( ((inputMonth == "December") || (inputMonth == "december")) && ((inputDay >= 21) && (inputDay <= 31))){
System.out.println("Winter");
}
else if( ((inputMonth == "January") || (inputMonth == "january")) && ((inputDay >= 1) && (inputDay <= 31))){
System.out.println("Winter");
}
else if( ((inputMonth == "February") || (inputMonth == "february")) && ((inputDay >= 1) && (inputDay <= 29))){
System.out.println("Winter");
}
else if( ((inputMonth == "March") || (inputMonth == "march")) && ((inputDay >= 1) && (inputDay <= 19))){
System.out.println("Winter");
}
else{
System.out.println("Invalid");
}
'''
I believe the problem is that it wont read both the string and the integer correctly but I'm not exactly sure why.
Also I know there's probably a shorter way to do this but I don't know how yet, if anyone would like to help me with that too it would be infinitely appreciated.
Thank you in advance
I don't know if this version makes more sense to you or not.
I put the month names, seasons, and date ranges in arrays. Normally, I would have created a class to hold the season name and date range, but I used arrays to keep it simpler.
I commented on the more obscure sections of code. I hope this helps.
package com.ggl.testing;
import java.util.Scanner;
public class Seasons {
static String[] months = { "January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December" };
// Winter has two ranges to make the comparisons easier
static String[] seasons = { "Spring", "Summer", "Autumn", "Winter",
"Winter" };
// Month and day to start the season, month and day to end the season
// Winter has two ranges to make the comparisons easier
// The month number is zero based (0 - 11)
static int[][] ranges = { { 2, 20, 5, 20 }, { 5, 21, 8, 21 },
{ 8, 22, 11, 20 }, { 11, 21, 11, 31 },
{ 0, 1, 2, 19 } };
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] values = getInput(scanner);
if (values[0] < 0 || values[1] < 0) {
System.out.println("Invalid");
} else {
System.out.println(getSeason(values));
}
scanner.close();
}
static int[] getInput(Scanner scanner) {
int[] output = new int[2];
System.out.print("Type the month and day: ");
String s = scanner.nextLine().trim();
String[] parts = s.split(" ");
output[0] = getMonthIndex(parts[0]);
output[1] = getDay(parts[1]);
return output;
}
static int getMonthIndex(String month) {
for (int i = 0; i < months.length; i++) {
if (month.toLowerCase().equals(months[i].toLowerCase())) {
return i;
}
}
return -1;
}
static int getDay(String number) {
try {
int value = Integer.valueOf(number);
// TODO Check last day of a particular month
if (value < 1 || value > 31) {
return -1;
} else {
return value;
}
} catch (NumberFormatException e) {
return -1;
}
}
static String getSeason(int[] values) {
for (int i = 0; i < ranges.length; i++) {
if ((ranges[i][0] == values[0]) && (ranges[i][1] <= values[1])) {
return seasons[i];
} else if ((values[0] == ranges[i][2]) && (values[1] <= ranges[i][3])) {
return seasons[i];
} else if ((ranges[i][0] < values[0]) && values[0] < ranges[i][2]) {
return seasons[i];
}
}
return "Invalid";
}
}

Search algorithm optimization

The code "works", but I'm having problems with optimization.
Algorithms idea is count the number of ways you can navigate n × n grid starting from the top left corner, always moving one step to the left, right, up or down, visiting each square. For example, when n = 3, there are 8 possible paths.
For example the algorithm gets unbearably slow with p.count(7), any hints/tips?
public class Paths {
static int[][] grid;
static int n,counter;
public int count(int n) {
grid = new int[n][n];
counter = 0;
search(0,0,1,n);
return counter;
}
void search(int y, int x, int k, int n) {
if (y < 0 || x < 0 || y >= n || x >= n) return;
if (grid[y][x] != 0) return;
if (x-1 > 0 && x+1 < n && y == n && grid[y][x-1] == 0 && grid[y][x+1] == 0) return;
else if (x-1 > 0 && x+1 < n && y == 0 && grid[y][x-1] == 0 && grid[y][x+1] == 0) return;
else if (y-1 > 0 && y+1 < n && x == n && grid[y-1][x] == 0 && grid[y+1][x] == 0) return;
else if (y-1 > 0 && y+1 < n && x == 0 && grid[y-1][x] == 0 && grid[y+1][x] == 0) return;
else if (y==n && x==n && grid[y][x-1] == 0 && grid[y-1][x] == 0) return;
else if (y==n && x==0 && grid[y-1][x] == 0 && grid[y][x+1] == 0) return;
else if (y==0 && x==n && grid[y+1][x] == 0 && grid[y][x-1] == 0) return;
if (k == n*n) {
counter++;
return;
}
grid[y][x] = k;
search(y,x-1,k+1,n);
search(y,x+1,k+1,n);
search(y+1,x,k+1,n);
search(y-1,x,k+1,n);
grid[y][x] = 0;
}
}
Output:
public static void main(String[] args) {
Paths p = new Paths();
System.out.println(p.count(1)); // 1
System.out.println(p.count(2)); // 2
System.out.println(p.count(3)); // 8
System.out.println(p.count(4)); // 52
}
}

Android Tic tac toe - After the computer wins, the player can still use the buttons, and wins

i'm a new android programmer, and i need your help..
As I said problem is after the computer wins, the player can still use the buttons, and wins..
Here is the code:
package com.example.qwert.graox;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
int c[][];
int i, j = 0;
Button b[][];
TextView textView;
AI ai;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setBoard();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuItem item = menu.add("New Game");
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
setBoard();
return true;
}
// Set up the game board.
private void setBoard() {
ai = new AI();
b = new Button[4][4];
c = new int[4][4];
textView = (TextView) findViewById(R.id.dialogi);
b[1][3] = (Button) findViewById(R.id.button1);
b[1][2] = (Button) findViewById(R.id.button2);
b[1][1] = (Button) findViewById(R.id.button3);
b[2][3] = (Button) findViewById(R.id.button4);
b[2][2] = (Button) findViewById(R.id.button5);
b[2][1] = (Button) findViewById(R.id.button6);
b[3][3] = (Button) findViewById(R.id.button7);
b[3][2] = (Button) findViewById(R.id.button8);
b[3][1] = (Button) findViewById(R.id.button9);
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++)
c[i][j] = 2;
}
textView.setText("Press any key to start");
textView.setTextColor(0xFFFF0000);
// add the click listeners for each button
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++) {
b[i][j].setOnClickListener(new MyClickListener(i, j));
if(!b[i][j].isEnabled()) {
b[i][j].setText("-");
b[i][j].setTextColor(0xff000000);
b[i][j].setEnabled(true);
}
}
}
}
class MyClickListener implements View.OnClickListener {
int x;
int y;
public MyClickListener(int x, int y) {
this.x = x;
this.y = y;
}
public void onClick(View view) {
if (b[x][y].isEnabled()); {
b[x][y].setEnabled(false);
b[x][y].setText("O");
b[x][y].setTextColor(0xFFFFFFFF );
c[x][y] = 0;
textView.setText("");
if (!checkBoard()) {
ai.takeTurn();
}
}
}
}
private class AI {
public void takeTurn() {
if(c[1][1]==2 &&
((c[1][2]==0 && c[1][3]==0) ||
(c[2][2]==0 && c[3][3]==0) ||
(c[2][1]==0 && c[3][1]==0))) {
markSquare(1,1);
} else if (c[1][2]==2 &&
((c[2][2]==0 && c[3][2]==0) ||
(c[1][1]==0 && c[1][3]==0))) {
markSquare(1,2);
} else if(c[1][3]==2 &&
((c[1][1]==0 && c[1][2]==0) ||
(c[3][1]==0 && c[2][2]==0) ||
(c[2][3]==0 && c[3][3]==0))) {
markSquare(1,3);
} else if(c[2][1]==2 &&
((c[2][2]==0 && c[2][3]==0) ||
(c[1][1]==0 && c[3][1]==0))){
markSquare(2,1);
} else if(c[2][2]==2 &&
((c[1][1]==0 && c[3][3]==0) ||
(c[1][2]==0 && c[3][2]==0) ||
(c[3][1]==0 && c[1][3]==0) ||
(c[2][1]==0 && c[2][3]==0))) {
markSquare(2,2);
} else if(c[2][3]==2 &&
((c[2][1]==0 && c[2][2]==0) ||
(c[1][3]==0 && c[3][3]==0))) {
markSquare(2,3);
} else if(c[3][1]==2 &&
((c[1][1]==0 && c[2][1]==0) ||
(c[3][2]==0 && c[3][3]==0) ||
(c[2][2]==0 && c[1][3]==0))){
markSquare(3,1);
} else if(c[3][2]==2 &&
((c[1][2]==0 && c[2][2]==0) ||
(c[3][1]==0 && c[3][3]==0))) {
markSquare(3,2);
}else if( c[3][3]==2 &&
((c[1][1]==0 && c[2][2]==0) ||
(c[1][3]==0 && c[2][3]==0) ||
(c[3][1]==0 && c[3][2]==0))) {
markSquare(3,3);
} else {
Random rand = new Random();
int a = rand.nextInt(4);
int b = rand.nextInt(4);
while(a==0 || b==0 || c[a][b]!=2) {
a = rand.nextInt(4);
b = rand.nextInt(4);
}
markSquare(a,b);
}
}
private void markSquare(int x, int y) {
b[x][y].setEnabled(false);
b[x][y].setText("X");
b[x][y].setTextColor(0xFF00FF00);
c[x][y] = 1;
checkBoard();
}
}
// check the board to see if someone has won
private boolean checkBoard() {
boolean gameOver = false;
if ((c[1][1] == 0 && c[2][2] == 0 && c[3][3] == 0)
|| (c[1][3] == 0 && c[2][2] == 0 && c[3][1] == 0)
|| (c[1][2] == 0 && c[2][2] == 0 && c[3][2] == 0)
|| (c[1][3] == 0 && c[2][3] == 0 && c[3][3] == 0)
|| (c[1][1] == 0 && c[1][2] == 0 && c[1][3] == 0)
|| (c[2][1] == 0 && c[2][2] == 0 && c[2][3] == 0)
|| (c[3][1] == 0 && c[3][2] == 0 && c[3][3] == 0)
|| (c[1][1] == 0 && c[2][1] == 0 && c[3][1] == 0)) {
textView.setText("Super - you Win");
gameOver = true;
} else if ((c[1][1] == 1 && c[2][2] == 1 && c[3][3] == 1)
|| (c[1][3] == 1 && c[2][2] == 1 && c[3][1] == 1)
|| (c[1][2] == 1 && c[2][2] == 1 && c[3][2] == 1)
|| (c[1][3] == 1 && c[2][3] == 1 && c[3][3] == 1)
|| (c[1][1] == 1 && c[1][2] == 1 && c[1][3] == 1)
|| (c[2][1] == 1 && c[2][2] == 1 && c[2][3] == 1)
|| (c[3][1] == 1 && c[3][2] == 1 && c[3][3] == 1)
|| (c[1][1] == 1 && c[2][1] == 1 && c[3][1] == 1)) {
textView.setText("GameOver. Computer wins..");
gameOver = true;
} else {
boolean empty = false;
for(i=1; i<=3; i++) {
for(j=1; j<=3; j++) {
if(c[i][j]==2) {
empty = true;
break;
}
}
}
if(!empty) {
gameOver = true;
textView.setText("Game Over. Draft!");
}
}
return gameOver;
}
}
I think the problem is somewhere there:
// check the board to see if someone has won
private boolean checkBoard() {
boolean gameOver = false;
if ((c[1][1] == 0 && c[2][2] == 0 && c[3][3] == 0)
|| (c[1][3] == 0 && c[2][2] == 0 && c[3][1] == 0)
|| (c[1][2] == 0 && c[2][2] == 0 && c[3][2] == 0)
|| (c[1][3] == 0 && c[2][3] == 0 && c[3][3] == 0)
|| (c[1][1] == 0 && c[1][2] == 0 && c[1][3] == 0)
|| (c[2][1] == 0 && c[2][2] == 0 && c[2][3] == 0)
|| (c[3][1] == 0 && c[3][2] == 0 && c[3][3] == 0)
|| (c[1][1] == 0 && c[2][1] == 0 && c[3][1] == 0)) {
textView.setText("Super - you Win");
gameOver = true;
} else if ((c[1][1] == 1 && c[2][2] == 1 && c[3][3] == 1)
|| (c[1][3] == 1 && c[2][2] == 1 && c[3][1] == 1)
|| (c[1][2] == 1 && c[2][2] == 1 && c[3][2] == 1)
|| (c[1][3] == 1 && c[2][3] == 1 && c[3][3] == 1)
|| (c[1][1] == 1 && c[1][2] == 1 && c[1][3] == 1)
|| (c[2][1] == 1 && c[2][2] == 1 && c[2][3] == 1)
|| (c[3][1] == 1 && c[3][2] == 1 && c[3][3] == 1)
|| (c[1][1] == 1 && c[2][1] == 1 && c[3][1] == 1)) {
textView.setText("GameOver. Computer wins..");
gameOver = true;
} else {
boolean empty = false;
for(i=1; i<=3; i++) {
for(j=1; j<=3; j++) {
if(c[i][j]==2) {
empty = true;
break;
}
}
}
if(!empty) {
gameOver = true;
textView.setText("Game Over. Draft!");
}
}
return gameOver;
}
Your bug is there
public void onClick(View view) {
if (b[x][y].isEnabled()) {
b[x][y].setEnabled(false);
b[x][y].setText("O");
b[x][y].setTextColor(0xFFFFFFFF );
c[x][y] = 0;
textView.setText("");
if (!checkBoard()) {
ai.takeTurn();
}
}
}
Player alway can touch button
best way is you gameOver be field and check in onClick if statment
Button have option setClickable.
if(!empty) {
gameOver = true;
textView.setText("Game Over. Draft!");
for (i = 1; i <= 3; i++) {
for (j = 1; j <= 3; j++)
b[i][j].setClickable(false); // button object
}
}

How to increase efficiency by using for loops?

I am a beginner java programmer and I am making a simple TicTacToe game using 2D arrays and these are my if statements to check if player 1, or player 2 has won. I believe that this can be simplified by using for loop(s) however I do not understand how to use that method.
if ((grid[0][0] == 1 && grid[0][1] == 1 && grid[0][2] == 1)
|| (grid[1][0] == 1 && grid[1][1] == 1 && grid[1][2] == 1)
|| (grid[2][0] == 1 && grid[2][1] == 1 && grid[2][2] == 1)
|| (grid[0][0] == 1 && grid[1][1] == 1 && grid[2][2] == 1)
|| (grid[0][2] == 1 && grid[1][1] == 1 && grid[2][0] == 1)
|| (grid[0][0] == 1 && grid[1][0] == 1 && grid[2][0] == 1)
|| (grid[0][1] == 1 && grid[1][1] == 1 && grid[2][1] == 1)
|| (grid[0][2] == 1 && grid[1][2] == 1 && grid[2][2] == 1)
&& won == false) {
title.setText("X wins!");
won = true;
} else if ((grid[0][0] == 2 && grid[0][1] == 2 && grid[0][2] == 2)
|| (grid[1][0] == 2 && grid[1][1] == 2 && grid[1][2] == 2)
|| (grid[2][0] == 2 && grid[2][1] == 2 && grid[2][2] == 2)
|| (grid[0][0] == 2 && grid[1][1] == 2 && grid[2][2] == 2)
|| (grid[0][2] == 2 && grid[1][1] == 2 && grid[2][0] == 2)
|| (grid[0][0] == 2 && grid[1][0] == 2 && grid[2][0] == 2)
|| (grid[0][1] == 2 && grid[1][1] == 2 && grid[2][1] == 2)
|| (grid[0][2] == 2 && grid[1][2] == 2 && grid[2][2] == 2)
&& won == false) {
title.setText("O wins!");
won = true;
}
Below is the modified code that uses far less if statments and conditions.
public static boolean hasWon(int[][] grid) {
for (int a = 1; a <= 2; a++) {
for (int b = 0; b < grid.length; b++) {
// Checking for win in horizontal, then vertical, then diagonal
if (grid[b][0] == a && grid[b][1] == a && grid[b][2] == a) {
won = true;
} else if (grid[0][b] == a && grid[1][b] == a && grid[2][b] == a) {
won = true;
} else if ((grid[0][0] == a && grid[1][1] == a && grid[2][2] == a
|| (grid[0][2] == a && grid[1][1] == a && grid[2][0] == a))) {
won = true;
}
}
}
}
In order to help you reach a solution on your own I'll give you some hints for now.
Hint #1: Think about what it means to win. A player must get 3 of their tokens in a row - horizontal, vertical, or diagonal. Think about how that can be represented in your program.
Hint #2: Think about how you can break the problem into smaller more manageable pieces. Think about what each winning scenario has in common and separate that logic into a method that you can call multiple times.
Hint #3: Consider what makes each winning scenario unique and how you might use your grid to produce a representation of the spaces you want to examine that is easier to check for a win.
If you're not sure about how for loops work or other aspects of the Java Language you can find tutorials on Oracle's site
Yes you are right. For loops are the way to go. Here is one way you could implement it.
public class tictactoe {
public static void main(String[] args) {
int[][] grid = {{1, 2, 1},
{1, 2, 1},
{2, 0, 1}};
boolean won = hasWon(grid);
}
public static boolean hasWon(int[][] grid){
for (int player = 1; player <= 2; player++){
boolean playerWon = false;
for(int i = 0; i < 3; i++){
//Horizonal win
playerWon = (grid[i][0] == player && grid[i][1] == player && grid[i][2] == player) || playerWon;
//Vertical Win
playerWon = (grid[0][i] == player && grid[1][i] == player && grid[i][2] == player) || playerWon;
}
//Diagonal Win
playerWon = (grid[0][0] == player && grid[1][1] == player && grid[2][2] == player) || playerWon;
playerWon = (grid[0][2] == player && grid[1][1] == player && grid[2][0] == player) || playerWon;
if(playerWon){
if(player == 1){
System.out.println("X wins!");
return true;
}
else{
System.out.println("O wins!");
return true;
}
}
}
//neither have won
return false;
}
}
Not a direct answer for the question. (as this is not "check all at once" style)
To simplify,
1. Check when a cell is clicked.
2. Condition depends on the place of a cell which is clicked and who clicked the cell.
3. If someone wins, end the game.
code sample
// Part of codes.(not tested.)
// Each cell has three states (0, 1, or 2)
int player = 1; // (Not written here but) switch this each turn (1 or 2)
// In some place (activity.onCreate() etc)
{
// For on click event(0, 0)
cell_0_0.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
grid[0][0] = player;
final boolean isEnd = checkEnd_0_0();
if (isEnd) {
// Call some function to end the game.
// Calling title.setText() in game end function maybe good.
// (as not needed to write many times.)
if (player == 1) {
title.setText("X wins!");
} else {
title.setText("O wins!");
}
} else {
switchPlayer(); // Not written in this code.
}
}
};
);
...
}
// Call this on cell(0, 0) click event
// Returns true if someone wins.
boolean checkEnd_0_0() {
// Omit checking grid[0][0] is 1 or 2 as it is clear.
// Check horizontal.
if (grid[0][1] == player) {
if (grid[0][2] == player) {
return true; // This is the case shown in question.
}
}
// Check other cases (vertical, diagonal)
...
// No match.
return false;
}

Categories