/** * Copyright 2007 Troy Korjuslommi. * All rights reserved. */ import java.util.Vector; import java.util.List; import java.util.Set; import java.util.TreeSet; public class Witch { private Tower mTower; private List mMaidens; private Set mUniqueVisits; private int mVisitCount; public Witch() { mTower = new Tower(); mVisitCount = 0; mUniqueVisits = new TreeSet(); mMaidens = new Vector(); mMaidens.add(new FirstMaiden(this)); for (int i = 1; i < 23; i++) mMaidens.add(new OtherMaiden(i+1)); } public static void main(String argv[]) { Witch witch = new Witch(); witch.playmaidens(); } void playmaidens() { while (true) { takeToTower(getRandomMaiden()); } } void takeToTower(Maiden maiden) { maiden.visit(mTower); mUniqueVisits.add(maiden.getID()); mVisitCount++; } Maiden getRandomMaiden() { // Note: Match.random() is >= 0.0 and < 1.0. int num = (int)Math.floor((Math.random() * (double)23)); return mMaidens.get(num); } void makeClaim() { if (mUniqueVisits.size() == 23) releasePrisoners(); else throwAwayTheKey(); } void releasePrisoners() { System.err.println("All prisoners are freed. A total of " + mVisitCount + " trips were made to the tower."); System.exit(0); } void throwAwayTheKey() { System.err.println("Ooops, lost the key. Game over. Only " + mUniqueVisits.size() + " maidens have visited the tower."); System.exit(0); } } class Tower { private boolean mLeftLeverUp; private boolean mRightLeverUp; Tower() { mLeftLeverUp = (Math.round(Math.random()) == 1); mRightLeverUp = (Math.round(Math.random()) == 0); } boolean rightLeverUp() { return mRightLeverUp; } boolean leftLeverUp() { return mLeftLeverUp; } void shiftLeft() { mLeftLeverUp = ! mLeftLeverUp; } void shiftRight() { mRightLeverUp = ! mRightLeverUp; } } interface Maiden { void visit(Tower tower); int getID(); } class FirstMaiden implements Maiden { private boolean mLeftWasUp; private boolean mRightMovedUp; private boolean mVisitedTower; private int mVisitors; private Witch mWitch; FirstMaiden(Witch w) { mWitch = w; mVisitedTower = false; mVisitors = 0; } public int getID() { return 1; } public void visit(Tower tower) { if (! mVisitedTower || mLeftWasUp == tower.leftLeverUp()) { // We shift right lever down if (a) we never visited the tower, // and (b) we ourselves were the one to shift the right lever up. // Case (b) needs to be handled so the other maidens will have a chance to // see the right lever down. if (tower.rightLeverUp()) tower.shiftRight(); else tower.shiftLeft(); } else { // If right up, nobody's been to the tower for the first time. // This is so since we are the only ones moving the right lever up. if (! tower.rightLeverUp()) { // There's only been a visitor if we moved the lever up last time. // We could have been the one to move it down. if (mRightMovedUp && ++mVisitors == 22) mWitch.makeClaim(); mRightMovedUp = true; } tower.shiftRight(); } mLeftWasUp = tower.leftLeverUp(); mVisitedTower = true; } } class OtherMaiden implements Maiden { private int mID; private boolean mSeenRightLeverDown; private boolean mShiftedRightLeverDown; OtherMaiden(int num) { mID = num; mSeenRightLeverDown = false; mShiftedRightLeverDown = false; } public int getID() { return mID; } public void visit(Tower tower) { if (! mShiftedRightLeverDown && mSeenRightLeverDown && tower.rightLeverUp()) { tower.shiftRight(); mShiftedRightLeverDown = true; } else { if (! tower.rightLeverUp()) mSeenRightLeverDown = true; tower.shiftLeft(); } } }