I'm making a tic tac toe game for my homework and the teacher told me to print a tie when only a tie can come out. (under the assumption that the players are not smart) For example,
x o x
- - -
o x o
can only result in a tie so when this happens we are supposed to end the game with "this is a tie"
I have finished coding the tic tac toe with a char[][] array but I have no idea how to predict a draw.
public class Ttt22 {
private static int spacesLe
private static char[][] board;
public static void main (String[] args) {
// the first move belongs to X.
System.out.println("Welcome to Tic Tac Toe");
board = new char[3][3];
initializeBoard();
firstDraw();
char mark = 'X';
while (true) {
int square = getLegalMove(mark);
move(square, mark);
draw();
if (is3InRow(mark)) {
System.out.println(mark + " wins!");
break;
}
if (isBoardFull()) {
System.out.println("Tie game!");
break;
}
if (mark == 'X') {
mark = 'O';
}
else {
mark = 'X';
}
}
}
public static int getLegalMove (char mark) {
java.util.Scanner console = new java.util.Scanner(System.in);
while (true) {
System.out.println(mark + "'s next move: ");
int square = console.nextInt();
if ((square >= 1) &&
(square <= 9) &&
(isSquareEmpty(square))) {
return square;
}
System.out.println("\nIllegal move, try again\n");
}
}
public static void initializeBoard () {
spacesLeft = 9;
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
board[i][j] = ' ';
}
}
}
public static void firstDraw () {
System.out.println();
System.out.println(" | | ");
System.out.println(" " + 1 + " | " + 2 + " | " + 3);
System.out.println(" | | ");
System.out.println("---+---+---");
System.out.println(" | | ");
System.out.println(" " + 4 + " | " + 5 + " | " + 6);
System.out.println(" | | ");
System.out.println("---+---+---");
System.out.println(" | | ");
System.out.println(" " + 7 + " | " + 8 + " | " + 9);
System.out.println(" | | ");
System.out.println();
}
public static void draw () {
System.out.println();
System.out.println(" | | ");
System.out.println(" " + board[0][0] + " | "
+ board[0][1] + " | " + board[0][2]);
System.out.println(" | | ");
System.out.println("---+---+---");
System.out.println(" | | ");
System.out.println(" " + board[1][0] + " | "
+ board[1][1] + " | " + board[1][2]);
System.out.println(" | | ");
System.out.println("---+---+---");
System.out.println(" | | ");
System.out.println(" " + board[2][0] + " | "
+ board[2][1] + " | " + board[2][2]);
System.out.println(" | | ");
System.out.println();
}
public static void move (int square, char mark) {
if (isSquareEmpty(square)) {
spacesLeft = spacesLeft - 1;
}
int row = (square - 1) / 3;
int column = (square - 1) % 3;
board[row][column] = mark;
}
public static boolean isSquareEmpty (int square) {
int row = (square - 1) / 3;
int column = (square - 1) % 3;
return (board[row][column] == ' ');
}
public static boolean is3InRow (char mark) {
return
(board[0][0] == mark && board[0][1] == mark && board[0][2] == mark) ||
(board[1][0] == mark && board[1][1] == mark && board[1][2] == mark) ||
(board[2][0] == mark && board[2][1] == mark && board[2][2] == mark) ||
(board[0][0] == mark && board[1][0] == mark && board[2][0] == mark) ||
(board[0][1] == mark && board[1][1] == mark && board[2][1] == mark) ||
(board[0][2] == mark && board[1][2] == mark && board[2][2] == mark) ||
(board[0][0] == mark && board[1][1] == mark && board[2][2] == mark) ||
(board[0][2] == mark && board[1][1] == mark && board[2][0] == mark);
}
public static boolean isBoardFull () {
return spacesLeft == 0;
}
}
the expected result is when the game is
x o x
- - -
o x o
It prints "Tie game!" and the game ends
Hmm, simply, after every move of the "players", launch an automatic process that will compute all outcomes of the game starting from that particular position. If all of those end in a draw, then you can safely declare that the final outcome is a draw. Of course, this is the first, not at all optimized solution, that comes to my mind immediately. If you are interested, you can probably work on some optimizations based on that.
There are algorithms for this kind of task, I suggest you read about Minimax
Related
In doing a lotto checker program, where one of the constraints is to not use loops, or data structures like arrays, lists etc I've written the following piece of code to check if the 3 entries given by the user (draw1, draw2, draw3) are equal to any of the 7 random numbers generated by the program (random1, random2, random3, ...).
if (random1==draw1 || random2==draw1 || random3==draw1 || random4==draw1|| random5==draw1
|| random6==draw1 || random7==draw1)
{
if(random1==draw2 || random2==draw2 || random3==draw2 || random4==draw2|| random5==draw2
|| random6==draw2 || random7==draw2)
{
if(random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str +'\n' + "The following 3 matches were found:" +'\n'+ draw1 + " " + draw2
+ " " + draw3 ;
}else
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw1 + " " + draw2;
}
}else if (random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw1 + " " + draw3 ;
}
else
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw1;
}
}else if (random1==draw2 || random2==draw2 || random3==draw2 || random4==draw2|| random5==draw2
|| random6==draw2 || random7==draw2)
{
if(random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 2 matches were found:" + '\n' + draw2 + " " + draw3;
}
else
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw2;
}
}
else if (random1==draw3 || random2==draw3 || random3==draw3 || random4==draw3|| random5==draw3
|| random6==draw3 || random7==draw3)
{
str = str + '\n' + "The following 1 matches were found:" + '\n' + draw3;
}
else
{
str = str + '\n' + "The following 0 matches were found:" ;
}
How can I go about optimizing this and most importantly will the optimization only increase readability or will it contribute to the efficiency of the program?
Use sets, this will improve readabilty.
Set<Integer> luckyNumbers = new HashSet<>();
//Add your numbers to the set
//Integer i = ...
//luckyNumbers.add(i);
Set<Integer> drawNumbers = new HashSet<>();
//Integer i = ...
//drawNumbers.add(i);
Set<Integer> matchNumbers = new HashSet<>(luckyNumbers);
matchNumbers.retainAll(drawNumbers);
//In matchNumbers will be the intersection of the previous sets.
//There you can get the size of the intersection set or its content to show the
//matches
If you want to use a loop for this part you can do something like this:
System.out.println("Number of matches: " + matchNumbers.size());
for(Integer matchNumber : matchNumbers){
System.out.println("Match number: " + matchNumber);
}
Try this.
static boolean equalsAny(int base, int... comparisons) {
for (int c : comparisons)
if (base == c)
return true;
return false;
}
and you can rewrite
if (random1 == draw1 || random2 == draw1 || random3 == draw1 || random4 == draw1 || random5 == draw1
|| random6 == draw1 || random7 == draw1) {
to
if (equalsAny(draw1, random1, random2, random3, random4, random5, random6, random7)) {
I'm trying to make a rock-paper-scissors program that is a best two out of three where the computer randomly rolls a 0-2 and each of those are assigned to rock, paper, or scissors, and then it compares the userInput and counts a win for computer or player then adds it up.
BUT, I can't figure out how to make it that if user were to enter "scissors" the program would know that it's also assigned to 2 (For comparison purposes).
public static void main(String[] args) {
Random r = new Random();
int gameCount = 0;
int computerWins = 0;
int playerWins = 0;
int rock = 0;
int paper = 1;
int scissors = 2;
int playerChoice;
int computerChoice = r.nextInt(3);
System.out.println("Welcome to Rock Paper Scissors! Best 2 out of 3!");
while (gameCount >= 0 && gameCount < 3)
{
System.out.println("Enter \"Rock\", \"Paper\", or \"Scissors\"");
break;
}
playerChoice = userInput.nextInt()
//If player enters anything besides rock, paper, or scissors
if (playerChoice < 0 || playerChoice >= 3) {
System.out.println("That wasn't an option");
computerWins++;
gameCount++;
//The game goes on, and the winners are added up!
} else if (playerChoice == 0 && computerChoice == 1) {
computerWins++;
gameCount++;
System.out.println("Rock v Paper! Computer Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 1 && computerChoice == 0) {
playerWins++;
gameCount++;
System.out.println("Paper v Rock! Player Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 1 && computerChoice == 2) {
computerWins++;
gameCount++;
System.out.println("Paper v Scissors! Computer Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 2 && computerChoice == 1) {
playerWins++;
gameCount++;
System.out.println("Scissors v Paper! Player Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 2 && computerChoice == 0) {
computerWins++;
gameCount++;
System.out.println("Scissors v Rock! Computer Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 0 && computerChoice == 2) {
playerWins++;
gameCount++;
System.out.println("Rock v Scissors! Player Wins!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 0 && computerChoice == 0) {
gameCount++;
System.out.println("Rock v Rock! Tie!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 1 && computerChoice == 1) {
gameCount++;
System.out.println("Paper v Paper! Tie!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
} else if (playerChoice == 2 && computerChoice == 2) {
gameCount++;
System.out.println("Paper v Paper! Tie!\n" +
"Player has won " + playerWins + " times and the computer " +
"has won " + computerWins + " times");
}
//Check if game count reaches max games then chooses a winner
if (gameCount == 3 && computerWins > playerWins) {
System.out.println("The Computer Wins!");
} else if (gameCount == 3 && computerWins < playerWins) {
System.out.println("The Player Wins!");
} else if (gameCount == 3 && computerWins == playerWins) {
System.out.println("The game is a tie!");
}
}
}
So instead of playerChoice = userInput.nextInt(); try this:
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
try {
playerChoice = Integer.parseInt(input);
} catch (NumberFormatException e) {
if (input.equalsIgnoreCase("rock")) {
playerChoice = rock;
} else if (input.equalsIgnoreCase("paper")) {
playerChoice = paper;
} else if (input.equalsIgnoreCase("scissors")) {
playerChoice = scissors;
} else {
// if input is invalid
playerChoice = -1;
}
}
Since you're using userInput.nextInt() and playerChoice is an int and can only hold ints, you need to parse your user's input. In this case, Integer.parseInt(input) will try to find an int in the user input. If it can't it will return an exception; that's why there's a try-catch block. If it isn't an int, it will look for each string and assign the associated int value to playerChoice or -1 if the input is invalid. Then the rest of your code should be able to appropriately handle the playerChoice after that.
I'm creating a Tic Tac Toe game and this is the way I am checking for the win. I get this list of errors in this section of code:
/tmp/java_hoEysf/TicTacToe.java:195: error: not a statement Public
void Checkforwin(); ^ /tmp/java_hoEysf/TicTacToe.java:195: error:
';' expected Public void Checkforwin();
^ /tmp/java_hoEysf/TicTacToe.java:195: error: illegal start of expression Public void Checkforwin();
Can anyone tell me what I'm doing wrong? (The code is not complete and I'm just wondering why the method won't work.)
Code:
public void checkForWin() {
if (board [0][0] + board[0][1] + board[0][2] == 15) {
btnA3.setText("Ax");
win = 1;
}
if (board [0][0] + board[0][1] + board[0][2] == 30) {
btnA3.setText("Ao");
win = 2;
}
if (board[1][0] + board[1][1] + board[1][2] == 15) {
btnA3.setText("Ax");
win = 1;
}
if (board[1][0] + board[1][1] + board[1][2] == 30) {
btnA3.setText("Ao");
win = 2;
}
if (board[2][0] + board[2][1] + board[2][2] == 15) {
btnA3.setText("Ax");
win = 1;
}
if (board[2][0] + board[2][1] + board[2][2] == 30) {
btnA3.setText("Ao");
win = 2;
}
if (board[0][0] + board[1][0] + board[2][0] == 15) {
btnA3.setText("Ax");
win = 1;
}
if (board[0][0] + board[1][0] + board[2][0] == 30) {
btnA3.setText("Ao");
win = 2;
}
}
In Java the right keyword is public not Public, indeed it is case sensitive.
You can find the list of all the existing keywords in Java and their meaning here.
This is my code:
/* Name: Steven Royster
* Date: Jan. 15, 2015
* Rock, Paper, Scissors Program
* This program simulates a game of rock, paper, scissors with the user until someone has one a total of five times.
*/
import java.util.Random;
import java.util.Scanner;
public class RPS {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Let's play rock, paper, scissors! First to five wins!");
String[] choice = { "zero" , "rock" , "paper" , "scissors" };
Random rander = new Random();
Scanner input = new Scanner(System.in);
int userScore = 0, compScore = 0,
userChoice, compChoice;
while (compScore < 5 && userScore < 5)
{
compChoice = rander.nextInt(3) + 1;
System.out.println("\nEnter: 1 for ROCK | 2 for PAPER | 3 for SCISSORS.");
userChoice = input.nextInt();
if (compChoice == userChoice) // tie
{
System.out.println("I chose " + choice[compChoice] + " too, so we tied!");
}
else if ( ( compChoice == 1 && userChoice == 3 ) //computer wins
|| ( compChoice == 2 && userChoice == 1 )
|| ( compChoice == 3 && userChoice == 2) )
{
System.out.println("I win! I chose " + choice[compChoice] + ". " +
choice[compChoice] + " beats " + choice[userChoice] + "." );
compScore += 1;
}
else //human wins
{
System.out.println("You win! I chose " + choice[compChoice] + ". " +
choice[userChoice] + " beats " + choice[compChoice] + ".");
userScore += 1;
}
}//end while
if (userScore == 5)
{
System.out.println("\nCongrats! You're the winner! You got "
+ userScore + " points. I only got " + compScore + " points." );
}
}//end main
}//end class
Is there a better algorithm I can implement rather than using the three separate conditions within my else-if statement? Also, instead of having the 'zero' string in my array, how could I check through my array using only numbers 1, 2, and 3?
Just use
String[] choice = { "rock" , "paper" , "scissors" };
Then instead of choice[userChoice] you can do choice[userChoice - 1].
You don't need to write
if ( ( compChoice == 1 && userChoice == 3 )
|| ( compChoice == 2 && userChoice == 1 )
|| ( compChoice == 3 && userChoice == 2) )
because it is the same as
if (compChoice == 1 + (userChoice % 3))
So, I am creating a text-based game where you fill in the blanks on the board with the letters, "S, M, A, R, T". To beat this game each row and column can only contain 1 out of the 5 given letters. (It's kind of like the game Sudoku) The game runs perfectly fine but when the user inputs the the row and column they want the letter to be in, it doesn't appear on the board. Could anyone please help me out? Thank you in advance. (Note: I am still new to java coding)
import java.util.Scanner;
public class SmartPuzzleProgram{
static Scanner keyboard = new Scanner(System.in);
static char[][] table = new char[5][5];
public static void main (String[] args){
Board(table);
int i = 0;
while (i < 5){
if( ((int)table[i][0] + (int)table[i][1] + (int)table[i][2] + (int)table[i][3] + (int)table[i][4]) != 391 ){
Move();
Board(table);
}
else
i++;
}
int j = 0;
while (i < 5){
if( ((int)table[0][j] + (int)table[1][j] + (int)table[2][j] + (int)table[3][j] + (int)table[4][j]) != 391 ){
Move();
Board(table);
}
else
j++;
}
System.out.println("Congratulations! You must be SMART.");
}
public static void Move(){
// Ask for user's input
System.out.print("Enter a row (1-5): ");
int r = keyboard.nextInt();
System.out.print("Enter a column (1-5): ");
int c = keyboard.nextInt();
System.out.print("Enter a letter (S,M,A,R or T): ");
char L = keyboard.next().toUpperCase().charAt(0);
if (L == 'S' || L == 'M' || L == 'A' || L == 'R' || L == 'T') {
table[r-1][c-1] = L;
}
else
// Error check
System.out.println("Invalid letter. Use 'S', M', 'A', 'R' or 'T'");
}
public static void Board(char[][] t){
// Given variables
t[0][0] = 'S';
t[0][1] = 'M';
t[0][2] = 'A';
t[0][3] = 'R';
t[0][4] = 'T';
t[1][0] = ' ';
t[1][1] = 'T';
t[1][2] = 'S';
t[1][3] = 'M';
t[1][4] = ' ';
t[2][0] = ' ';
t[2][1] = ' ';
t[2][2] = 'R';
t[2][3] = ' ';
t[2][4] = 'S';
t[3][0] = ' ';
t[3][1] = 'S';
t[3][2] = 'M';
t[3][3] = ' ';
t[3][4] = ' ';
t[4][0] = ' ';
t[4][1] = ' ';
t[4][2] = 'T';
t[4][3] = 'S';
t[4][4] = ' ';
// Prints out the board
System.out.println(" 1 2 3 4 5 ");
System.out.println(" ---+---+---+---+--- ");
System.out.println("1 | " + t[0][0] + " | " + t[0][1] + " | " + t[0][2] + " | " + t[0][3] + " | " + t[0][4] + " |");
System.out.println(" ---+---+---+---+--- ");
System.out.println("2 | " + t[1][0] + " | " + t[1][1] + " | " + t[1][2] + " | " + t[1][3] + " | " + t[1][4] + " |");
System.out.println(" ---+---+---+---+--- ");
System.out.println("3 | " + t[2][0] + " | " + t[2][1] + " | " + t[2][2] + " | " + t[2][3] + " | " + t[2][4] + " |");
System.out.println(" ---+---+---+---+--- ");
System.out.println("4 | " + t[3][0] + " | " + t[3][1] + " | " + t[3][2] + " | " + t[3][3] + " | " + t[3][4] + " |");
System.out.println(" ---+---+---+---+--- ");
System.out.println("5 | " + t[4][0] + " | " + t[4][1] + " | " + t[4][2] + " | " + t[4][3] + " | " + t[4][4] + " |");
System.out.println(" ---+---+---+---+--- ");
}
}
The problem is that you are assigning the values to table each time you call the Board() method, you may want to initialize them just one time. For this, create a new method, let's say initialize():
public static void initialize()
{
System.out.println("here");
table[0][0] = 'S';
table[0][1] = 'M';
table[0][2] = 'A';
table[0][3] = 'R';
table[0][4] = 'T';
table[1][0] = ' ';
table[1][1] = 'T';
table[1][2] = 'S';
table[1][3] = 'M';
table[1][4] = ' ';
table[2][0] = ' ';
table[2][1] = ' ';
table[2][2] = 'R';
table[2][3] = ' ';
table[2][4] = 'S';
table[3][0] = ' ';
table[3][1] = 'S';
table[3][2] = 'M';
table[3][3] = ' ';
table[3][4] = ' ';
table[4][0] = ' ';
table[4][1] = ' ';
table[4][2] = 'T';
table[4][3] = 'S';
table[4][4] = ' ';
}
And call it at the beginning of the main():
public static void main(String[] args)
{
initialize();
Board(table);
...
}