My check vertical win and check horizontal win work perfectly fine, however i dont know what to do with my check diagonal code to make it actually check diagonal. Some guidance would be much appreciated and this is in java. Thank you.
private boolean checkVerticalWin()
{
PieceType type = myBoard[myLastPoint.x][myLastPoint.y];
System.out.println("check vert");
for(int j = 0; j < myNumColumns; j++)
{
for(int i = 0; i < myNumRows; i++)
{
if(myBoard[i][j] == type && myBoard[i][j] != null )
{
count++;
if(count == 1)
{
myWinBegin = new Point(i,j);
}
}
else
{
myWinBegin = null;
count = 0;
}
System.out.println(count);
if(count == myWinLength)
{
myWinEnd = new Point(i,j);
return true;
}
}
}
myWinBegin = null;
return false;
}
private boolean checkHorizontalWin()
{
System.out.println("test");
PieceType type = myBoard[myLastPoint.x][myLastPoint.y];
for(int i = 0; i < myNumRows; i++)
{
for(int j = 0; j < myNumColumns; j++)
{
if(myBoard[i][j] == type && myBoard[i][j] != null)
{
count++;
if (count == 1)
{
myWinBegin = new Point(i,j);
}
}
else
{
myWinBegin = null;
count = 0;
}
if(count == myWinLength)
{
myWinEnd = new Point(i,j);
return true;
}
}
}
myWinBegin = null;
return false;
}
private boolean checkDiagonalWin()
{
PieceType type = myBoard[myLastPoint.x][myLastPoint.y];
for(int i = 0; i < myNumRows; i++)
{
for (int j = 0; j < myNumColumns; j++)
{
if(myBoard[i][j] == type && myBoard[i][j] != null )
{
count++;
myWinBegin = new Point(i,j);
}
else
{
count = 0;
myWinEnd = new Point(i,j);
}
if(count == myWinLength)
{
return true;
}
}
}
for(int j = 0; j < myNumColumns; j--)
{
for (int i = 0; i < myNumRows; i--)
{
if(myBoard[i][j] == type && myBoard[i][j] != null )
{
count++;
myWinBegin = new Point(i,j);
}
else
{
count = 0;
}
if(count == myWinLength)
{
myWinEnd = new Point(i,j);
return true;
}
}
}
for(int j = 0; j < myNumColumns; j++)
{
for (int i = 0; i < myNumRows; i--)
{
if(myBoard[i][j] == type && myBoard[i][j] != null )
{
count++;
}
else
{
myWinBegin = new Point(i,j);
count = 0;
}
if(count == myWinLength)
{
myWinEnd = new Point(i,j);
return true;
}
}
}
for(int j = 0; j < myNumColumns; j--)
{
for (int i = 0; i < myNumRows; i++)
{
if(myBoard[i][j] == type && myBoard[i][j] != null )
{
count++;
myWinBegin = new Point(i,j);
}
else
{
count = 0;
}
if(count == myWinLength)
{
myWinEnd = new Point(i,j);
return true;
}
}
}
return false;
}
So basically, you need a start point, you then need to determine in which direction to move
With that idea in hand, you could use something like...
boolean win = true;
for (int count = 0; count < 4; count++) {
if (row < myNumRows && row >= 0 && col < myNumColumns && col >= 0) {
int test = myBoard[row][col];
if (test != check) {
win = false;
break;
}
} else {
break;
}
row += rowDelta;
col += colDelta;
}
As the basic algorithm. All this does is checks each cell from a start point, to a total of 4 cells, the algorithm moves by the specified delta/direction and keeps checking while each cell matches the check value.
Now, I'd wrap this in a simple method
public boolean didWin(int[][] grid, int check, int row, int col, int rowDelta, int colDelta) {
boolean win = true;
for (int count = 0; count < 4; count++) {
if (row < ROWS && row >= 0 && col < COLUMNS && col >= 0) {
int test = grid[row][col];
if (test != check) {
win = false;
break;
} else {
break;
}
}
row += rowDelta;
col += colDelta;
}
return win;
}
which makes it simpler to call, know given any point, you can do something like...
int startRow = ...;
int startCol = ...;
int player = ...;
if (didWin(myBoard, player, startRow, startCol, 1, 0) || // Vertical, down
didWin(myBoard, 1, startRow, startCol, 0, 1) || // Right
didWin(myBoard, 1, startRow, startCol, 0, -1) || // Left
didWin(myBoard, 1, startRow, startCol, 1, 1) || // Right/down
didWin(myBoard, 1, startRow, startCol, -1, -1) || // Left/Up
didWin(myBoard, 1, startRow, startCol, 1, -1) || // Down/Left
didWin(myBoard, 1, startRow, startCol, -1, 1) // Up/Right
) {
// You be the winner
}
nb: I've left out check a vertical up direction, because it's unlikely that you could actually win this way
ps: I'd be even more lazy and would just have a didWin method, which did the above checks and returned true or false, but I'm lazy
So, the startRow and startCol would represent the anchor point around which you want to check and would, in this example, represent the last drop.
This example uses a int to represent the player/token, but you could use anything, all this does is compares the token you supply with the values in the array
Related
This question already has an answer here:
Customizable TicTacToe game board with Java
(1 answer)
Closed 28 days ago.
Already implemented horizontal and vertical methods, i can't figure out diagonals
That's my working methods:
private boolean checkHorizontalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK HORIZONTAL WIN
for (int row = 0; row < gameSize; row++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, 0);
int counter = 1;
for (int column = 0; column < gameSize; column++) {
char pawn = getPawnAtCoords(gameBoard, gameSize, row, column);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
return false;
}
private boolean checkHVerticalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK VERTICAL WIN
for (int column = 0; column < gameSize; column++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, 0, column);
int counter = 1;
for (int row = 0; row < gameSize; row++) {
char pawn = getPawnAtCoords(gameBoard, gameSize, row, column);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
return false;
}
Anyone got an idea for diagonals?
Already tried everything what i can do by myself.
ChatGPT did it
private boolean checkDiagonalWin(String gameBoard, int gameSize, int gameDifficulty) {
// CHECK DIAGONAL WIN (LEFT TO RIGHT)
for (int row = 0; row < gameSize - gameDifficulty + 1; row++) {
for (int col = 0; col < gameSize - gameDifficulty + 1; col++) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, col);
int counter = 1;
for (int i = 1; i < gameDifficulty; i++) {
int nextRow = row + i;
int nextCol = col + i;
char pawn = getPawnAtCoords(gameBoard, gameSize, nextRow, nextCol);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
}
// CHECK DIAGONAL WIN (RIGHT TO LEFT)
for (int row = 0; row < gameSize - gameDifficulty + 1; row++) {
for (int col = gameSize - 1; col >= gameDifficulty - 1; col--) {
char candidate = getPawnAtCoords(gameBoard, gameSize, row, col);
int counter = 1;
for (int i = 1; i < gameDifficulty; i++) {
int nextRow = row + i;
int nextCol = col - i;
char pawn = getPawnAtCoords(gameBoard, gameSize, nextRow, nextCol);
if ((pawn == candidate) && (pawn != '-')) {
counter++;
} else {
counter = 1;
candidate = pawn;
}
if (counter == gameDifficulty) {
return true;
}
}
}
}
return false;
}
So I keep running into a problem with my code for checking if there is a connect 4 vertically. Preface to my code: the board has 6 rows and 7 columns, the variable player1 holds the value of the character being used as a chip and playerID just holds the value of whoever gets the connect 4.
public int verticalWin() {
int playerID = 0;
for (int x = 0; x < board[x].length; x++) {
int count = 1;
for (int y = board.length-2; y >= 0; y--) {
if (board[y][x] == board[y+1][x]) {
count++;
if (count == 4) {
if (board[y][x] == player1) {
playerID = 1;
} else {
playerID = 2;
}
}
} else {
count = 1;
}
}
}
return playerID;
}
The problem I keep running into is that an exception java.lang.ArrayIndexOutOfBoundsException: 6 keeps happening and I think it's in the first line, but I can't seem to find the problem.
Some cleaner code
boolean isWinnerOnColumn(int playerID, int column) {
int count = 0;
for (int row = 0; row < 6; row++) {
count = (board[row][column] == playerID) ? (count + 1) : 0;
if (count == 4){
return true;
}
}
return false;
}
public int verticalWin() {
for (int column = 0; column < 7; column++) {
if (isWinnerOnColumn(1, column) {
return 1;
}
if (isWinnerOnColumn(2, column) {
return 2;
}
}
return 0; // no winner
}
why i need to write:
mat.length-1
in the second for loop (the loop it all conditions).
the loop:
for (int i = 0; i < mat.length-1; i++) {
for (int j = 0; j < mat.length-1; j++) {
if (i == j) {
j++;
if (i == mat.length - 1 && j == mat.length - 1) {
break;
}
}
if (i != j && mat[i][j] == mat[j][i]) {
flag = true;
} else {
flag = false;
if (flag == false) {
stop = 1;
i = mat.length - 1;
}
}
}
}
Checking program applies
Complete code:
public class test {
public static void main(String[] args) {
//int[][] mat = { { 9, 2, 4 }, { 2, 9, 7 }, { 4, 7, 9 } };
int[][]mat = { { 9, 2, 3, 4},
{ 2, 9, 6, 3},
{ 3, 6, 9 ,2},
{ 4, 3, 2 ,9}};
boolean flag = true;
int stop = 0;
for (int i = 0; i < mat.length; i++) {
for (int j = 0; j < mat.length; j++) {
System.out.print("[" + mat[i][j] + "]");
}
System.out.println();
}
for (int i = 0; i < mat.length-1; i++) {
for (int j = 0; j < mat.length-1; j++) {
if (i == j) {
j++;
if (i == mat.length - 1 && j == mat.length - 1) {
break;
}
}
if (i != j && mat[i][j] == mat[j][i]) {
flag = true;
} else {
flag = false;
if (flag == false) {
stop = 1;
i = mat.length - 1;
}
}
}
}
if (stop == 1) {
System.out.println("Not first folded matrix");
} else {
System.out.println("First folded matrix");
}
}
}
this is work but if i change it to
mat.length
It does not work
If I write a negative one then it stops the loop of the i before it reaches the end of the array.
Can explanation?
In your code, these lines serve no purpose as i and j would never be equal to (mat.length-1) in your code.
if (i == mat.length - 1 && j == mat.length - 1) {
break;
}
Change your code to :
for (int i = 0; i < mat.length; i++) {
for (int j = i+1; j < mat.length; j++) {
if (mat[i][j] != mat[j][i]) {
flag = false;
j = mat.length;
i = mat.length;
}
}
}
if (flag == false) {
System.out.println("Not first folded matrix");
} else {
System.out.println("First folded matrix");
}
I am programming a minesweeper game, and having a problem making the main method. I cant seem to get the text based game to output to the screen, allowing the user to interact with it. I have tried several ways, but none have worked.
public class Game {
private Board board;
boolean finish = false;
boolean win = false;
int turn = 0;
public void Jogo() {
board = new Board();
Play(board);
}
public void Play(Board board) {
do {
turn++;
System.out.println("Turn " + turn);
board.show();
finish = board.setPosition();
if (!finish) {
board.openNeighbors();
finish = board.win();
}
} while (!finish);
if (board.win()) {
System.out.println("Congratulations, you let the 10 fields with the mines in " + turn
+ " turns");
board.showMines();
} else {
System.out.println("Mine! You lost!");
board.showMines();
}
}
}
import java.util.Random;
import java.util.Scanner;
public class Board extends Game {
private int[][] mines;
private char[][] boardgame;
private int Line, Column;
Random random = new Random();
Scanner input = new Scanner(System.in);
public void Jogo() {
mines = new int[10][10];
boardgame = new char[10][10];
startMines();
randomMines();
fillTips();
startBoard();
}
public boolean win() {
int count = 0;
for (int line = 1; line < 9; line++)
for (int column = 1; column < 9; column++)
if (boardgame[line][column] == '_')
count++;
if (count == 10)
return true;
else
return false;
}
public void openNeighbors() {
for (int i = -1; i < 2; i++)
for (int j = -1; j < 2; j++)
if ((mines[Line + i][Column + j] != -1)
&& (Line != 0 && Line != 9 && Column != 0 && Column != 9))
boardgame[Line + i][Column + j] =
Character.forDigit(mines[Line + i][Column + j], 10);
}
public int getPosition(int Line, int Column) {
return mines[Line][Column];
}
public boolean setPosition() {
do {
System.out.print("\nLine: ");
Line = input.nextInt();
System.out.print("Column: ");
Column = input.nextInt();
if ((boardgame[Line][Column] != '_')
&& ((Line < 9 && Line > 0) && (Column < 9 && Column > 0)))
System.out.println("Field already shown");
if (Line < 1 || Line > 8 || Column < 1 || Column > 8)
System.out.println("Choose a number between 1 and 8");
} while ((Line < 1 || Line > 8 || Column < 1 || Column > 8)
|| (boardgame[Line][Column] != '_'));
if (getPosition(Line, Column) == -1)
return true;
else
return false;
}
public void show() {
System.out.println("\n Lines");
for (int Line = 8; Line > 0; Line--) {
System.out.print(" " + Line + " ");
for (int Column = 1; Column < 9; Column++) {
System.out.print(" " + boardgame[Line][Column]);
}
System.out.println();
}
System.out.println("\n 1 2 3 4 5 6 7 8");
System.out.println(" Columns");
}
public void fillTips() {
for (int line = 1; line < 9; line++)
for (int column = 1; column < 9; column++) {
for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
if (mines[line][column] != -1)
if (mines[line + i][column + j] == -1)
mines[line][column]++;
}
}
public void showMines() {
for (int i = 1; i < 9; i++)
for (int j = 1; j < 9; j++)
if (mines[i][j] == -1)
boardgame[i][j] = '*';
show();
}
public void startBoard() {
for (int i = 1; i < mines.length; i++)
for (int j = 1; j < mines.length; j++)
boardgame[i][j] = '_';
}
public void startMines() {
for (int i = 0; i < mines.length; i++)
for (int j = 0; j < mines.length; j++)
mines[i][j] = 0;
}
public void randomMines() {
boolean raffled;
int Line, Column;
for (int i = 0; i < 10; i++) {
do {
Line = random.nextInt(8) + 1;
Column = random.nextInt(8) + 1;
if (mines[Line][Column] == -1)
raffled = true;
else
raffled = false;
} while (raffled);
mines[Line][Column] = -1;
}
}
}
public class MineSweeper extends Board {
public static void main(String[] args) {
Game game = new Game();
}
}
So I've been using this great resource class i found online to Sort two cursors based on an column:
https://android.googlesource.com/platform/frameworks/base.git/+/android-4.4.4_r1/core/java/com/android/internal/database/SortCursor.java
The onMove function of this Cursor seems to be doing the sorting between the two cursors:
#Override
public boolean onMove(int oldPosition, int newPosition)
{
if (oldPosition == newPosition)
return true;
/*
* Find the right cursor
* Because the client of this cursor (the listadapter/view) tends
* to jump around in the cursor somewhat, a simple cache strategy
* is used to avoid having to search all cursors from the start.
* TODO: investigate strategies for optimizing random access and
* reverse-order access.
*/
int cache_entry = newPosition % ROWCACHESIZE;
if (mRowNumCache[cache_entry] == newPosition) {
int which = mCursorCache[cache_entry];
mCursor = mCursors[which];
if (mCursor == null) {
Log.w(TAG, "onMove: cache results in a null cursor.");
return false;
}
mCursor.moveToPosition(mCurRowNumCache[cache_entry][which]);
mLastCacheHit = cache_entry;
return true;
}
mCursor = null;
int length = mCursors.length;
if (mLastCacheHit >= 0) {
for (int i = 0; i < length; i++) {
if (mCursors[i] == null)
continue;
mCursors[i].moveToPosition(mCurRowNumCache[mLastCacheHit][i]);
}
}
if (newPosition < oldPosition || oldPosition == -1) {
for (int i = 0; i < length; i++) {
if (mCursors[i] == null)
continue;
mCursors[i].moveToFirst();
}
oldPosition = 0;
}
if (oldPosition < 0) {
oldPosition = 0;
}
// search forward to the new position
int smallestIdx = -1;
for (int i = oldPosition; i <= newPosition; i++) {
String smallest = "";
smallestIdx = -1;
for (int j = 0; j < length; j++) {
if (mCursors[j] == null || mCursors[j].isAfterLast()) {
continue;
}
String current = mCursors[j].getString(mSortColumns[j]);
if (smallestIdx < 0 || current.compareToIgnoreCase(smallest) < 0) {
smallest = current;
smallestIdx = j;
}
}
if (i == newPosition)
break;
if (mCursors[smallestIdx] != null) {
mCursors[smallestIdx].moveToNext();
}
}
mCursor = mCursors[smallestIdx];
mRowNumCache[cache_entry] = newPosition;
mCursorCache[cache_entry] = smallestIdx;
for (int i = 0; i < length; i++) {
if (mCursors[i] != null) {
mCurRowNumCache[cache_entry][i] = mCursors[i].getPosition();
}
}
mLastCacheHit = -1;
return true;
}
I'm not familiar with how cursors work but I was wondering how I would modify the onMove function such that the sorting of the two cursors would be sorted in desceding order rather than the default ascending order?
Any ideas would help! Thanks!