Chelle
Chelle

Reputation: 23

Can someone help me with my win scenario in my Gomoku program?

I have written a program for an assignment where we had to write a simple Gomoku program. I thought I had it all, but when I compile and run, it sets off the win scenario even if I only have 4 of a kind and even if they're not next to each other. (It should only set off a win if there are five in a row of one kind...X's or O's). I feel like I should be resetting my counter back to 0 before each turn, but I'm not sure where I should be doing that. Any tips would be appreciated!

import java.util.Scanner;

public class Gomoku1
{
    public static void main (String[] args)
    {
        Scanner input = new Scanner(System.in);

        char[][] map = new char [19][19];

        int row = 0;
        int column = 0;

        //fill game with dots
        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map[i].length; j++)
            {
                map[i][j] = '.';
            }
        }

        printMap(map);

        char player1Choice = 'X';
        char player2Choice = 'O';

        int [] place;
        while (true)
        {

            System.out.println("Player 1's turn!");
            place = userTurn(map, player1Choice);

            if (isValidMove(map, place[0], place[1]) == false)
            {
                System.out.println("Invalid move! Try again!");
                place = userTurn(map, player1Choice);
            }
            if (isValidMove(map, place[0], place[1])) {
                map[place[0]][place[1]] = player1Choice;
                printMap(map);
            }
            if (isBoardFull(map) == true)
            {
                System.out.println("Board is full. Tied game.");
                break;
            }

            if (hasPlayerWon(map, player1Choice) == true)
            {
                System.out.println("Player 1 Wins!");
                break;
            }

            else
            {

                System.out.println("Player 2's turn!: ");
                place = userTurn(map, player2Choice);

                //System.out.println(isValidMove(map, row, column));

                if (isValidMove(map, place[0], place[1]) == false)
                {
                    System.out.println("Invalid move! Try again!");
                    place = userTurn(map, player2Choice);
                }
                if (isValidMove(map, place[0], place[1])) {
                    map[place[0]][place[1]] = player2Choice;
                    printMap(map);
                }
                if (isBoardFull(map) == true)
                {
                    System.out.println("Board is full. Tied game.");
                    break;
                }
                if (hasPlayerWon(map, player2Choice) == true)
                {
                    System.out.println("Player 2 Wins!");
                    break;
                }
            }


        }
    }

    public static void printMap (char[][] map)
    {
        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map[i].length; j++)
            {
                System.out.printf("%2c", map[i][j]);
            }
            System.out.println();
        }
    }

    public static int [] userTurn (char[][] map, char playerChoice)
    {
        Scanner input = new Scanner(System.in);

        System.out.print("Enter row: ");
        int row = input.nextInt();

        System.out.print("Enter column: ");
        int column = input.nextInt();

        int place [] = {row, column};
        return place;
    }

    public static boolean isValidMove (char[][] map, int row, int column)
    {
        //System.out.println ("n is valid move");
        if (row < 0 || row > 18 || column < 0 || column > 18 || map[row][column]=='O' || map[row][column]=='X')
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    public static boolean isBoardFull (char[][] map)
    {
        int openSpots = 0;
        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map.length; j++)
            {
                if (!(map[i][j]=='.'))
                    openSpots++;
            }
        }
        if (openSpots == 361)
        {
            return true;
        }
        return false;
    }

    public static boolean hasPlayerWon(char[][] map, int player)
    {
        if (isHorizontalWin(map, player) == true || isVerticalWin(map, player) == true || isDiagonalWin(map, player) == true)
        {
            return true;
        }
        return false;
    }

    public static boolean isHorizontalWin(char[][] map, int player)
    {
        int count = 0;

        int r;
        int c;



        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map.length; j++)
            {
                if (map[i][j]==(player))
                {
                    r = i;
                    c = j;
                    while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
                    {
                        count ++;
                        r += 0;
                        c += 1;
                    }
                }
            }
        }
        if (count == 5)
        {
            return true;

        }
        return false;


    }

    public static boolean isVerticalWin(char[][] map, int player)
    {
        int count = 0;

        int r;
        int c;

        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map.length; j++)
            {
                if (map[i][j]==(player))
                {
                    r = i;
                    c = j;
                    while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
                    {
                        count ++;
                        r += 1;
                        c += 0;
                    }
                }
            }
        }
        if (count == 5)
        {
            return true;

        }
        return false;

    }
    public static boolean isDiagonalWin(char[][] map, int player)
    {
        int count = 0;
        int r;
        int c;

        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map.length; j++)
            {
                if (map[i][j]==(player))
                {
                    r = i;
                    c = j;
                    while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
                    {
                        count++;
                        r += 1;
                        c += 1;
                    }
                }
            }
        }
        if (count == 5)
        {
            return true;

        }
        return false;


    }


}

Upvotes: 2

Views: 483

Answers (2)

Lummo
Lummo

Reputation: 99

I know that it's been a while... Here is my attempt at detecting five in a row in any direction but not as part of six or more. It's JavaScript but you could convert to Java pretty easily. It's a bit more compact and does it all in a single function with a couple of helper functions. It counts connected stones in both directions away from the x,y stone at the same time. board[][] is a simple 2D array with the Y value as the first index.

const isWinningTurn = (x, y) => {
  let tests = [ [1, 0], [0, 1], [-1, 1], [1, 1] ];
  for (let i = 0; i < tests.length; i++) {
    let dx = tests[i][0];
    let dy = tests[i][1];
    const first = numMatches(x, y, dx, dy);
    const second = numMatches(x, y, -dx, -dy);
    let runLength = first.n + second.n + 1;
    if (runLength == 5) {
      return {'from' : {x:first.x , y:first.y} , 'to' : {x:second.x, y:second.y}};
      }
    }
  return false;
  };

const numMatches = (x, y, dx, dy) => {
  let i = 1;
  while (inBounds(x + i*dx, y + i*dy) && board[y + i*dy][x + i*dx] === board[y][x]) {
    i++;
  }
  return {'n' : i - 1, 'x' : x + i*dx - dx, 'y' : y + i*dy - dy};
};

const inBounds = (x, y) => {
  return (y >= 0 && y < board.length) && (x >= 0 && x < board[y].length));
};

Upvotes: 0

Joey Kilpatrick
Joey Kilpatrick

Reputation: 1602

You have problems in all three of the function that check win conditions: isHorizontalWin, isVerticalWin, and isDiagonalWin. All three increment the variable count, but this variable is never set back to zero. Additionally, the check to see if count == 5 should be made inside the loop. Here is an example on how to fix isHorizontalWin:

    public static boolean isHorizontalWin(char[][] map, int player)
    {
        int count = 0;

        int r;
        int c;

        for (int i = 0; i < map.length; i++)
        {
            for (int j = 0; j < map.length; j++)
            {
                if (map[i][j]==(player))
                {
                    r = i;
                    c = j;
                    while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
                    {
                        count ++;
                        r += 0;
                        c += 1;
                    }
                    if (count == 5)
                    {
                        return true;
                    } else {
                        count = 0;
                    }
                }
            }
        }
        return false;
    }

Upvotes: 1

Related Questions