Spielprogrammierung mit Java
HomeAufgabenDruckenJava-Online

Solitär Brettspiel


Solitär (auch Jumper) ist ein Brettspiel für eine Person. Das Spiel wird mit 32 Spielsteinen, die kreuzförmig in 33 Feldern angeordnet sind, gestartet. Ziel ist es alle Steine bis auf einen zu eliminieren, in dem man sie mit einem Nachbarstein überspringt. Die Spielsteine werden mit der gedrückten Maustaste an die neue Position gezogen, wobei man nur senkrecht oder waagrecht aber nicht diagonal springen darf.

erlaubt nicht erlaubt


Programmcode für lokale Bearbeitung Downloaden: BoardSolitaire.zip

 

Programmcode:

// BoardSolitaire.java

import ch.aplu.jgamegrid.*;
import java.awt.Point;
import java.util.*;

public class BoardSolitaire extends GameGrid implements GGMouseTouchListener
{
  final int DOWN = 0;
  final int UP = 1;
  Actor draggedMarble;
  private ArrayList<Location> boardPatternLocations = new ArrayList<Location>();
  private Location initialMarbleLocation;

  public BoardSolitaire()
  {
    super(7, 7, 70, null"sprites/solitaire.png"false);
    setBgColor(255, 166, 0);
    setTitle("Solitaire");
    loadMarbleLocations();
    loadMarbles();
    show();
    setSimulationPeriod(20);
    doRun();
  }

  public void act()
  {
    refresh();
  }

  public void mouseTouched(Actor touchedMarble, GGMouse mouse, Point spot)
  {
    Location mouseLoc = toLocation(mouse.getX(), mouse.getY());
    Point mousePoint = new Point(mouse.getX(), mouse.getY());
    switch (mouse.getEvent())
    {
      case GGMouse.lPress:
        //define draggedMarble:
        if (draggedMarble == null)
        {
          draggedMarble = touchedMarble;
          initialMarbleLocation = touchedMarble.getLocation();
          draggedMarble.show(UP);
          draggedMarble.setOnTop();
        }
        else
        {
          draggedMarble.show(DOWN);
          draggedMarble.setLocationOffset(new Point(0, 0));
          draggedMarble.setLocation(initialMarbleLocation);
          draggedMarble = null;
        }
        break;
      case GGMouse.lDrag:
        if (draggedMarble != null)
          draggedMarble.setPixelLocation(mousePoint);
        break;

      case GGMouse.lRelease:
        if (draggedMarble != null)
        {
          draggedMarble.setLocationOffset(new Point(0, 0));
          if (isValidJumpLocation(mouseLoc, initialMarbleLocation, true)
            && jumpedMarbleExists(mouseLoc, initialMarbleLocation))
          {
            draggedMarble.setLocation(mouseLoc);
            Actor jumpedMarble = getJumpedMarble(mouseLoc, initialMarbleLocation);
            removeActor(jumpedMarble);
          }
          else
          {
            draggedMarble.setLocation(initialMarbleLocation);
          }
          draggedMarble.show(DOWN);
          draggedMarble = null;
          isGameOver();
        }
        break;
    }
  }

  private boolean jumpedMarbleExists(Location loc, Location initialLoc)
  {
    return getJumpedMarble(loc, initialLoc) != null;
  }

  private Actor getJumpedMarble(Location loc, Location initialLoc)
  {
    Double jumpDirection = loc.getDirectionTo(initialLoc);
    Location overJumpedLoc = loc.getNeighbourLocation(jumpDirection);
    return getOneActorAt(overJumpedLoc, Marble.class);
  }

  private void loadMarbleLocations()
  {
    for (int y = 0; y < 7; y++)
    {
      if (y < || y > 4)
      {
        for (int x = 2; x < 5; x++)
          boardPatternLocations.add(new Location(x, y));
      }
      else
      {
        for (int x = 0; x < 7; x++)
          boardPatternLocations.add(new Location(x, y));
      }
    }
  }

  // Initializes marbles on the board
  private void loadMarbles()
  {
    for (Location loc : boardPatternLocations)
    {
      Marble marble = new Marble(DOWN);
      marble.addMouseTouchListener(this, GGMouse.lPress | GGMouse.lDrag | GGMouse.lRelease);
      addActorNoRefresh(marble, loc);
    }
    this.removeActorsAt(new Location(3, 3)); //make hole in middle
  }

  // check if location is a valid jump location
  private boolean isValidJumpLocation(Location loc, Location previousLoc, boolean isDragged)
  {
    int expectedMarbleNr;
    if (isDragged)
      expectedMarbleNr = 1;
    else
      expectedMarbleNr = 0;
    ArrayList<Location> validJumpLocs = new ArrayList<Location>();
    for (int possibleDir = 0; possibleDir < 360; possibleDir += 90)
      validJumpLocs.add(previousLoc.getAdjacentLocation(possibleDir, 2));
    return (boardPatternLocations.contains(loc) && validJumpLocs.contains(loc)
      && getActorsAt(loc, Marble.class).size() == expectedMarbleNr);
  }

  private void isGameOver()
  {
    ArrayList<Actor> leftMarbles = getActors(Marble.class);
    // One left => you win
    if (leftMarbles.size() == 1)
    {
      addActor(new Actor("sprites/you_win.gif")new Location(3, 3));
      restart();
    }
    else
    {
      //check if there are any valid moves left
      for (Actor a : leftMarbles)
      {
        if (hasOrthagonalJumpableNeighbours(a))
          return;
      }
      //no more valid jumps possible => you lose!
      addActor(new Actor("sprites/gameover.gif")new Location(3, 3));
      restart();
    }
  }

  private boolean hasOrthagonalJumpableNeighbours(Actor a)
  {
    Location marbleLoc = a.getLocation();
    for (Location loc : marbleLoc.getNeighbourLocations(0.5))
    {
      double locDir = marbleLoc.getDirectionTo(loc);
      Location jumpLoc = loc.getNeighbourLocation(locDir);
      if (getActorsAt(loc, Marble.class).size() != 0
        && isValidJumpLocation(jumpLoc, marbleLoc, false))
        return true;
    }
    return false;
  }

  // restart game
  private void restart()
  {
    delay(5000);
    removeAllActors();
    loadMarbles();
  }

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

// -----------           class Marble    ------------------------
class Marble extends Actor
{

  public Marble(int imgID)
  {
    super("sprites/marble.png"2);
    show(imgID);
  }
}



Solitär Brettspiel: einfachere Variante

In dieser Lösung werden die Spielsteine mit einem Mausklick auf den zu bewegenden Spielstein und einem nachfolgendem Mausklick an die Zielposition verschoben. Der Programmcode dieser Lösung ist einfacher.

Programmcode für lokale Bearbeitung Downloaden: BoardSolitaire2.zip