Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Bauernkrieg Game


Bauernkrieg ist ein sehr einfaches Kartenspiel für zwei oder mehrere Spieler. In unserem Beispiel ist das Spiel für zwei Spieler implementiert. Zu Beginn des Spieles werden alle Karten verteilt und verdeckt bei jedem Spieler auf einen Stapel aufgelegt. Dann spielen die beiden Spieler die oberste Karte und die beiden vergleichen die Ränge. Wer den höhere Rang hat, nimmt beide Karten zu sich. Gewinner ist, wer mehr Karten erspielt hat. Haben die zwei Karten denselben Rang, so spielt jeder Spieler die nächste Karte verdeckt. Dann spielen sie eine nächste Karte auf. Wer jetzt den höheren Rang hat, nimmt danach alle sechs Karten. Besteht wieder Kartengleichheit, so wird das Verfahren wiederholt. Das Spiel dauert solange, bis die beiden Stapel aufgebraucht sind (Besteht zu dieser Zeit Kartengleichheit, bleiben die Karten in der Mitte liegen).

Programmcode downloaden (BauernKrieg.zip)

 

Programmcode:

// BauernKrieg.java

import ch.aplu.jcardgame.*;
import ch.aplu.jgamegrid.*;
import ch.aplu.util.Monitor;
import java.awt.*;

public class BauernKrieg extends CardGame
{
  public enum Suit
  {
    KREUZ, HERZ, KARO, PIK
  }

  public enum Rank
  {
    ASS, KOENIG, DAME, BAUER, ZEHN, NEUN, ACHT, SIEBEN, SECHS
  }
  private final Deck deck = new Deck(Suit.values(), Rank.values(), "cover");
  private final int nbPlayers = 2;
  private final int nbCards = 18;
  private final Location[] handLocations =
  {
    new Location(210, 440),
    new Location(390, 440),
  };
  private final Location[] bidLocations =
  {
    new Location(210, 200),
    new Location(390, 200),
  };
  private final Location[] stockLocations =
  {
    new Location(90, 400),
    new Location(510, 400),
  };
  private Hand[] hands;
  private Hand[] bids = new Hand[nbPlayers];
  private Hand[] stocks = new Hand[nbPlayers];
  private int currentPlayer = 0;
  private int nbMovesInRound = 0;
  private int targetCount = 0;

  public BauernKrieg()
  {
    super(600, 600, 30);
    initHands();
    setStatusText("Doubleclick to play card"
      + ". Starting player: " + currentPlayer);
    TextActor player0 = new TextActor("player 0 "Color.white,
      getBgColor(), new Font("Arial"Font.BOLD, 16));
    addActor(player0, new Location(182, 530));
    TextActor player1 = new TextActor("player 1 "Color.white,
      getBgColor(), new Font("Arial"Font.BOLD, 16));
    addActor(player1, new Location(360, 530));
    initBids();
    initStocks();
    hands[0].setTouchEnabled(true);
  }

  private void initHands()
  {
    hands = deck.dealingOut(nbPlayers, nbCards);
    for (int = 0; i < nbPlayers; i++)
    {
      hands[i].setView(thisnew StackLayout(handLocations[i]));
      hands[i].setVerso(true);
      hands[i].draw();
    }
  }

  private void initBids()
  {
    for (int = 0; i < nbPlayers; i++)
    {
      bids[i] = new Hand(deck);
      bids[i].setView(thisnew RowLayout(bidLocations[i], 130));
      bids[i].addCardListener(new CardAdapter()
      {
        public void atTarget(Card card, Location loc)
        {
          targetCount++;
          if (targetCount == nbPlayers)
            Monitor.wakeUp();  // All cards in stock->continue
        }
      });

      hands[i].setTargetArea(new TargetArea(bidLocations[i]));
      final int = i;
      hands[i].addCardListener(new CardAdapter()
      {
        public void leftDoubleClicked(Card card)
        {
          card.setVerso(false);
          card.transfer(bids[k], true);
          hands[currentPlayer].setTouchEnabled(false);
          currentPlayer = (currentPlayer + 1) % nbPlayers;
          if (nbMovesInRound % == 1) //only works for two players
          {
            if (isSameRank())
            {
              if (hands[currentPlayer].isEmpty())
              {
                gameOver();
                return;
              }

              for (int = 0; i < nbPlayers; i++)
              {
                Card = hands[i].getLast();
                c.transfer(bids[i], true);
              }
              nbMovesInRound++;
            }
            else
            {
              setStatusText("Evaluating round...");
              nbMovesInRound = 0;
              currentPlayer = transferToWinner();
            }
          }
          else
            nbMovesInRound++;

          if (!hands[currentPlayer].isEmpty())
          {
            setStatusText("Current player: " + currentPlayer);
            hands[currentPlayer].setTouchEnabled(true);
          }
          else
            gameOver();
        }

        private boolean isSameRank()
        {
          if (bids[0].getLast() == null || bids[1].getLast() == null)
            return false;
          return bids[0].getLast().getRank() == bids[1].getLast().getRank();
        }
      });
    }
  }

  private void gameOver()
  {
    int nbCard0 = stocks[0].getNumberOfCards();
    int nbCard1 = stocks[1].getNumberOfCards();
    TextActor winnerLabel = new TextActor("Winner!"Color.yellow,
      getBgColor(), new Font("Arial"Font.BOLD, 16));
    winnerLabel.setLocationOffset(new Point(-30, 90));
    if (nbCard0 > nbCard1)
    {
      setStatusText("Game over. Winner: player 0 ("
        + nbCard0 + " cards), player 1 (" + nbCard1 + " cards)");
      addActor(winnerLabel, stockLocations[0]);
    }
    else if (nbCard0 < nbCard1)
    {
      setStatusText("Game over. Winner: player 1 ("
        + nbCard1 + " cards), player 0 (" + nbCard0 + " cards)");
      addActor(winnerLabel, stockLocations[1]);
    }
    else
      setStatusText("Game over. Tie: player 1 ("
        + nbCard1 + " cards), player 0 (" + nbCard0 + " cards)");
  }

  private void initStocks()
  {
    for (int = 0; i < nbPlayers; i++)
    {
      stocks[i] = new Hand(deck);
      stocks[i].setView(thisnew StackLayout(stockLocations[i]));
    }
  }

  private int transferToWinner()
  {
    delay(1000);
    Hand eval = new Hand(deck);
    for (int = 0; i < nbPlayers; i++)
      eval.insert(bids[i].getLast(), false);
    int nbWinner = eval.getMaxPosition(Hand.SortType.RANKPRIORITY);
    transferToStock(nbWinner);
    return nbWinner;
  }

  private void transferToStock(int player)
  {
    targetCount = 0;
    for (int = 0; i < nbPlayers; i++)
    {
      bids[i].setTargetArea(new TargetArea(stockLocations[player]));
      while (true)
      { //moves now multiple cards!
        Card = bids[i].getLast();
        if (c == null)
          break;
        c.setVerso(true);
        bids[i].transferNonBlocking(c, stocks[player]);
      }
    }
    Monitor.putSleep();  // Wait until all cards are transferred to stock
    stocks[player].draw();
  }

  public static void main(String[] args)
  {
    new BauernKrieg();
  }
}

Erklärungen zum Programmcode:
boolean isSameRank() Die Methode isSameRank() gibt true zurück, wenn die beiden ausgespielten Karten den gleichen Rang haben
int transferToWinner()
Diese Methode gibt 0 oder 1 zurück, je nach dem, ob der Spieler 0 oder 1 die höhere Karte hat
nbCard0 = stocks[0].getNumberOfCards();
nbCard1 = stocks[1].getNumberOfCards();
Die Zahl der gewonnen Karten in beiden Stocks
transferToStock(int player) Die Karten werden verdeckt vom den bids zum Stack des Gewinners verschoben
bids[i].transferNonBlocking(c, stocks[player]) Es werden mehrere Karten miteinander verschoben, deswegen muss transferNonBlocking gewählt werden
if (hands[currentPlayer].isEmpty()) Wenn alle Karten ausgespielt sind