AlgoAnim Uebung 3, Uebung 4

This commit is contained in:
M.Scholz 2012-05-15 10:43:51 +02:00
parent 9f02922ba9
commit 5bb82966ac
3 changed files with 659 additions and 82 deletions

View File

@ -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;

View File

@ -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"

View File

@ -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<String, Object> 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 &Aumlgyptischen Multiplizieren, Abessinische Bauernregel oder Verdopplungs-Halbierungs-Methode"
+"\n"
+"bekannt. Die Geschichte des vorgestellten Rechenverfahrens f&uumlhrt bis auf die &Aumlgypter 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&aumlsst sich in die folgenden f&uumlnf 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 &uumlbrigen 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;
}
}