In dieser Applikation ist das Pearl-Game gegen computer programmiert.
|
Programmcode downloaden: PearlGameVsComputer.zip
Programmcode:
// PearlGameVsComputer.java import ch.aplu.jgamegrid.*; import java.awt.*; import java.util.*; import java.util.List; public class PearlGameVsComputer extends GameGrid implements GGMouseListener, GGButtonListener { private int nbPearl = 0; private int nbTakenPearl; private int nbRows = 4; private int activeRow; private GGBackground bg; private GGButton okBtn = new GGButton("sprites/ok.gif", true); private GGButton newBtn = new GGButton("sprites/new.gif", true); private ComputerPlayer cp; private final boolean misereMode = true; public PearlGameVsComputer() { super(8, 6, 60, false); setBgColor(new Color(80, 15, 247)); bg = getBg(); addMouseListener(this, GGMouse.lPress); addActor(okBtn, new Location(6, 4)); okBtn.addButtonListener(this); addActor(newBtn, new Location(6, 4)); newBtn.addButtonListener(this); cp = new ComputerPlayer(this, misereMode); init(); show(); } public void init() { int nb = 6; cp.reset(); bg.clear(); for (int k = 0; k < nbRows; k++) { for (int i = 0; i < nb; i++) { Pearl pearl = new Pearl(); addActor(pearl, new Location(1 + i, 1 + k)); cp.updatePearlArrangement(k + 1, +1); nbPearl++; } nb--; } prepareNextHumanMove(); // human starts okBtn.show(); newBtn.hide(); refresh(); setTitle(nbPearl + " Pearls. Remove any number of pearls from same row and press OK."); } public boolean mouseEvent(GGMouse mouse) { Location loc = toLocationInGrid(mouse.getX(), mouse.getY()); Actor pearlAtClick = getOneActorAt(new Location(loc), Pearl.class); if (pearlAtClick != null) { int y = pearlAtClick.getY(); if (activeRow != 0 && activeRow != y) setTitle("You must remove pearls from the same row."); else { activeRow = y; pearlAtClick.removeSelf(); nbPearl--; setTitle(nbPearl + " Pearls remaining. Click 'OK' to continue."); nbTakenPearl++; cp.updatePearlArrangement(y, -1); if (nbPearl == 0) { if (misereMode) gameOver("You lost!"); else gameOver("You won!"); } refresh(); } } return true; } public void gameOver(String msg) { setTitle("Press 'new Game' to play again."); bg.setPaintColor(Color.red); bg.setFont(new Font("Arial", Font.BOLD, 32)); bg.drawText(msg, new Point(toPoint(new Location(2, 5)))); okBtn.hide(); newBtn.show(); refresh(); } public void buttonClicked(GGButton button) { if (nbPearl == 0) init(); else { if (nbTakenPearl == 0) setTitle("You have to remove at least 1 Pearl!"); else { cp.makeMove(); refresh(); nbPearl = getNumberOfActors(Pearl.class); if (nbPearl == 0) { if (misereMode) gameOver("You win!"); else gameOver("You lose!"); } else prepareNextHumanMove(); } } } private void prepareNextHumanMove() { nbTakenPearl = 0; setTitle(nbPearl + " pearls remaining. Your move now."); activeRow = 0; // Spieler darf neue "Ziehreihe" bestimmen } public void buttonPressed(GGButton button) { } public void buttonReleased(GGButton button) { } public void reset() { } public static void main(String[] args) { new PearlGameVsComputer(); } } // class Pearl extends Actor { public Pearl() { super("sprites/pearl.gif"); } } // class ComputerPlayer { protected int[] pearlArrangement; private final int dualMax = 4; private int vertCells; protected GameGrid gg; protected boolean misere; private boolean changeStrat; public ComputerPlayer(GameGrid pearlGG, boolean misere) { this.gg = pearlGG; this.vertCells = gg.getNbVertCells(); this.misere = misere; } public void updatePearlArrangement(int row, int amount) { pearlArrangement[row] += amount; } public void makeMove() { int nbToRemoveMatches = 0; int[] tgPearls = new int[vertCells]; int removeRow = shouldIChangeStrat(); if (removeRow != -1) { System.arraycopy(pearlArrangement, 0, tgPearls, 0, vertCells); tgPearls[removeRow] = 0; if (isUSituation(tgPearls)) nbToRemoveMatches = pearlArrangement[removeRow]; else nbToRemoveMatches = pearlArrangement[removeRow] - 1; } // if optimal Strategy is not possible, do something random. else if (!isUSituation(pearlArrangement)) { ArrayList<Actor> pearls = gg.getActors(Pearl.class); System.out.println("Doing something random"); // from a random (not empty!) row Collections.shuffle(pearls); removeRow = pearls.get(0).getY(); // take a random amount (at least 1) nbToRemoveMatches = (int)((pearlArrangement[removeRow] - 1) * Math.random() + 1); } else { // list for saving all possible solutions List<int[]> solutions = new ArrayList<int[]>(); // Try all possible situations and add them to "solutions if they're // good. for (int y = 0; y < vertCells; y++) { System.arraycopy(pearlArrangement, 0, tgPearls, 0, vertCells); for (int i = 0; i < pearlArrangement[y]; i++) { tgPearls = makeSituation(tgPearls, y); if (isUSituation(tgPearls) == false) { solutions.add((new int[] { y, i + 1 })); } } } // choose a random solution Collections.shuffle(solutions); removeRow = solutions.get(0)[0]; nbToRemoveMatches = solutions.get(0)[1]; System.out.println("Number of solutions: " + solutions.size()); } removePearls(removeRow, nbToRemoveMatches); } private int shouldIChangeStrat() { if (changeStrat || !misere) return -1; boolean oneHeapBiggerTwo = false; int bigHeap = -1; for (int heap = 0; heap < vertCells; heap++) { if (pearlArrangement[heap] > 1) { bigHeap = heap; if (oneHeapBiggerTwo) return -1; oneHeapBiggerTwo = true; } } System.out.println("changing strategy for misere!"); changeStrat = true; return bigHeap; } private void miserify(int[] sit) { if (!misere) return; else { for (int heap : sit) { if (heap > 1) return; } changeStrat = true; } } private void removePearls(int removeRow, int nbToRemoveMatches) { updatePearlArrangement(removeRow, -nbToRemoveMatches); List<Actor> removeCandidates = new ArrayList<Actor>(); for (Actor p : gg.getActors(Pearl.class)) { if (p.getY() == removeRow) removeCandidates.add(p); } Collections.shuffle(removeCandidates); while (nbToRemoveMatches > 0) { Actor removedPearl = removeCandidates.remove(0); removedPearl.removeSelf(); nbToRemoveMatches--; } } // for debugging only private String toString(int[] k) { String output = ""; for (int i = 0; i < k.length; i++) output = (output + k[i] + ", "); return output; } /* private int[] makeSituation(int[] sit, int row) { sit[row] = sit[row] - 1; return sit; } // Check if its a U-Situation private Boolean isUSituation(int[] sit) { int[] allDuals = new int[dualMax]; int[] oneDual = new int[dualMax]; for (int y = 0; y < vertCells; y++) { oneDual = toDual(sit[y]); for (int i = 0; i < allDuals.length; i++) { allDuals[i] = allDuals[i] + oneDual[i]; } } for (int i = 0; i < allDuals.length; i++) { if (allDuals[i] % 2 == 1) return true; } return false; } /** private int[] toDual(int input) { int[] output = new int[dualMax]; // 4 dualstellen int x = 0; while (input != 0) { output[x] = input % 2; input = input / 2; x++; } return output; } public void reset() { pearlArrangement = new int[vertCells]; changeStrat = false; } } |