Tic-Tac-Toe Program Design Level 1 in Java - java

I need assistance on how to start 'playing' the game like if the user inputs any number from 1-9 that number will be replaced by 'X' or 'O'.
Here is my code so far:
import java.util.Scanner;
public class TicTacToe {
public static char[][] board = new char[3][3];
public static void main(String[] args){
Scanner kb = new Scanner(System.in);
Player player1 = new Player("John");
Player player2 = new Player("Jill");
initBoard();
int turn = 1;
int choice = 0;
while(choice != -1){
printBoard();
Player currentPlayer = player1;
if(turn % 2 == 0){
currentPlayer = player2;
}
System.out.print(currentPlayer + ", pick a box: ");
if(choice == 1){
board[0][0] = 'X';
}
turn++;
choice = kb.nextInt();
}
}
public static void initBoard(){
for(int r = 0; r < board.length; r++){
for(int c = 0; c < board[r].length; c++){
board[r][c] = (char)((r*3)+(c+1)+48);
}
}
}
public static void printBoard(){
for(int r = 0; r < board.length; r++){
for(int c = 0; c < board[r].length; c++){
System.out.print(board[r][c]+" ");
}
System.out.println();
}
}
}
class Player{
String name;
int wins = 0;
int losses = 0;
int draws = 0;
public Player(String s){
name = s;
}
public String toString(){
return name;
}
}
Note: I'm not asking anyone to complete my homework for me, I just need a hint on how to place the 'X's and 'O's and to check to see if one of the boards has already an 'X' or 'O'.

I suppose that you are asking how to convert 1-9 into matrix indices.
In such case, if you the matrix
`
|0|1|2| -----> j - column
|1|2|3| 0
|4|5|6| 1
|7|8|9| 2
`
You could find the pattern that allows you to convert numbers to indicies.
i = (input - 1) / 3;
j = (input - 1) % 3;

You are on the right track, you can do something like:
if (board[row][col] != 'X' || board[row][col] != 'O'){ //Position is currently a number since it isn't X or O
// do something here since move is valid
}
You can also also initialize your board to ' ' instead of the actual numbers, then check if the board spot is equal to a space or not.
public static void initBoard(){
for(int r = 0; r < board.length; r++){
for(int c = 0; c < board[r].length; c++){
board[r][c] = ' '; // space here instead of numbers
}
}
}
if (board[row][col] == ' '){ // Board spot is a space so spot has not been played on
// do something here since move is valid
}

Related

Making Connect Four in Java (Dropping the checker)

Right now I'm making Connect Four in Java. I'm currently working on being able to drop the checker but I'm running into some problems. This is my code so far:
private static char board[][];
private static final int BOARD_WIDTH = 7;
private static final int BOARD_HEIGHT = 6;
private static boolean gameEnd = false;
public static void main(String[] args)
{
// Element #0 in the two-dimensional 'board' array is not used
// so that the column numbers selected by the players match
// with the actual internal element numbers of the array
board = new char[BOARD_HEIGHT + 1][BOARD_WIDTH + 1];
Scanner input = new Scanner(System.in);
char turn = 'x';
int dropColumn = 0;
System.out.println("TWO PLAYER CONNECT FOUR GAME!");
InitializeBoard();
while (gameEnd == false)
{
DisplayBoard();
dropColumn = GetDropColumn(turn, input);
if (turn == 'x')
turn = 'o';
else
turn = 'x';
if (DropChecker(turn, dropColumn) == true)
board[BOARD_HEIGHT][dropColumn] = turn;
}
}
// Set all elements of the two-dimensional 'board' array to spaces
private static void InitializeBoard()
{
char a = ' ';
for (int i = 0; i < board.length; i++)
{
board[i][0] = a;
}
for (int e = 0; e < board.length; e++)
{
board[0][e] = a;
}
}
// Display the game board (the board itself, along with the elements of
// the two-dimensional 'board' array); note that the lines of the game
// board are NOT stored in the two-dimensional 'board' array
private static void DisplayBoard()
{
for (int row = 0; row < board.length; row++)
{
for (int col = 0; col < board.length; col++)
{
System.out.print("|");
System.out.printf("%3c", board[row][col]);
}
System.out.println();
}
}
// Get (from the appropriate player) the number (1 – 'BOARD_WIDTH') of
// the column in which a checker should be dropped, and then return that
// number; if the player does not enter an integer, report the error and
// keep asking for a column number until an integer is entered; note that
// the check for an invalid column number (< 1 or > 'BOARD_WIDTH') can be
// performed in this method or in 'main', from where this method is called
private static int GetDropColumn(char turn, Scanner input)
{
int numInput = 0;
int realInput = 0;
while (realInput == 0)
{
try
{
System.out.println("Player " + turn + "'s turn: In which column would you like to place a checker? (1-7)");
numInput = input.nextInt();
if (numInput < 1 || numInput > BOARD_WIDTH)
{
numInput = 0;
System.out.println("The number was out of bounds. Please try again.");
}
}
catch (NumberFormatException e)
{
System.out.println("Invalid input. Please try again.");
}
realInput = numInput;
}
return realInput;
}
// "Drop" a checker into the designated column by setting the
// appropriate element of the two-dimensional 'board' array to
// either an 'x' or an 'o'; if the "drop" was successful, this
// method returns "true"; an attempt to "drop" the checker into
// a full column results in "false" being returned
private static boolean DropChecker(char turn, int dropColumn)
{
int count = 0;
while (count < BOARD_HEIGHT)
{
if (board[BOARD_HEIGHT - count][dropColumn] == ' ')
{
return true;
}
count++;
}
return false;
}
My problem currently is that the program won't drop the checker on the board. After I enter column 6, the program returns the board but the checker has not been dropped. What am I missing/doing wrong here?
There are a few issues with your code
The turn of the player's is reversed, so what you need to do is change the player AFTER they drop the piece, not before
The initialize board method is off, just use two for loops to initialize it
The index of placing the checker was incorrect, so start with the index at the bottom and then decrement whenever the space isn't "empty" (== ' ')
1.Main Game Loop Refactor
while (gameEnd == false)
{
DisplayBoard();
dropColumn = GetDropColumn(turn, input);
if (DropChecker(turn, dropColumn) == true)
{
turn = 'x' == turn ? 'o' : 'x'; //ternary operator works great
}
}
2.Initialize Method refactor
private static void InitializeBoard()
{
char a = ' ';
for (int i = 0; i < board.length; i++)
{
for (int e = 0; e < board[i].length; e++)
board[i][e] = a;
}
}
3.Drop Checker Method Refactor
private static boolean DropChecker(char turn, int dropColumn)
{
int indexToPaceChecker = BOARD_HEIGHT;
while (indexToPaceChecker >= 0)
{
if (board[indexToPaceChecker][dropColumn] == ' ')
{
//drop the checker, that's what this method is supposed to do anyways :)
board[indexToPaceChecker][dropColumn] = turn;
return true;
}
indexToPaceChecker--;
}
return false;
}
I'd also recommend using private static final char emptySpace = ' '; that way in your code you can intitialize the board like board[i][e] = emptySpace;, and check for an empty space like if (board[indexToPaceChecker][dropColumn] == emptySpace). It's cleaner and easier to make changes if you wanted a different board fill.
DropChecker() just checks if there is a free place in the column. Instead you should return which line is the lowest one (the one with the highest index), if there is no you could return -1.
You are setting the wrong row with the following line: board[BOARD_HEIGHT][dropColumn] = turn this puts turn into last line.
You are also not initializing your board array (if you not initialize it, it's not the same as ' ', which is also a char)
This should work for you:
private static int DropChecker(char turn, int dropColumn) {
int count = 0;
while (count < BOARD_HEIGHT) {
if (board[BOARD_HEIGHT - count][dropColumn] == ' ') {
count++;
}
else {
return --count;
}
}
}
You set the place in the board with this:
board[DropChecker(turn, dropColumn)][dropColumn]
Add this lines at the beginning of main, right after board = new char[][] :
for(int i = 0; i < BOARD_HEIGHT; i++) {
for(int j = 0; j < BOARD_WIDTH; j++) {
board[i][j] = ' ';
}
}

(Java) Minesweeper clone not correctly revealing squares?

so basically I've been making a minesweeper clone in Java. I had it working perfectly until I added the game win and lose parts and the big opening print. Now when I run it some of the spots that are next to zero's don't get revealed, even though they should. I can't figure out where the bug is though. Here's my code:
/**
* A program to play Scat Scout...
*/
import static java.lang.System.*; // so you can write out.println() instead of System.out.println()
import java.util.*;
class ScatScout {
static final int boardSize = 10;
static final Random rand = new Random();
static final boolean SCAT = true;
static final boolean CLEAR = false;
static int clearCounter = 100;
static boolean gameWon = false;
static boolean gameLost = false;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean[][] board = new boolean[boardSize+2][boardSize+2]; // scat or no scat
boolean[][] exposed = new boolean[boardSize+2][boardSize+2]; // showing or hidden
int[][] counts = new int[boardSize+2][boardSize+2]; // number of neighbors with scat
if (args.length > 0) {
rand.setSeed(Integer.parseInt(args[0]));
}
System.out.println("comment explaining game");
createScat(board); //initialize the board
compareScat(board, counts); //find how many scat are next to each spot
while(!gameWon&&!gameLost){ //keep going until game win or loss
printBoard(board, counts, exposed);
System.out.println("Enter two integers (row and column):");
expose(input.nextInt()+1, input.nextInt()+1, board, exposed, counts);
if (gameLost){
for (int i = 1; i<= board.length-2; i++){
for (int j = 1; j<= board.length-2; j++){
if (!board[i][j]){
exposed[i][j] = true;
}
}
}
printBoard(board, counts, exposed);
System.out.print("You stepped in it! Yucky!"); //game lose
break;
}
gameWon = true; //game is one if all blanks but the bombs are exposed
for(int i = 1; i<= board.length-2; i++){
for(int j = 1; j<= board[0].length-2; j++){
if(!exposed[i][j]&&!board[i][j]){
gameWon=false; //otherwise continue loop
}
}
}
if (gameWon){
System.out.print("You cleared the scat! Congrats!"); //game win message
break;
}
}
input.close();
}
public static void printBoard(boolean[][] board, int[][] counts, boolean[][] exposed){ //initialize board
int numRows = counts.length;
int numCols = counts[0].length;
System.out.println(" 0123456789"); //print the border
for(int i=1; i<=numRows-2; i++){
System.out.print(i-1 + " "); //border
for(int j=1; j<=numCols-2; j++){
if (exposed[i][j] == true){
System.out.print(counts[i][j]); //print the scat near a spot if it's exposed
}
else{
System.out.print("*"); //print unknown spot
}
}
System.out.print(" ");
System.out.print(i-1); //border
System.out.println(" ");
}
System.out.println(" 0123456789"); //border
}
public static void createScat(boolean[][] board){ //randomly seed scat into field
for(int i=1; i<= board.length-2; i++){
int x = rand.nextInt(board.length-3)+1;
int y = rand.nextInt(board.length-3)+1;
if(x!=0&&x!=11&&y!=0&&y!=11&&board[x][y]==CLEAR){
board[x][y]=SCAT; //scat in this random spot
}
}
}
public static void compareScat(boolean[][] board, int[][] counts){ //checks #scat in surrounding spots
int numRows = counts.length;
int numCols = counts[0].length;
for(int i=1; i<=numRows-2; i++){
for(int j=1; j<=numCols-2; j++){
for(int ii=i-1; ii<=i+1; ii++){
for(int jj=j-1; jj<=j+1; jj++){
if(board[ii][jj]==SCAT){ //this looks at all scat in all directions around the original spot
counts[i][j]=counts[i][j]+1; //adds to the counter if scat found around it
}
}
}
}
}
}
static void expose(int c, int r, boolean[][] board, boolean[][] exposed, int[][] counts) { //exposes chosen spot
if (exposed[r][c]) return; // nothing to do
if (board[r][c]== SCAT){
gameLost=true; //lose game if choose a spot with scat
}
exposed[r][c] = true; // expose any neighbors that have zero counts
if (counts[r][c] > 0) return;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int x = r+i;
int y = c+j;
if (!(i==1 && j==1) && x >= 1 && x < board.length-1 && y >= 1 && y < board[x].length-1) {
if (counts[x][y] == 0) {
expose(x, y, board, exposed, counts);
}
else {
exposed[x][y] = true;
}
}
}
}
}
}

Writing the findWinner() for a tictactoe game

I am writing a tictactoe game and I am stuck in writing the findWinner(). The following is what I have but it does not do anything when a player wins any diagonal.
I am using access1 and access2 to evaluate whether all the members of the array are equal or not. Since the loop happens 2 times, if they equal 2, then I return true. Thank you
public static boolean diagonalTest()
{
/*create a TicTacToe object to access private fields*/
TicTacToe temp = new TicTacToe();
/*an ArrayList to store the values*/
ArrayList<Character> major = new ArrayList<Character>();
int k = 0;
while(k < temp.getRow())
{
major.add(temp.getBoard()[k][k]);
k++;
}
/*to test whether the values in the array are equal to each other*/
int access1 = 0;
for(int i = 1; i < major.size(); i++)
if(major.get(0) != ' ' && major.get(0) == major.get(i))
access1++;
ArrayList<Character> minor = new ArrayList<Character>();
k = 0;
while(k < temp.getRow())
{
minor.add(temp.getBoard()[k][temp.getColumn() - 1 - k]);
k++;
}
int access2 = 0;
for(int a = 1; a < minor.size(); a++)
if(minor.get(0) != ' ' && minor.get(0) == minor.get(a))
access2++;
if(access1 == 2 || access2 == 2)
return true;
return false;
}

Trouble with randomly generated arrays

So I am working on a assignment that deals with randomly generated arrays. Here is the assignment:
Write the following function that tests whether a two-dimensional list has four consecutive numbers of the same value, either horizontally, vertically, or diagonally. public static boolean isConsecutiveFour(int[][] values) Write a test program that prompts the user to enter the number of rows and columns of a two-dimensional list and then use a random number generator to fill the array and print it out. Display True if the list contains four consecutive numbers with the same value. Otherwise, display False.
I got everything else done, and it seems to work, but I am stuck on the randomly generating the array part. What is supposed to happen is the user is supposed to enter in the amount of rows and columns for an array, then it is generated. Then, the array is tested to find out whether or not four consecutive numbers exist. When I come to test the problem, it does not actually display the numbers. I am at a loss, and really confused ( Can anyone help me or give me a hint? It would be greatly appreciated. Thank You!
import java.util.Random;
import java.util.Scanner;
public class ConsecutiveFour {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random r = new Random();
System.out.print("Enter number of rows: ");
int rows = input.nextInt();
input.nextLine();
System.out.print("Enter number of columns: ");
int columns = input.nextInt();
input.nextLine();
int[][] matrix = new int[rows][columns];
// generate some random boolean values
boolean[] booleans = new boolean[10];
for (int i = 0; i < booleans.length; i++) {
booleans[i] = r.nextBoolean();
}
for (boolean b : booleans) {
System.out.print(b + ", ");
}
System.out.println("");
}
public static boolean isConsecutiveFour(int[][] values) {
boolean cons = false;
int
//tests horizontally
for (int r=0; r < rows; r++) {
for (int c=0; c < columns - 3; c++){
if (values[c][r] == values[c+1][r] &&
values[c][r] == values[c+2][r] &&
values[c][r] == values[c+3][r]) {
cons = true;
}
}
}
//tests vertically
for (int r=0; r < rows - 3; r++) {
for (int c=0; c < columns; c++){
if (values[c][r] == values[c][r+1] &&
values[c][r] == values[c][r+2] &&
values[c][r] == values[c][r+3]) {
cons = true;
}
}
}
//tests diagonally (going down and to the right)
for (int r=3; r < rows; r++) {
for (int c=0; c < columns - 3; c++) {
if (values[c][r] == values[c+1][r-1] &&
values[c][r] == values[c+2][r-2] &&
values[c][r] == values[c+3][r-3]) {
cons = true;
}
}
}
//tests diagonally (going down and to the left)
for (int r=0; r < rows - 3; r++) {
for (int c=0; c < columns - 3; c++) {
if (values[c][r] == values[c+1][r+1] &&
values[c][r] == values[c+2][r+2] &&
values[c][r] == values[c+3][r+3]) {
cons = true;
}
}
}
return cons;
}
}
To start both of the input.nextLine(); lines are unnecessary. Your input.nextInt(); will be enough to bring in the two values that you need.
It might be easier for you to generate the exact number of random numbers that you need. Seeing how this is an assignment i'll throw you some pseudo code to work through.
for (int i = 0; i < rows; i++) {
for (int k = 0; i < columns; k++) {
int ranNum // Generate random number
// Place random number in matrix[i][k]
}
}
// Send array through checks
Is this the problem you are having or am I misunderstanding your confusion?

Using Recursion in java

I'm working on the Conway's game of life program. I have the first two generations of cells printed out, but I can not get anymore printed. So I decided to use recursion so multiple batches of cells can be printed. My NewCells method creates the second generation. I thought that If I were to repeat said method by returning NewCells(c) instead of c, It would print out different results, but it prints out the same batch of cells over and over again.
public class Life {
public static boolean[][] NewCells(boolean[][] c)
{
int N = 5;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("Next Generation");
// Checks for the amount of "*" surrounding (o,p)
for (o=0; o < N; o++)
{
for (p=0; p<N; p++)
{
for (int k=(o-1); k <= o+1; k++)
{
for (int l =(p-1); l <=p+1; l++)
{
if ( k >= 0 && k < N && l >= 0 && l < N) //for the border indexes.
{
if (!(k== o && l==p)) //so livecnt won't include the index being checked.
{
if (c[k][l] == true)
{
livecnt++;
}
}
}
}
}
livestore[store]= livecnt;
livecnt = 0;
store++;
}
}
//Prints the next batch of cells
int counter= 0;
for (int i2 = 0; i2 <N; i2++)
{
for (int j2 = 0; j2 < N; j2++)
{
if (c[i2][j2] == false)
{
if (livestore[counter] ==3)
{
c[i2][j2]=true;
System.out.print("* ");
}
else
System.out.print("- ");
}
else if (c[i2][j2] == true)
{
if (livestore[counter] ==1)
{
c[i2][j2]= false;
System.out.print("- ");
}
else if (livestore[counter] >3)
{
c[i2][j2]= false;
System.out.print("- ");
}
else
System.out.print("* ");
}
counter++;
}
System.out.println();
}
return NewCell(c);
}
/*************************************************************************************************************************************************/
public static void main(String[] args)
{
int N = 5;
boolean[][] b = new boolean[N][N];
double cellmaker = Math.random();
int i = 0;
int j = 0;
int o=0;
int p=0;
int livecnt = 0; //keeps track of the alive cells surrounding cell
int store = 0; //amount of surrounding cells for each individual cell
int livestore[] = new int[N*N];
System.out.println("First Generation:");
// Makes the first batch of cells
for ( i = 0; i < N ; i++)
{
for ( j = 0; j< N; j++)
{
cellmaker = Math.random();
if (cellmaker > 0.5) // * = alive; - = dead
{
b[i][j]=true;
System.out.print( "* ");
}
if (cellmaker < 0.5)
{ b[i][j] = false;
System.out.print("- ");
}
}
System.out.println();
}
boolean[][] newcells = new boolean[N][N];
newcells = NewCells(b);
}
}
I do not think recursion is a good idea for this application. It leads to a StackOverflowError because each generation pushes another call stack frame. Recursion, as this program uses it, has no advantage over iteration.
Instead, put the main method call to NewCells in a loop. That way, you can run as many iterations as you like, regardless of stack size.
You are not calling NewCell from within NewCell, which is how recursion works.
I'm assuming it's not a typo in your question, but rather a lack of understanding of what it is and how it works, I recommend some reading on recursion in Java.
After you understand the basics, come back here for more help!

Categories