Search code examples
javarecursioninfinite

Why does this message print extra times (more than I want it to print)?


import java.util.ArrayList;
import java.lang.Math;

public class War {
    ArrayList deck = new ArrayList(0);
    ArrayList player1 = new ArrayList(0);
    ArrayList player2 = new ArrayList(0);
    int sum1 = 0;
    int sum2 = 0;
    int count = 0;

private void setup ()
{
    for (int x = 1; x <= 13; x++)
    {
        for (int y = 1; y <= 4; y++)
        {
            deck.add(x);
        }
    }

    while (deck.size() > 26)
    {
        double x = Math.random() * deck.size();
        int y = (int) x;

        player1.add(deck.remove(y));
    }

    while (deck.size() > 0)
    {
        double x = Math.random() * deck.size();
        int y = (int) x;

        player2.add(deck.remove(y));
    }

    for (int x = 0; x < 26; x++)
    {
        sum1 += (int) player1.get(x);
        sum2 += (int) player2.get(x);
    }

    System.out.println("Player 1's starting power is " + sum1 + ".");
    System.out.println();
    System.out.println("Player 2's starting power is " + sum2 + ".");
    System.out.println();

    if (sum1 == sum2)
    {
        System.out.println("The two player's starting powers are equal! This'll be a good one, folks!");
    }
}

public void play ()
{
    if (hasSomeoneWon() || count == 0)
    {
        setup();
    }

    while (!player1.isEmpty() && !player2.isEmpty())
    {
        int a = (int) player1.get(0);
        int b = (int) player2.get(0);

        if (a > b)
        {
            player1.add(player1.remove(0)); // The winner's card is re-added to his deck before
            player1.add(player2.remove(0)); // the loser's is added to the winner's deck.
        }

        if (a < b)
        {
            player2.add(player2.remove(0));
            player2.add(player1.remove(0));
        }

        if (a == b)
        {
            war();
        }
    }

    victory();
}

private void war ()
{
    ArrayList temp1 = new ArrayList(0);
    ArrayList temp2 = new ArrayList(0);
    temp1.add(player1.remove(0));
    temp2.add(player2.remove(0));
    int x = 0;

    while (!(player1.isEmpty() || player2.isEmpty()) && x < 3)
    {
        temp1.add(player1.remove(0));
        temp2.add(player2.remove(0));
        x++;
    }

    int a = (int) temp1.get(temp1.size() - 1);
    int b = (int) temp2.get(temp2.size() - 1);

    if (a == b)
    {
        if (temp1.size() != temp2.size())
        {
            if (temp1.size() > temp2.size())
            {
                while (!temp1.isEmpty())
                {
                    player1.add(temp1.remove(0));
                }

                while (!temp2.isEmpty())
                {
                    player1.add(temp2.remove(0));
                }
            }

            else
            {
                while (!temp2.isEmpty())
                {
                    player2.add(temp2.remove(0));
                }

                while (!temp1.isEmpty())
                {
                    player2.add(temp1.remove(0));
                }
            }
        }

        else
        {
            if (player1.isEmpty() || player2.isEmpty())
            {
                if (player1.isEmpty())
                {
                    while (!temp2.isEmpty())
                    {
                        player2.add(temp2.remove(0));
                    }

                    while (!temp1.isEmpty())
                    {
                        player2.add(temp1.remove(0));
                    }
                }

                else
                {
                    while (!temp1.isEmpty())
                    {
                        player1.add(temp1.remove(0));
                    }

                    while (!temp2.isEmpty())
                    {
                        player1.add(temp2.remove(0));
                    }
                }
            }

            else
            {
                war();
            }
        }
    }

    else
    {
        if (a > b)
        {
            while (!temp1.isEmpty())
            {
                player1.add(temp1.remove(0));
            }

            while (!temp2.isEmpty())
            {
                player1.add(temp2.remove(0));
            }
        }

        else
        {
            while (!temp2.isEmpty())
            {
                player2.add(temp2.remove(0));
            }

            while (!temp1.isEmpty())
            {
                player2.add(temp1.remove(0));
            }
        }

        play();
    }
}

private void victory ()
{
    if (player1.isEmpty() && sum2 > sum1)
    {
        System.out.println("Player 2 has won!");
    }

    if (player1.isEmpty() && sum1 > sum2)
    {
        System.out.println("Upset! Player 2 has won!");
    }

    if (player2.isEmpty() && sum1 > sum2)
    {
        System.out.println("Player 1 has won!");
    }

    if (player2.isEmpty() && sum2 > sum1)
    {
        System.out.println("Upset! Player 1 has won!");
    }

    hasSomeoneWon();
}

private boolean hasSomeoneWon ()
{
    if (player1.isEmpty() || player2.isEmpty())
    {
        count++;
        return true;
    }

    return false;
}

}

Sorry for including all of my code, but I don't know which part is causing the extra printing.

This is the card game War. It's supposed to play out the game between two players on its own and then print the winner. Whenever I've played it, though, the victory message (whichever one gets printed) is printed a variable number of times. I'm guessing this has something to do with either where and how often I've included my calls to some of the methods OR the recursive call to war within the war() method.

My only experience with Java is an AP Computer Science class I took this school year, so I'm for sure a noob by the standards of everyone reading this.


Solution

  • In the war() method you are recursively calling war() and war() will eventually end by recalling play(). So there will be multiple instances executing play(). Eventually when the cards run out for one player all this instances will comeback as the stack is unwound and continue executing play(). And finally of course calling victory() and printing it multiple times (should be the amount of times war() was called).

    So each war() may print out a player has won once it reached the bottom of the recursion. I don't think the call to play() in war() is necessary, it will go back to the play() method after it finishes the war() method anyway.