Skip to content

Instantly share code, notes, and snippets.

@IngwiePhoenix
Created November 13, 2018 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IngwiePhoenix/c9b4541e453d18f8f2609c199abed842 to your computer and use it in GitHub Desktop.
Save IngwiePhoenix/c9b4541e453d18f8f2609c199abed842 to your computer and use it in GitHub Desktop.
aufgabe04
/**
* @file
* Implementierung des chinesischen Spiels "Baguenaudier".
* @see Aufgabe 4.2
* @author Kevin Ingwersen
*/
/**
* @section Spielregeln
* Kurze zusammenfassung der Regeln (angelegt aus Eigeninteresse).
* 1. Der höchste Ring darf zu jeder Zeit entfernt oder aufgesetzt werden.
* 2. Ein Ring darf entfernt oder aufgesetzt werden, wenn sich auf den 2
* höheren Positionen die Ringe entfernt wurden und auf der nächst höheren
* Position ein Ring vorhanden ist.
* 3. Pro Zug darf nur ein Ring bewegt werden.
*
* Bedeutung der Bits:
* 0 = Aufgesetzt
* 1 = Entfernt
*/
final public class aufgabe04_2 {
/**
* Ermittle die Position des äußerst aufgesetztesten Ringes.
* @param stick Der Stab, an welchem operiert werden soll.
* @return Integer, der die Position des vorderesten Rings anzeigt.
*/
final public static int getLeadingRingPos(byte stick) {
int pos = 0;
// Verschiebe testBit so lange, bis die Höhe von stick überschritten
// werden würde.
for(byte testBit = 1; testBit <= stick; testBit = (byte)(testBit << 1)) {
if((testBit & stick) == 0) {
break;
} else {
pos++;
}
}
return pos;
}
final public static boolean isOnStick(byte stick, int pos) {
// @note Durch den Right-Shift um #pos steht das zu prüfende Bit
// am äußersten Rand und kann mit "AND 1" geprüft werden.
return ((stick >> pos) & 1) == 1;
}
final public static boolean canMove(byte stick, int pos) {
boolean result;
if(pos == 0) {
// Erster Ring darf immer entfernt oder aufgesetzt werden.
return true;
} else {
// Prüfe, ob der vorstehende (n-1) Ring der führende Ring ist.
// Denn nur dann kann der gewünschte Ring bewegt werden.
int leaderPos = getLeadingRingPos(stick);
if(pos - leaderPos == 1) {
result = true;
} else {
result = false;
}
}
return result;
}
final public static byte move(byte stick, int pos, boolean on)
throws Exception
{
byte newStick = stick;
if(canMove(stick, pos)) {
if(on && !isOnStick(stick, pos))
{
// Auf Stick aufhängen...
// Verwende OR und Left-Shift um das passende Bit zu setzen.
newStick |= (1 << pos);
}
else if(!on && isOnStick(stick, pos))
{
// Wie oben, nur negiert und umgekehrt.
newStick &= ~(1 << pos);
}
else
{
// Generiere eine vernünftige Fehlermeldung.
throw new Exception(
"Ring auf pos=" + pos
+ " sollte " + (on ? "aufgesetzt" : "entfernt") + " werden.\n"
+ "Allerdings ist dieser Ring "
+(isOnStick(stick, pos)?"aufgesetzt":"entfernt")+"!"
);
}
} else {
throw new Exception("Kann pos="+pos+" nicht bewegen (canMove() == FALSE).");
}
return newStick;
}
final public static void printStick(byte stick) {
// @see https://stackoverflow.com/questions/12310017/how-to-convert-a-byte-to-its-binary-string-representation
// 0xFF (hex) = 255 (dez) = 11111110 (bin)
// 0x100 (hex) = 256 (dez) = 11111111 (bin, Vorzeichenlos)
System.out.println(
Integer.toBinaryString(
(stick & 0xFF) + 0x100
).substring(1)
);
}
final public static byte solve(byte stick, int rings) {
return 0;
}
final public static byte unsolve(byte stick, int rings) {
return 0;
}
final public static void main(String[] argv) {
System.out.println("Willkommen zur Lösung von Aufgabe 4.2!");
System.out.println("Beobachten Sie nun, wie sich die Ringe von selbst lösen.");
try {
byte stick = 0b00000000;
printStick(stick);
stick = move(stick, 3, true);
printStick(stick);
} catch(Exception e) {
System.out.println(e.getMessage());
System.exit(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment