diff --git a/ArmySchubser.java b/ArmySchubser.java deleted file mode 100644 index 9bd5bc9..0000000 --- a/ArmySchubser.java +++ /dev/null @@ -1,95 +0,0 @@ -import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) -import greenfoot.MouseInfo.*; -import javax.swing.JOptionPane; - -/** - * Schubst Einheiten umher. - * - * @author MaxiJohl, GruenerWal - * @version 1.1.0 - */ - -public class ArmySchubser extends Map_World -{ - static Province savedProvince = null; - - /** - * Konstruktor für ArmySchubser. - * - * NICHT BENUTZEN! - * Sämtliche benötigten Methoden sind static! - */ - public ArmySchubser(String[] playerList, int[] colorList) - { - super(playerList,colorList); - } - - /** - * Nimmt zwei Provinzen entgegen, und fragt, wieviele Einheiten vom ersten zum zweiten Eintrag verschoben werden sollen. - * Überprüft, ob eine Verschiebung möglich ist und führt sie bei Erfolg aus. - */ - public void moveEntities(Province sourceProvince, Province destinationProvince) - { - String toMoveString = JOptionPane.showInputDialog(null, "Wieviele Einheiten willst du verschieben?"); - Integer entitiesToMove = Integer.valueOf(toMoveString); - - if ( entitiesToMove != null ) - { - if ( (sourceProvince.getEntityCount() - entitiesToMove) > 0) - { - sourceProvince.removeFromEntities(entitiesToMove); - destinationProvince.addToEntities(entitiesToMove); - JOptionPane.showMessageDialog(null,"Einheiten erfolgreich verschoben, Kommandant " + getPlayerName() + "."); - } - - else if ( (sourceProvince.getEntityCount() - entitiesToMove) <= 0) - { - JOptionPane.showMessageDialog(null,"Du hast nicht genügend Einheiten, um die gewünschte Anzahl von " + sourceProvince.getDisplayName() + " nach " + destinationProvince.getDisplayName() + " zu verschieben, Köhler."); - } - } - } - - /** - * Speichert ein gegebene Provinz als savedProvince ein, insofern dieser Platz nicht bereits belegt ist. - * Ist er das, so wird überprüft, ob eine neue, an savedProvince angrenzende Provinz angeklickt wurde. - * Ist dies der Fall, werden beide Provinzen an moveEntities übergeben. - */ - public void useProvincesToMove(Province givenProvince) - { - if (savedProvince == null) - { - savedProvince = givenProvince; - } - - else if ((savedProvince != null) && (givenProvince != savedProvince) && (savedProvince.getOwner() == givenProvince.getOwner()) && (savedProvince.getOwner() == currentPlayer) ) - { - if (givenProvince.isProvinceNear(savedProvince.getID()) == true) - { - moveEntities(savedProvince,givenProvince); - } - - savedProvince = null; - } - } - - /** - * Überprüft, ob eine Provinz angeklickt wurde. - * Wenn ja, wird diese als clickedProvince eingespeichert und useProvincesToMove aufgerufen. - * - * Kommt nachher in die GeneralMap! - */ - public void act() - { - Province clickedProvince; - - for ( int i = 1; i <= (provinces.length - 1); i++) - { - if (provinces[i].hasClicked() == true) - { - clickedProvince = provinces[i]; - useProvincesToMove(clickedProvince); - break; - } - } - } -} \ No newline at end of file diff --git a/Fight.java b/Fight.java deleted file mode 100644 index 0debbd5..0000000 --- a/Fight.java +++ /dev/null @@ -1,112 +0,0 @@ -import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) -import java.util.Arrays; - -/** - * Write a description of class Fight here. - * - * @author (your name) - * @version (a version number or a date) - */ -public class Fight extends Map_World -{ - - /** - * Constructor for objects of class Fight. - * - */ - Province offenderProvince; - Province defenderProvince; - - public Fight(String[] playerList, int[] colorList) - { - super(playerList,colorList); - } - - public void act() - { - if(offenderProvince == null) - { - OffenderProvince(); - } - else - { - defenderProvince(); - } - } - - private void OffenderProvince() - { - for ( int i = 1; i <= provinceCount; i++) - { - if (provinces[i].hasClicked() == true) - { - offenderProvince = provinces[i]; - System.out.println("1"); - } - } - } - - private void defenderProvince() - { - { - for (int i = 1; i <= provinceCount; i++) - { - if (provinces[i].hasClicked() == true)//&& defenderProvince != offenderProvince) - { - defenderProvince = provinces[i]; - System.out.println("2"); - chooser(); - break; - } - } - } - } - - private void chooser() - { - Dice_Offender diceOffender = new Dice_Offender(); - int[] maxDiceOffender = diceOffender.max_offender(offenderProvince.getEntityCount()); - Dice_Defender diceDefender = new Dice_Defender(); - int[] maxDiceDefender = diceDefender.max_defender(defenderProvince.getEntityCount()); - Arrays.sort(maxDiceOffender); - Arrays.sort(maxDiceDefender); - decider(maxDiceOffender, maxDiceDefender); - } - - private void decider(int[] maxDiceOffender, int [] maxDiceDefender) - { - - int maxDefender = maxDiceDefender[1]; - int maxOffender = maxDiceOffender[2]; - if (maxOffender>maxDefender && defenderProvince.getEntityCount()>1) - { - int EntitiesOffender = offenderProvince.getEntityCount(); - int EntitiesDefender = defenderProvince.getEntityCount(); - defenderProvince.setEntityCount(EntitiesDefender - 1); - } - - if (maxOffender1) - { - int EntitiesOffender = offenderProvince.getEntityCount(); - int EntitiesDefender = defenderProvince.getEntityCount(); - offenderProvince.setEntityCount(EntitiesOffender - 1); - } - - if (maxOffender>maxDefender && defenderProvince.getEntityCount()==1) - { - defenderProvince.setOwner(offenderProvince.getOwner()); - defenderProvince.setEntityCount(0); - } - - if (maxOffender>maxDefender && offenderProvince.getEntityCount()==1) - { - offenderProvince.setOwner(defenderProvince.getOwner()); - offenderProvince.setEntityCount(0); - } - System.out.println("3"); - offenderProvince = null; - defenderProvince = null; - } -} - -//Ein <3 für Felix (von Aaron)(geschrieben von Samuel)(aber Aaron wollte das ich des schreib) diff --git a/GeneralMap.java b/GeneralMap.java index 48d710f..edf4909 100644 --- a/GeneralMap.java +++ b/GeneralMap.java @@ -1,51 +1,65 @@ import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.lang.Math; +import java.util.Arrays; +import greenfoot.MouseInfo.*; +import javax.swing.JOptionPane; /** - Oberklasse für verschiedene Maps; - neue Maps werden als Unterklasse dieser Klasse eingefügt. +Oberklasse für verschiedene Maps; +neue Maps werden als Unterklasse dieser Klasse eingefügt. - @author GruenerWal, MaxiJohl, Felix Stupp - @version 0.3.0 -*/ -public abstract class GeneralMap extends World +@author GruenerWal, MaxiJohl, Felix Stupp +@version 0.3.0 + */ +public abstract class GeneralMap extends World implements ButtonEvent { - /* - Felder, im Moment nur Anzahl der Provinzen - Später evtl. weitere Werte wie Schwierigkeit denkbar - */ - - private final int X_OFFSET = 160; // Verschiebt die Provinzen nach rechts - private final int Y_OFFSET = 0; // Verschiebt die Provinzen nach unten - - /* - Die einzelnen Positionen der Provinzen wird mit SCALE_VALUE/10000 multipliziert. - Dies ist nützlich, wenn die Karte beispielsweise nur noch 80% der Originalgröße bei ihrer Darstellung groß ist. - Bei diesem Beispiel wäre hier, neben dem Offset oben, der Wert 0.8 einzutragen. - */ - private final double SCALE_VALUE = 1; - - protected Province[] provinces; - protected Player[] players; - - protected int currentPlayer = 0; - - /** - Erstellt eine GeneralMap mit allen Eigenschaften und initialisiert die Arrays für Provinzen und Spieler. - @param backImage Das Hintergrundbild, welches von dieser Klasse geladen und dargestellt wird. - @param playerList Die Liste mit den Namen der Spieler - @param colorList Die Liste mit den Farben der Spieler - */ - public GeneralMap(String backImage, String[] playerList, int[] colorList) - { + /* + Felder, im Moment nur Anzahl der Provinzen + Später evtl. weitere Werte wie Schwierigkeit denkbar + */ + + private final int X_OFFSET = 160; // Verschiebt die Provinzen nach rechts + private final int Y_OFFSET = 0; // Verschiebt die Provinzen nach unten + + /* + Die einzelnen Positionen der Provinzen wird mit SCALE_VALUE/10000 multipliziert. + Dies ist nützlich, wenn die Karte beispielsweise nur noch 80% der Originalgröße bei ihrer Darstellung groß ist. + Bei diesem Beispiel wäre hier, neben dem Offset oben, der Wert 0.8 einzutragen. + */ + private final double SCALE_VALUE = 1; + + protected enum GameStates { + KAMPF, + VERSCHIEBEN + } + + protected Province[] provinces; + protected Player[] players; + + protected int currentPlayer = 0; + protected GameStates status = GameStates.VERSCHIEBEN; + + Province offenderProvince; + Province defenderProvince; + + Province savedProvince = null; + + /** + Erstellt eine GeneralMap mit allen Eigenschaften und initialisiert die Arrays für Provinzen und Spieler. + @param backImage Das Hintergrundbild, welches von dieser Klasse geladen und dargestellt wird. + @param playerList Die Liste mit den Namen der Spieler + @param colorList Die Liste mit den Farben der Spieler + */ + public GeneralMap(String backImage, String[] playerList, int[] colorList) + { super(1600,900,1); - players = new Player[playerList.length]; - for (int i = 0; i < playerList.length; i++) { - players[i] = new Player(i,playerList[i],colorList[i]); - } + players = new Player[playerList.length]; + for (int i = 0; i < playerList.length; i++) { + players[i] = new Player(i,playerList[i],colorList[i]); + } createPlayerObjects(playerList.length); - } + } private void createPlayerObjects(int playerCount) { @@ -71,97 +85,260 @@ public abstract class GeneralMap extends World { addObject(players[5],1512,350); - } - } - } - } - } - } - - /** - Fügt alle Provinzen aus dem Array der Welt an der entsprechden Stelle zu. - */ - protected void initProvinces() { - for(int i = 1; i < provinces.length; i++) { - addObject(provinces[i],((int) Math.floor(provinces[i].getXPos() * SCALE_VALUE)) + X_OFFSET,((int) Math.floor(provinces[i].getYPos() * SCALE_VALUE)) + Y_OFFSET); - } - } - - /** - Gibt die Anzahl der vorhandenen Spieler aus. - */ - public int getPlayerCount() - { - return players.length; - } - - /** - Gibt den Namen des aktuellen Spielers aus. - @return Der Name des aktuellen Spielers - */ - public String getPlayerName() - { - return players[currentPlayer].getDisplayName(); - } - - /** - Gibt den Namen des Spielers aus, dem dessen ID gehört. - @param plID Die ID des zu findenden Spielers - @return Der Name des Spielers - */ - public String getPlayerName(int plID) - { - return players[plID].getDisplayName(); - } - - /** - Gibt die Anzahl der Sterne des aktuellen Spielers zurück. - @return Die Anzahl der Sterne des aktuellen Spielers - */ - public int getPlayerStars() - { - return players[currentPlayer].getStars(); - } - - /** - Gibt die ID des Spielers zurück, dem die gefragte Provinz gehört. - @param prID Die gefragte Provinz - */ - public int getProvinceOwner(int prID) - { - if(prID < 1 || prID > provinces.length) { - return -1; - } - return provinces[prID].getOwner(); - } - - /** - Gibt eine Liste mit allen Provinzen und deren Besitzern zurück. - @return Array mit der Provinz-ID als Index und dem Besitzer als Wert - */ - public int[] getProvinceOwners() - { - int[] prOwners = new int[provinces.length]; - for (int i = 1; i > provinces.length; i++) { - prOwners[i] = provinces[i].getOwner(); - } - return prOwners; - } - - /** - Zählt die Anzahl der Einheiten von allen Provinzen zusammen, die einem bestimmten Spieler gehört. - @param playerID Die ID des Spielers, für den die Einheiten gezählt werden sollen. - @return Die Anzahl der Einheiten, die dem Spieler gehören. - */ - public int getProvinceEntityCount(int playerID) - { - int c = 0; - for (int i = 1; i > provinces.length; i++) { - if(provinces[i].getOwner() == playerID) { - c = c + provinces[i].getEntityCount(); - } - } - return c; - } + } + } + } + } + } + } + + /** + Fügt alle Provinzen aus dem Array der Welt an der entsprechden Stelle zu. + */ + protected void initProvinces() { + for(int i = 1; i < provinces.length; i++) { + addObject(provinces[i],((int) Math.floor(provinces[i].getXPos() * SCALE_VALUE)) + X_OFFSET,((int) Math.floor(provinces[i].getYPos() * SCALE_VALUE)) + Y_OFFSET); + } + } + + public void act() { + if(status == GameStates.KAMPF) { + if(offenderProvince == null) + { + OffenderProvince(); + } + else + { + defenderProvince(); + } + } else if(status == GameStates.VERSCHIEBEN) { + Province clickedProvince; + + for ( int i = 1; i <= (provinces.length - 1); i++) + { + if (provinces[i].hasClicked() == true) + { + clickedProvince = provinces[i]; + useProvincesToMove(clickedProvince); + break; + } + } + } + } + + /** + Gibt die Anzahl der vorhandenen Spieler aus. + */ + public int getPlayerCount() + { + return players.length; + } + + /** + Gibt den Namen des aktuellen Spielers aus. + @return Der Name des aktuellen Spielers + */ + public String getPlayerName() + { + return players[currentPlayer].getDisplayName(); + } + + /** + Gibt den Namen des Spielers aus, dem dessen ID gehört. + @param plID Die ID des zu findenden Spielers + @return Der Name des Spielers + */ + public String getPlayerName(int plID) + { + return players[plID].getDisplayName(); + } + + /** + Gibt die Anzahl der Sterne des aktuellen Spielers zurück. + @return Die Anzahl der Sterne des aktuellen Spielers + */ + public int getPlayerStars() + { + return players[currentPlayer].getStars(); + } + + /** + Gibt die ID des Spielers zurück, dem die gefragte Provinz gehört. + @param prID Die gefragte Provinz + */ + public int getProvinceOwner(int prID) + { + if(prID < 1 || prID > provinces.length) { + return -1; + } + return provinces[prID].getOwner(); + } + + /** + Gibt eine Liste mit allen Provinzen und deren Besitzern zurück. + @return Array mit der Provinz-ID als Index und dem Besitzer als Wert + */ + public int[] getProvinceOwners() + { + int[] prOwners = new int[provinces.length]; + for (int i = 1; i > provinces.length; i++) { + prOwners[i] = provinces[i].getOwner(); + } + return prOwners; + } + + /** + Zählt die Anzahl der Einheiten von allen Provinzen zusammen, die einem bestimmten Spieler gehört. + @param playerID Die ID des Spielers, für den die Einheiten gezählt werden sollen. + @return Die Anzahl der Einheiten, die dem Spieler gehören. + */ + public int getProvinceEntityCount(int playerID) + { + int c = 0; + for (int i = 1; i > provinces.length; i++) { + if(provinces[i].getOwner() == playerID) { + c = c + provinces[i].getEntityCount(); + } + } + return c; + } + + public void buttonClicked(Button b) { + if(status == GameStates.KAMPF) { + status = GameStates.VERSCHIEBEN; + } else if(status == GameStates.VERSCHIEBEN) { + status = GameStates.KAMPF; + currentPlayer++; + if(currentPlayer >= players.length) { + currentPlayer = 0; + } + } + } + + // Kampfsystem + + private void OffenderProvince() + { + for ( int i = 1; i <= (provinces.length - 1); i++) + { + if (provinces[i].hasClicked() == true) + { + offenderProvince = provinces[i]; + System.out.println("1"); + } + } + } + + private void defenderProvince() + { + { + for (int i = 1; i <= (provinces.length - 1); i++) + { + if (provinces[i].hasClicked() == true)//&& defenderProvince != offenderProvince) + { + defenderProvince = provinces[i]; + System.out.println("2"); + chooser(); + break; + } + } + } + } + + private void chooser() + { + Dice_Offender diceOffender = new Dice_Offender(); + int[] maxDiceOffender = diceOffender.max_offender(offenderProvince.getEntityCount()); + Dice_Defender diceDefender = new Dice_Defender(); + int[] maxDiceDefender = diceDefender.max_defender(defenderProvince.getEntityCount()); + Arrays.sort(maxDiceOffender); + Arrays.sort(maxDiceDefender); + decider(maxDiceOffender, maxDiceDefender); + } + + private void decider(int[] maxDiceOffender, int [] maxDiceDefender) + { + int maxDefender = maxDiceDefender[1]; + int maxOffender = maxDiceOffender[2]; + if (maxOffender>maxDefender && defenderProvince.getEntityCount()>1) + { + int EntitiesOffender = offenderProvince.getEntityCount(); + int EntitiesDefender = defenderProvince.getEntityCount(); + defenderProvince.setEntityCount(EntitiesDefender - 1); + } + + if (maxOffender1) + { + int EntitiesOffender = offenderProvince.getEntityCount(); + int EntitiesDefender = defenderProvince.getEntityCount(); + offenderProvince.setEntityCount(EntitiesOffender - 1); + } + + if (maxOffender>maxDefender && defenderProvince.getEntityCount()==1) + { + defenderProvince.setOwner(offenderProvince.getOwner()); + defenderProvince.setEntityCount(0); + } + + if (maxOffender>maxDefender && offenderProvince.getEntityCount()==1) + { + offenderProvince.setOwner(defenderProvince.getOwner()); + offenderProvince.setEntityCount(0); + } + System.out.println("3"); + offenderProvince = null; + defenderProvince = null; + } + + // Einheiten verschieben + + /** + * Nimmt zwei Provinzen entgegen, und fragt, wieviele Einheiten vom ersten zum zweiten Eintrag verschoben werden sollen. + * Überprüft, ob eine Verschiebung möglich ist und führt sie bei Erfolg aus. + */ + private void moveEntities(Province sourceProvince, Province destinationProvince) + { + String toMoveString = JOptionPane.showInputDialog(null, "Wieviele Einheiten willst du verschieben?"); + int entitiesToMove = Utils.StringToInt(toMoveString); + + if (entitiesToMove == 0) { + JOptionPane.showMessageDialog(null,"Bitte eine Zahl eingeben, Kommandant " + getPlayerName() + "."); + return; + } + + if ( (sourceProvince.getEntityCount() - entitiesToMove) > 0) + { + sourceProvince.removeFromEntities(entitiesToMove); + destinationProvince.addToEntities(entitiesToMove); + JOptionPane.showMessageDialog(null,"Einheiten erfolgreich verschoben, Kommandant " + getPlayerName() + "."); + } + + else if ( (sourceProvince.getEntityCount() - entitiesToMove) <= 0) + { + JOptionPane.showMessageDialog(null,"Du hast nicht genügend Einheiten, um die gewünschte Anzahl von " + sourceProvince.getDisplayName() + " nach " + destinationProvince.getDisplayName() + " zu verschieben, Köhler."); + } + } + + /** + * Speichert ein gegebene Provinz als savedProvince ein, insofern dieser Platz nicht bereits belegt ist. + * Ist er das, so wird überprüft, ob eine neue, an savedProvince angrenzende Provinz angeklickt wurde. + * Ist dies der Fall, werden beide Provinzen an moveEntities übergeben. + */ + private void useProvincesToMove(Province givenProvince) + { + if (savedProvince == null) + { + savedProvince = givenProvince; + } + + else if ((savedProvince != null) && (givenProvince != savedProvince) && (savedProvince.getOwner() == givenProvince.getOwner()) && (savedProvince.getOwner() == currentPlayer) ) + { + if (givenProvince.isProvinceNear(savedProvince.getID()) == true) + { + moveEntities(savedProvince,givenProvince); + } + savedProvince = null; + } + } } diff --git a/Utils.java b/Utils.java index cb9680a..ebfadc3 100644 --- a/Utils.java +++ b/Utils.java @@ -3,73 +3,83 @@ import java.awt.Color; import java.util.*; /** - Diese Klasse enthält nur statische Funktionen, welche für euch als Unterstützung gedacht sind. Damit könnt ihr dann hoffentlich viele Code-Zeilen sparen. :) +Diese Klasse enthält nur statische Funktionen, welche für euch als Unterstützung gedacht sind. Damit könnt ihr dann hoffentlich viele Code-Zeilen sparen. :) - @author Zocker1999_NET - @version 15.06.2016 +@author Zocker1999_NET +@version 15.06.2016 */ public final class Utils { - - /** - Kopiert ein boolean-Array und übergibt diese. - @param a Das zu kopierende Array - @return Die Kopie des Arrays - */ - public static boolean[] copyArray(boolean[] a) { - boolean[] b = new boolean[a.length]; - for(int i = 0; i < a.length; i++) { - b[i] = a[i]; - } - return b; - } - /** - Kopiert ein int-Array und übergibt diese. - @param a Das zu kopierende Array - @return Die Kopie des Arrays - */ - public static int[] copyArray(int[] a) { - int[] b = new int[a.length]; - for(int i = 0; i < a.length; i++) { - b[i] = a[i]; - } - return b; - } - /** - Kopiert ein String-Array und übergibt diese. - @param a Das zu kopierende Array - @return Die Kopie des Arrays - */ - public static String[] copyArray(String[] a) { - String[] b = new String[a.length]; - for(int i = 0; i < a.length; i++) { - b[i] = a[i]; - } - return b; - } - - /** - Zeichnet innerhalb eines GreenfootImage ein gefülltes Rechteck in der gegebenen Farbe und mit dem gegebenen Abstand zum Rand. - @param i Das GreenfootImage, in dem gezeichnet werden soll. - @param c Die Farbe, in der das gefüllte Rechteck gezeichnet werden soll. - @param b Der Abstand zum Rand der Grafik. - */ - public static void drawInsideRectangle(GreenfootImage i, Color c, int b) { - int sx = i.getWidth(); - int sy = i.getHeight(); - i.setColor(c); - i.fillRect(b,b,sx-(2*b),sy-(2*b)); - } - - /** - Sortiert ein int[]-Array absteigend. - @param a Das zu sortierende Array - */ - public static void sortDesc(int[] a) { - Arrays.sort(a); - int[] b = copyArray(a); - for(int i = (a.length - 1); i >= 0; i--) { - a[i] = b[i]; - } - } + /** + Kopiert ein boolean-Array und übergibt diese. + @param a Das zu kopierende Array + @return Die Kopie des Arrays + */ + public static boolean[] copyArray(boolean[] a) { + boolean[] b = new boolean[a.length]; + for(int i = 0; i < a.length; i++) { + b[i] = a[i]; + } + return b; + } + + /** + Kopiert ein int-Array und übergibt diese. + @param a Das zu kopierende Array + @return Die Kopie des Arrays + */ + public static int[] copyArray(int[] a) { + int[] b = new int[a.length]; + for(int i = 0; i < a.length; i++) { + b[i] = a[i]; + } + return b; + } + + /** + Kopiert ein String-Array und übergibt diese. + @param a Das zu kopierende Array + @return Die Kopie des Arrays + */ + public static String[] copyArray(String[] a) { + String[] b = new String[a.length]; + for(int i = 0; i < a.length; i++) { + b[i] = a[i]; + } + return b; + } + + /** + Zeichnet innerhalb eines GreenfootImage ein gefülltes Rechteck in der gegebenen Farbe und mit dem gegebenen Abstand zum Rand. + @param i Das GreenfootImage, in dem gezeichnet werden soll. + @param c Die Farbe, in der das gefüllte Rechteck gezeichnet werden soll. + @param b Der Abstand zum Rand der Grafik. + */ + public static void drawInsideRectangle(GreenfootImage i, Color c, int b) { + int sx = i.getWidth(); + int sy = i.getHeight(); + i.setColor(c); + i.fillRect(b,b, sx-(2*b),sy-(2*b)); + } + + /** + Sortiert ein int[]-Array absteigend. + @param a Das zu sortierende Array + */ + public static void sortDesc(int[] a) { + Arrays.sort(a); + int[] b = copyArray(a); + for(int i = (a.length - 1); i >= 0; i--) { + a[i] = b[i]; + } + } + + public static int StringToInt(String s) { + int i = 0; + try { + Integer in = Integer.valueOf(s); + i = in; + } catch (java.lang.NumberFormatException e) {} + return i; + } }