diff --git a/ss2012/AlgoAnim/Teil 3/RussischeBauernmultiplikation.java b/ss2012/AlgoAnim/Teil 3/RussischeBauernmultiplikation.java index 02470332..0d6e4928 100644 --- a/ss2012/AlgoAnim/Teil 3/RussischeBauernmultiplikation.java +++ b/ss2012/AlgoAnim/Teil 3/RussischeBauernmultiplikation.java @@ -20,27 +20,20 @@ import algoanim.util.Timing; /** * @author Michael Scholz, Ulf Gebhardt - * @version 0.1 2012-05-15 + * @version 0.7 2012-05-15 * */ public class RussischeBauernmultiplikation { - //Feedback aus †bung 2: - /*Es handelt sich bereits um eine anschauliche Animation. - * Dennoch fallen mir ein Paar Details ein, die ihr im Laufe der nŠchsten Aufgaben - * noch einbauen solltet. - * - * Dass die Aufrufkette am Ende der Animation źber die return-Statements wieder - * nach oben zurźckverfolgt wird, ist nicht unbedingt intuitiv ersichtlich. - * Das kšnnte man noch erlŠutern oder vielleicht auch graphisch verdeutlichen. - * Die im letzten Schritt einfach da stehende Zerlegung in Zweierpotenzen kšnnte - * ebenfalls animiert dargestellt werden. - * - * - * -> Aufrufkette - * -> Zerlegung in Zweierpotenzen animieren - * - * */ + /** + * static variables -> simple testing + */ + static int A = 27; + static int B = 82; + static int HIGHLIGHTING_TIME = 100; //in ticks + static int UNHIGHLIGHTING_TIME = 0; //in ticks + +//========================================================================================================= /** * The concrete language object used for creating output @@ -68,22 +61,53 @@ public class RussischeBauernmultiplikation { /** * The tables */ - StringMatrix tb1 = null; - StringMatrix tb2 = null; + private StringMatrix tb1 = null; + private StringMatrix tb2 = null; /** * int-array with the values of b (only for animation) */ - public int[] bArray = null; + private int[] bArray = null; /** * recursionArray */ - public int[] recursionArray = null; + private int[] recursionArray = null; + /** + * unhighlightingTime + */ + private Timing unhighTime = new Timing(UNHIGHLIGHTING_TIME) { + + @Override + public String getUnit() { + // TODO Auto-generated method stub + return "ticks"; + } + }; + + + /** + * highlightTime + */ + private Timing highTime = new Timing(HIGHLIGHTING_TIME) { + + @Override + public String getUnit() { + // TODO Auto-generated method stub + return "ticks"; + } + }; + + + /** + * number of lines for tb1 + */ + private int linesOfTb1 = 0; + private static final String DESCRIPTION = "Russische Bauernmultiplikation\n" + "Das hier vorgestellte Verfahren eignet sich fźr die Multiplikation zweier ganzer Zahlen.\n" + @@ -106,6 +130,9 @@ public class RussischeBauernmultiplikation { + "\n return russe(a/2, b*2);" // 7 + "\n }" // 8 + "\n }"; // 9 + + +//========================================================================================================= /** @@ -199,7 +226,7 @@ public class RussischeBauernmultiplikation { * @param b * @return int number of needed lines */ - public int calculateLines(int a, int b){ + public void calculateLines(int a, int b){ //calculate needed lines -> animation is more dynamic int aTemp = a; @@ -211,7 +238,7 @@ public class RussischeBauernmultiplikation { //initialize the bArray und the recursionArray this.bArray = new int[lines-1]; this.recursionArray = new int[lines-1]; - return lines; + this.linesOfTb1 = lines; } @@ -221,7 +248,7 @@ public class RussischeBauernmultiplikation { * @param b * @param lines */ - public void generateTable(int a, int b, int lines){ + public void generateTableTb1(int a, int b, int lines){ //create String[][] data array for tb1 String[][] tb1Data = new String[lines][4]; @@ -299,10 +326,11 @@ public class RussischeBauernmultiplikation { //create table tb2 if(this.tb2 != null){ - this.tb2.hide(); //hide old version of tb2 + this.tb2.put(1, 0, tmp, this.highTime, this.highTime); + }else{ + this.tb2 = lang.newStringMatrix(new Offset(0, 10, this.tb1, AnimalScript.DIRECTION_SW), tb2Data, "tb2", null); + this.tb2.changeColor(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE, null, null); } - this.tb2 = lang.newStringMatrix(new Offset(0, 10, this.tb1, AnimalScript.DIRECTION_SW), tb2Data, "tb2", null); - this.tb2.changeColor(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE, null, null); } @@ -319,7 +347,7 @@ public class RussischeBauernmultiplikation { int newLineNumber = 0; int oldLineNumber = 0; - sc.unhighlight(2); //"return b" + this.sc.unhighlight(2); //"return b" for(int i = this.bArray.length-1; i > 1; i--){ oldLineNumber = newLineNumber; if(this.recursionArray[i-1] == 0){ @@ -327,19 +355,23 @@ public class RussischeBauernmultiplikation { }else{ newLineNumber = 7; } - sc.unhighlight(oldLineNumber); + if(oldLineNumber == 5){ + this.tb2.unhighlightCell(1, 0, this.unhighTime, this.unhighTime); + } + this.sc.unhighlight(oldLineNumber); //STEP lang.nextStep(); - - sc.highlight(newLineNumber); + this.sc.highlight(newLineNumber); + if(newLineNumber == 5){ + this.tb2.highlightCell(1, 0, this.highTime, this.highTime); + } //update tb2 this.bArray[i-1] = this.bArray[i-1] + this.bArray[i]; drawTb2(i); //STEP lang.nextStep(); } - sc.unhighlight(oldLineNumber); - + this.sc.unhighlight(oldLineNumber); } /** @@ -349,7 +381,7 @@ public class RussischeBauernmultiplikation { */ public void multiply(int a, int b){ - //generate information text and the header + //generate information text and the header generateInfoText(); generateHeader(); @@ -361,8 +393,8 @@ public class RussischeBauernmultiplikation { generateSourceCode(); //calculate needed lines and generate table - int lines = calculateLines(a, b); - generateTable(a, b, lines); + calculateLines(a, b); + generateTableTb1(a, b, this.linesOfTb1); //STEP lang.nextStep(); @@ -370,9 +402,10 @@ public class RussischeBauernmultiplikation { //higlight line 0 this.sc.highlight(0); - russe(a, b, sc, tb1, 1, ""); - // this.tb1.put(lines - 1, 2, "Ergebnis", null, null); - //this.tb1.put(lines - 1, 3, result+"", null, null); + russe(a, b, sc, tb1, 1, ""); + + //unhighlight last line of tb1 + this.tb1.unhighlightCellColumnRange(this.linesOfTb1-2, 2, 3, this.unhighTime, this.unhighTime); //generate recursion animation generateRecursion(); @@ -400,24 +433,17 @@ public class RussischeBauernmultiplikation { */ public int russe(int a, int b, SourceCode code, StringMatrix tb1, int line, String sum){ - - int aTb = a; int bTb = b; - Timing sTime = new Timing(100) { - - @Override - public String getUnit() { - // TODO Auto-generated method stub - return "ticks"; - } - }; - tb1.highlightCell(line, 0, sTime, sTime); - tb1.put(line, 0, a+"", null, null); //update column 0 (a) - tb1.put(line, 1, b+"", null, null); //update column 1 (b) + + this.tb1.unhighlightCellColumnRange(line-1, 2, 3, this.unhighTime, this.unhighTime); + this.tb1.highlightCellColumnRange(line, 0, 1, this.highTime, this.highTime); + this.tb1.put(line, 0, a+"", null, null); //update column 0 (a) + this.tb1.put(line, 1, b+"", null, null); //update column 1 (b) //STEP lang.nextStep(); + this.tb1.unhighlightCellColumnRange(line, 0, 1, this.unhighTime, this.unhighTime); code.unhighlight(0); code.highlight(1); @@ -430,8 +456,9 @@ public class RussischeBauernmultiplikation { //write last line sum = sum+"+"+b; //update table - tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) - tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + this.tb1.highlightCellColumnRange(line, 2, 3, this.highTime, this.highTime); + this.tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) + this.tb1.put(line, 3, sum, null, null); //update column 3 (Summe) this.bArray[line] = b; return b; } @@ -458,8 +485,9 @@ public class RussischeBauernmultiplikation { } } //update table - tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) - tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + this.tb1.highlightCellColumnRange(line, 2, 3, this.highTime, this.highTime); + this.tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) + this.tb1.put(line, 3, sum, null, null); //update column 3 (Summe) //STEP lang.nextStep(); @@ -473,8 +501,9 @@ public class RussischeBauernmultiplikation { else{ code.toggleHighlight(4, 7); //update table - tb1.put(line, 2, "Nein", null, null); //update column 2 (addieren) - tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + this.tb1.highlightCellColumnRange(line, 2, 3, this.highTime, this.highTime); + this.tb1.put(line, 2, "Nein", null, null); //update column 2 (addieren) + this.tb1.put(line, 3, sum, null, null); //update column 3 (Summe) //STEP lang.nextStep(); @@ -513,9 +542,7 @@ public class RussischeBauernmultiplikation { Language l = new AnimalScript("Russische Bauenmultiplikation", "Michael Scholz, Ulf Gebhardt", 640, 480); RussischeBauernmultiplikation s = new RussischeBauernmultiplikation(l); - int a = 27; - int b = 82; - s.multiply(a, b); + s.multiply(A, B); //konsolenausgabe direkt als asu-datei schreiben, vor Abgabe bitte wieder entfernen!!! boolean writeFile = false; diff --git a/ss2012/AlgoAnim/Teil 3/uebung3_2.asu b/ss2012/AlgoAnim/Teil 3/uebung3_2.asu index f9a82040..70626dcd 100644 --- a/ss2012/AlgoAnim/Teil 3/uebung3_2.asu +++ b/ss2012/AlgoAnim/Teil 3/uebung3_2.asu @@ -60,11 +60,16 @@ author "Michael Scholz, Ulf Gebhardt" } { highlightCode on "sourceCode" line 0 row 0 + unhighlightGridCell "tb1[0][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[0][3]" after 0 ticks within 0 ticks highlightGridCell "tb1[1][0]" after 100 ticks within 100 ticks + highlightGridCell "tb1[1][1]" after 100 ticks within 100 ticks setGridValue "tb1[1][0]" "27" refresh setGridValue "tb1[1][1]" "82" refresh } { + unhighlightGridCell "tb1[1][0]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[1][1]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 0 row 0 highlightCode on "sourceCode" line 1 row 0 } @@ -76,17 +81,24 @@ author "Michael Scholz, Ulf Gebhardt" unhighlightCode on "sourceCode" line 1 row 0 unhighlightCode on "sourceCode" line 4 row 0 highlightCode on "sourceCode" line 5 row 0 + highlightGridCell "tb1[1][2]" after 100 ticks within 100 ticks + highlightGridCell "tb1[1][3]" after 100 ticks within 100 ticks setGridValue "tb1[1][2]" "Ja" refresh setGridValue "tb1[1][3]" "82" refresh } { unhighlightCode on "sourceCode" line 5 row 0 highlightCode on "sourceCode" line 0 row 0 + unhighlightGridCell "tb1[1][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[1][3]" after 0 ticks within 0 ticks highlightGridCell "tb1[2][0]" after 100 ticks within 100 ticks + highlightGridCell "tb1[2][1]" after 100 ticks within 100 ticks setGridValue "tb1[2][0]" "13" refresh setGridValue "tb1[2][1]" "164" refresh } { + unhighlightGridCell "tb1[2][0]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[2][1]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 0 row 0 highlightCode on "sourceCode" line 1 row 0 } @@ -98,17 +110,24 @@ author "Michael Scholz, Ulf Gebhardt" unhighlightCode on "sourceCode" line 1 row 0 unhighlightCode on "sourceCode" line 4 row 0 highlightCode on "sourceCode" line 5 row 0 + highlightGridCell "tb1[2][2]" after 100 ticks within 100 ticks + highlightGridCell "tb1[2][3]" after 100 ticks within 100 ticks setGridValue "tb1[2][2]" "Ja" refresh setGridValue "tb1[2][3]" "82+164" refresh } { unhighlightCode on "sourceCode" line 5 row 0 highlightCode on "sourceCode" line 0 row 0 + unhighlightGridCell "tb1[2][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[2][3]" after 0 ticks within 0 ticks highlightGridCell "tb1[3][0]" after 100 ticks within 100 ticks + highlightGridCell "tb1[3][1]" after 100 ticks within 100 ticks setGridValue "tb1[3][0]" "6" refresh setGridValue "tb1[3][1]" "328" refresh } { + unhighlightGridCell "tb1[3][0]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[3][1]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 0 row 0 highlightCode on "sourceCode" line 1 row 0 } @@ -120,17 +139,24 @@ author "Michael Scholz, Ulf Gebhardt" unhighlightCode on "sourceCode" line 1 row 0 unhighlightCode on "sourceCode" line 4 row 0 highlightCode on "sourceCode" line 7 row 0 + highlightGridCell "tb1[3][2]" after 100 ticks within 100 ticks + highlightGridCell "tb1[3][3]" after 100 ticks within 100 ticks setGridValue "tb1[3][2]" "Nein" refresh setGridValue "tb1[3][3]" "82+164" refresh } { highlightCode on "sourceCode" line 0 row 0 unhighlightCode on "sourceCode" line 7 row 0 + unhighlightGridCell "tb1[3][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[3][3]" after 0 ticks within 0 ticks highlightGridCell "tb1[4][0]" after 100 ticks within 100 ticks + highlightGridCell "tb1[4][1]" after 100 ticks within 100 ticks setGridValue "tb1[4][0]" "3" refresh setGridValue "tb1[4][1]" "656" refresh } { + unhighlightGridCell "tb1[4][0]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[4][1]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 0 row 0 highlightCode on "sourceCode" line 1 row 0 } @@ -142,25 +168,36 @@ author "Michael Scholz, Ulf Gebhardt" unhighlightCode on "sourceCode" line 1 row 0 unhighlightCode on "sourceCode" line 4 row 0 highlightCode on "sourceCode" line 5 row 0 + highlightGridCell "tb1[4][2]" after 100 ticks within 100 ticks + highlightGridCell "tb1[4][3]" after 100 ticks within 100 ticks setGridValue "tb1[4][2]" "Ja" refresh setGridValue "tb1[4][3]" "82+164+656" refresh } { unhighlightCode on "sourceCode" line 5 row 0 highlightCode on "sourceCode" line 0 row 0 + unhighlightGridCell "tb1[4][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[4][3]" after 0 ticks within 0 ticks highlightGridCell "tb1[5][0]" after 100 ticks within 100 ticks + highlightGridCell "tb1[5][1]" after 100 ticks within 100 ticks setGridValue "tb1[5][0]" "1" refresh setGridValue "tb1[5][1]" "1312" refresh } { + unhighlightGridCell "tb1[5][0]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[5][1]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 0 row 0 highlightCode on "sourceCode" line 1 row 0 } { unhighlightCode on "sourceCode" line 1 row 0 highlightCode on "sourceCode" line 2 row 0 + highlightGridCell "tb1[5][2]" after 100 ticks within 100 ticks + highlightGridCell "tb1[5][3]" after 100 ticks within 100 ticks setGridValue "tb1[5][2]" "Ja" refresh setGridValue "tb1[5][3]" "82+164+656+1312" refresh + unhighlightGridCell "tb1[5][2]" after 0 ticks within 0 ticks + unhighlightGridCell "tb1[5][3]" after 0 ticks within 0 ticks grid "tb2" offset (0, 10) from "tb1" SW lines 2 columns 1 color (0, 0, 0) elementColor (0, 0, 0) fillColor (0, 0, 0) highlightTextColor (0, 0, 0) highlightBackColor (0, 0, 0) depth 1 setGridValue "tb2[0][0]" "Rekursion aufloesen:" setGridValue "tb2[1][0]" "82+164+656+1312" refresh @@ -172,44 +209,33 @@ author "Michael Scholz, Ulf Gebhardt" } { highlightCode on "sourceCode" line 5 row 0 - grid "StringMatrix1" offset (0, 10) from "tb1" SW lines 2 columns 1 color (0, 0, 0) elementColor (0, 0, 0) fillColor (0, 0, 0) highlightTextColor (0, 0, 0) highlightBackColor (0, 0, 0) depth 1 - setGridValue "StringMatrix1[0][0]" "Rekursion aufloesen:" - setGridValue "StringMatrix1[1][0]" "82+164+1968" refresh - color "StringMatrix1" type "fillColor" (255, 255, 255) - hide "tb2" + highlightGridCell "tb2[1][0]" after 100 ticks within 100 ticks + setGridValue "tb2[1][0]" "82+164+1968" refresh after 100 ticks within 100 ticks } { + unhighlightGridCell "tb2[1][0]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 5 row 0 } { highlightCode on "sourceCode" line 7 row 0 - grid "StringMatrix2" offset (0, 10) from "tb1" SW lines 2 columns 1 color (0, 0, 0) elementColor (0, 0, 0) fillColor (0, 0, 0) highlightTextColor (0, 0, 0) highlightBackColor (0, 0, 0) depth 1 - setGridValue "StringMatrix2[0][0]" "Rekursion aufloesen:" - setGridValue "StringMatrix2[1][0]" "82+164+1968" refresh - color "StringMatrix2" type "fillColor" (255, 255, 255) - hide "StringMatrix1" + setGridValue "tb2[1][0]" "82+164+1968" refresh after 100 ticks within 100 ticks } { unhighlightCode on "sourceCode" line 7 row 0 } { highlightCode on "sourceCode" line 5 row 0 - grid "StringMatrix3" offset (0, 10) from "tb1" SW lines 2 columns 1 color (0, 0, 0) elementColor (0, 0, 0) fillColor (0, 0, 0) highlightTextColor (0, 0, 0) highlightBackColor (0, 0, 0) depth 1 - setGridValue "StringMatrix3[0][0]" "Rekursion aufloesen:" - setGridValue "StringMatrix3[1][0]" "82+2132" refresh - color "StringMatrix3" type "fillColor" (255, 255, 255) - hide "StringMatrix2" + highlightGridCell "tb2[1][0]" after 100 ticks within 100 ticks + setGridValue "tb2[1][0]" "82+2132" refresh after 100 ticks within 100 ticks } { + unhighlightGridCell "tb2[1][0]" after 0 ticks within 0 ticks unhighlightCode on "sourceCode" line 5 row 0 } { highlightCode on "sourceCode" line 5 row 0 - grid "StringMatrix4" offset (0, 10) from "tb1" SW lines 2 columns 1 color (0, 0, 0) elementColor (0, 0, 0) fillColor (0, 0, 0) highlightTextColor (0, 0, 0) highlightBackColor (0, 0, 0) depth 1 - setGridValue "StringMatrix4[0][0]" "Rekursion aufloesen:" - setGridValue "StringMatrix4[1][0]" "2214" refresh - color "StringMatrix4" type "fillColor" (255, 255, 255) - hide "StringMatrix3" + highlightGridCell "tb2[1][0]" after 100 ticks within 100 ticks + setGridValue "tb2[1][0]" "2214" refresh after 100 ticks within 100 ticks } { unhighlightCode on "sourceCode" line 5 row 0 @@ -220,7 +246,7 @@ author "Michael Scholz, Ulf Gebhardt" addCodeLine "Die Idee des Verfahrens kann man mit Hilfe des Dualsystems verdeutlichen." to "statement" addCodeLine "Hierbei wird eine Zahl in ihre Zweierpotenzen zerlegt." to "statement" addCodeLine "" to "statement" - hide "tb1" "StringMatrix4" "sourceCode" + hide "tb1" "tb2" "sourceCode" } { addCodeLine "82 * 27 = 82 * (2^0 + 2^1 + 0 * 2^2 + 2^3 + 2^4 )" to "statement" diff --git a/ss2012/AlgoAnim/Teil 4/RMultiGenerator.java b/ss2012/AlgoAnim/Teil 4/RMultiGenerator.java new file mode 100644 index 00000000..9e6c3a10 --- /dev/null +++ b/ss2012/AlgoAnim/Teil 4/RMultiGenerator.java @@ -0,0 +1,524 @@ +package generators.maths; + +import generators.framework.Generator; +import generators.framework.GeneratorType; + +import java.awt.Color; +import java.util.Locale; + +import algoanim.primitives.SourceCode; +import algoanim.primitives.StringMatrix; +import algoanim.primitives.generators.Language; +import algoanim.properties.AnimationPropertiesKeys; +import algoanim.properties.RectProperties; +import algoanim.properties.SourceCodeProperties; +import algoanim.properties.TextProperties; +import algoanim.util.Coordinates; +import algoanim.util.Offset; +import algoanim.util.Timing; + +import java.util.Hashtable; + +import de.ahrgr.animal.kohnert.asugen.Font; +import generators.framework.properties.AnimationPropertiesContainer; +import algoanim.animalscript.AnimalScript; + +public class RMultiGenerator implements Generator { + private Language lang; + private int b; + private int a; + + /** + * The info text as a SourceCode object (first slide) + */ + private SourceCode info = null; + + /** + * The statement text as a SourceCode object (last several slides) + */ + private SourceCode statement = null; + + + /** + * The sourceCode + */ + private SourceCode sc = null; + + + /** + * The tables + */ + StringMatrix tb1 = null; + StringMatrix tb2 = null; + + + /** + * int-array with the values of b (only for animation) + */ + public int[] bArray = null; + + + /** + * recursionArray + */ + public int[] recursionArray = null; + + + /** + * Builds the information text for the first page in the animation + */ + public void generateInfoText(){ + + //create first page of animation (info text) as a code group + SourceCodeProperties infoProps = new SourceCodeProperties(); + infoProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new java.awt.Font("SansSerif", Font.SANSSERIF, 16)); + + this.info = lang.newSourceCode(new Coordinates(10, 75), "info", null, infoProps); + this.info.addCodeLine("Das hier vorgestellte Verfahren eignet sich fuer die Multiplikation zweier ganzer Zahlen.", null, 0, null); + this.info.addCodeLine("Die Funktionsweise laesst sich in die folgenden fuenf Schritte gliedern:", null, 0, null); + this.info.addCodeLine("1. Schreibe die beiden zu multiplizierenden Zahlen nebeneinander.", null, 1, null); + this.info.addCodeLine("2. Die linke Zahl wird halbiert (Reste werden abgerundet), die rechte Zahl wird verdoppelt.", null, 1, null); + this.info.addCodeLine(" Die beiden berechneten Zahlen werden in die darauffolgende Zeile geschrieben.", null, 2, null); + this.info.addCodeLine("3. Schritt 2 wird solange wiederholt, bis in der linken Spalte eine 1 steht.", null, 1, null); + this.info.addCodeLine("4. Nun streicht man alle Zeilen, in denen die linke Zahl gerade ist.", null, 1, null); + this.info.addCodeLine("5. Schlussendlich werden alle uebrigen Zahlen der rechten Spalte addiert.", null, 1, null); + } + + + /** + * Builds the header which is shown during the whole animation + */ + public void generateHeader(){ + + //head + TextProperties textProperties = new TextProperties(); + textProperties.set(AnimationPropertiesKeys.COLOR_PROPERTY, Color.BLACK); + textProperties.set(AnimationPropertiesKeys.DEPTH_PROPERTY, 1); + textProperties.set(AnimationPropertiesKeys.FONT_PROPERTY, new java.awt.Font("Serif", Font.SANSSERIF, 24)); + lang.newText(new Coordinates(11, 15), "Russische Bauernmultiplikation", "header", null, textProperties); + + //header background + RectProperties rectProperties = new RectProperties(); + rectProperties.set(AnimationPropertiesKeys.FILL_PROPERTY, Color.GRAY); + rectProperties.set(AnimationPropertiesKeys.FILLED_PROPERTY, true); + rectProperties.set(AnimationPropertiesKeys.DEPTH_PROPERTY, 2); + lang.newRect(new Offset(-5, -5, "header", + AnimalScript.DIRECTION_NW), new Offset(5, 5, "header", + AnimalScript.DIRECTION_SE), "headerBackground", null, + rectProperties); + } + + + /** + * Builds the SourceCode + */ + public void generateSourceCode(){ + + //set the visual properties for the source code + SourceCodeProperties scProps = new SourceCodeProperties(); + scProps.set(AnimationPropertiesKeys.HIGHLIGHTCOLOR_PROPERTY, Color.RED); + + //initialize source code object and add code lines + this.sc = lang.newSourceCode(new Coordinates(10, 147), "sourceCode", null, scProps); + this.sc.addCodeLine("public int russe(int a, int b){", null, 0, null); // 0 + this.sc.addCodeLine("if(a == 1){", null, 1, null); // 1 + this.sc.addCodeLine("return b;", null, 2, null); // 2 + this.sc.addCodeLine("}", null, 1, null); // 3 + this.sc.addCodeLine("if(a % 2 == 1){", null, 1, null); // 4 + this.sc.addCodeLine("return b + russe(a/2, b*2);", null, 2, null); // 5 + this.sc.addCodeLine("}else{", null, 1, null); // 6 + this.sc.addCodeLine("return russe(a/2, b*2);", null, 2, null); // 7 + this.sc.addCodeLine("}", null, 1, null); // 8 + this.sc.addCodeLine("}", null, 0, null); // 9 + + } + + + /** + * calculate needed lines -> animation is more dynamic + * @param a + * @param b + * @return int number of needed lines + */ + public int calculateLines(int a, int b){ + + //calculate needed lines -> animation is more dynamic + int aTemp = a; + int lines = 3; + while(aTemp != 1){ + aTemp = aTemp / 2; + lines++; + } + //initialize the bArray und the recursionArray + this.bArray = new int[lines-1]; + this.recursionArray = new int[lines-1]; + return lines; + } + + + /** + * Builds the table + * @param a + * @param b + * @param lines + */ + public void generateTable(int a, int b, int lines){ + + //create String[][] data array for tb1 + String[][] tb1Data = new String[lines][4]; + + //fill all fields with "" + for(int i = 0; i < tb1Data.length; i++){ + for(int j = 0; j < tb1Data[i].length; j++){ + tb1Data[i][j] = ""; + } + } + + //fill the known fields + tb1Data[0][0] = "A-Seite"; + tb1Data[0][1] = "B-Seite"; + tb1Data[0][2] = "addieren"; + tb1Data[0][3] = "Summe"; + tb1Data[1][0] = a+""; + tb1Data[1][1] = b+""; + + //create table tb1 + this.tb1 = lang.newStringMatrix(new Coordinates(270, 100), tb1Data, "tb1", null); + this.tb1.changeColor(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE, null, null); + + } + + /** + * builds the statement for the last several slides + */ + public void generateStatement(){ + //final statement + SourceCodeProperties statementProps = new SourceCodeProperties(); + statementProps.set(AnimationPropertiesKeys.FONT_PROPERTY, new java.awt.Font("SansSerif", Font.SANSSERIF, 16)); + + this.statement = lang.newSourceCode(new Coordinates(10, 75), "statement", null, statementProps); + this.statement.addCodeLine("Erklaerung:", null, 0, null); + this.statement.addCodeLine("Die Idee des Verfahrens kann man mit Hilfe des Dualsystems verdeutlichen.", null, 0, null); + this.statement.addCodeLine("Hierbei wird eine Zahl in ihre Zweierpotenzen zerlegt.", null, 0, null); + this.statement.addCodeLine("", null, 0, null); //empty line for vertical space + //STEP + lang.nextStep(); + this.statement.addCodeLine("82 * 27 = 82 * (2^0 + 2^1 + 0 * 2^2 + 2^3 + 2^4 )", null, 0, null); + //STEP + lang.nextStep(); + this.statement.addCodeLine("= 82 * 2^0 + 82 * 2^1 + 82 * 0 + 82 * 2^3 + 82 * 2^4", null, 4, null); + //STEP + lang.nextStep(); + this.statement.addCodeLine("= 82 + 164 + 0 + 656 + 1312", null, 4, null); + //STEP + lang.nextStep(); + this.statement.addCodeLine("= 2214", null, 4, null); + } + + + /** + * Draw the table tb2 + * @param bArrayLength + */ + public void drawTb2(int bArrayLength){ + + //create String[][] data array for tb2 + String[][] tb2Data = new String[2][1]; + tb2Data[0][0] = "Rekursion aufloesen:"; + + String tmp = ""; + for(int i = 1; i < bArrayLength; i++){ + if(this.bArray[i] != 0){ + tmp = tmp+this.bArray[i]; + if(i+1 != bArrayLength){ + tmp = tmp+"+"; + } + } + } + tb2Data[1][0] = tmp; + + + //create table tb2 + if(this.tb2 != null){ + this.tb2.hide(); //hide old version of tb2 + } + this.tb2 = lang.newStringMatrix(new Offset(0, 10, this.tb1, AnimalScript.DIRECTION_SW), tb2Data, "tb2", null); + this.tb2.changeColor(AnimationPropertiesKeys.FILL_PROPERTY, Color.WHITE, null, null); + } + + + /** + * Generates the animation of the recursion flow + */ + public void generateRecursion(){ + + //draw tb2 + drawTb2(this.bArray.length); + +//STEP + lang.nextStep(); + + int newLineNumber = 0; + int oldLineNumber = 0; + sc.unhighlight(2); //"return b" + for(int i = this.bArray.length-1; i > 1; i--){ + oldLineNumber = newLineNumber; + if(this.recursionArray[i-1] == 0){ + newLineNumber = 5; + }else{ + newLineNumber = 7; + } + sc.unhighlight(oldLineNumber); +//STEP + lang.nextStep(); + + sc.highlight(newLineNumber); + //update tb2 + this.bArray[i-1] = this.bArray[i-1] + this.bArray[i]; + drawTb2(i); +//STEP + lang.nextStep(); + } + sc.unhighlight(oldLineNumber); + + } + + /** + * logical method: calls the needed methods for generating the animation + * @param a + * @param b + */ + public void multiply(int a, int b){ + + //generate information text and the header + generateInfoText(); + generateHeader(); + +//STEP + lang.nextStep(); + this.info.hide(); + + //generate SourceCode + generateSourceCode(); + + //calculate needed lines and generate table + int lines = calculateLines(a, b); + generateTable(a, b, lines); + +//STEP + lang.nextStep(); + + //higlight line 0 + this.sc.highlight(0); + + russe(a, b, sc, tb1, 1, ""); + // this.tb1.put(lines - 1, 2, "Ergebnis", null, null); + //this.tb1.put(lines - 1, 3, result+"", null, null); + + //generate recursion animation + generateRecursion(); + +//STEP + lang.nextStep(); + this.tb1.hide(); + this.tb2.hide(); + this.sc.hide(); + + //generate statement + generateStatement(); + + } + + /** + * the algorithm which is used in the animation + * @param a + * @param b + * @param code + * @param tb1 + * @param line + * @param sum + * @return the product of a and b (a*b) + */ + public int russe(int a, int b, SourceCode code, StringMatrix tb1, int line, String sum){ + + + + int aTb = a; + int bTb = b; + Timing sTime = new Timing(100) { + + @Override + public String getUnit() { + // TODO Auto-generated method stub + return "ticks"; + } + }; + tb1.highlightCell(line, 0, sTime, sTime); + tb1.put(line, 0, a+"", null, null); //update column 0 (a) + tb1.put(line, 1, b+"", null, null); //update column 1 (b) + + //STEP + lang.nextStep(); + code.unhighlight(0); + code.highlight(1); + + //STEP + lang.nextStep(); + + if(a == 1){ + code.toggleHighlight(1, 2); + + //write last line + sum = sum+"+"+b; + //update table + tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) + tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + this.bArray[line] = b; + return b; + } + if(line != 1){ // first line + aTb = aTb/2; + bTb = bTb*2; + } + code.toggleHighlight(1, 4); + + //STEP + lang.nextStep(); + code.unhighlight(1); + + if(a % 2 == 1){ + code.toggleHighlight(4, 5); + + if(line == 1){ + sum = b+""; + }else{ + if(sum.equals("")){ + sum = b+"";} + else{ + sum = sum+"+"+b; + } + } + //update table + tb1.put(line, 2, "Ja", null, null); //update column 2 (addieren) + tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + + //STEP + lang.nextStep(); + code.unhighlight(5); + code.highlight(0); + //safe actual value of b in bArray + this.bArray[line] = b; + this.recursionArray[line] = 0; + return b + russe(a/2, b*2, code, tb1, line+1, sum); + } + else{ + code.toggleHighlight(4, 7); + //update table + tb1.put(line, 2, "Nein", null, null); //update column 2 (addieren) + tb1.put(line, 3, sum, null, null); //update column 3 (Summe) + + //STEP + lang.nextStep(); + code.highlight(0); + code.unhighlight(7); + //safe 0 in bArray + this.bArray[line] = 0; + this.recursionArray[line] = 1; + return russe(a/2, b*2, code, tb1, line+1, sum); + } + } + + public void init(){ + lang = new AnimalScript("Russische Bauenmultiplikation [DE]", "Ulf Gebhardt, Michael Scholz", 800, 600); + } + + public String generate(AnimationPropertiesContainer props,Hashtable primitives) { + b = (Integer)primitives.get("b"); + a = (Integer)primitives.get("a"); + + RMultiGenerator multi = new RMultiGenerator(); + multi.multiply(a, b); + + return lang.toString(); + } + + public String getName() { + return "Russische Bauenmultiplikation [DE]"; + } + + public String getAlgorithmName() { + return "Russische Bauenmultiplikation"; + } + + public String getAnimationAuthor() { + return "Ulf Gebhardt, Michael Scholz"; + } + + public String getDescription(){ + return "Das hier vorgestellte Verfahren eignete sich fźr die Multiplikation zweier ganzer Zahlen. Es ist auch unter den" + +"\n" + +"Namen Ägyptischen Multiplizieren, Abessinische Bauernregel oder Verdopplungs-Halbierungs-Methode" + +"\n" + +"bekannt. Die Geschichte des vorgestellten Rechenverfahrens führt bis auf die Ägypter zurźck. Sie" + +"\n" + +"nutzten diese Methode nachweislich zur Multiplikation zweier ganzer Zahlen. Das Verfahren baut auf dem Teile und Herrsche Prinzip" + +"\n" + +"(Divide et impera ) auf und lŠsst sich somit leicht mittels Rekursion implementieren.\n" + +"\n" + +"Die Funktionsweise lässt sich in die folgenden fünf Schritte gliedern:\n" + +"\n" + +"1. Schreibe die beiden zu multiplizierenden Zahlen nebeneinander.\n" + +"\n" + +"2. Die linke Zahl wird halbiert (Reste werden abgerundet), die rechte Zahl wird verdoppelt.\n" + +"\n" + +"\t Die beiden berechneten Zahlen werden in die darauffolgende Zeile geschrieben.\n" + +"\n" + +"3. Schritt 2 wird solange wiederholt, bis in der linken Spalte eine 1 steht.\n" + +"\n" + +"4. Nun streicht man alle Zeilen, in denen die linke Zahl gerade ist.\n" + +"\n" + +"5. Schlussendlich werden alle übrigen Zahlen der rechten Spalte addiert." + +"\n" + +" "; + } + + public String getCodeExample(){ + return "public int russe(int a, int b){" + +"\n" + +" if(a == 1){" + +"\n" + +" return b;" + +"\n" + +" }" + +"\n" + +" if(a % 2 == 1){" + +"\n" + +" return b + russe(a/2, b*2);" + +"\n" + +" }else{" + +"\n" + +" return russe(a/2, b*2);" + +"\n" + +" }" + +"\n" + +"}" + +"\n"; + } + + public String getFileExtension(){ + return "asu"; + } + + public Locale getContentLocale() { + return Locale.GERMAN; + } + + public GeneratorType getGeneratorType() { + return new GeneratorType(GeneratorType.GENERATOR_TYPE_MORE); + } + + public String getOutputLanguage() { + return RMultiGenerator.JAVA_OUTPUT; + } + +} \ No newline at end of file