package nl.sogyo.mancala.domein; public class Kom { private int aantalStenen; private Speler eigenaar; private Kom volgendeKom; /** * Maak een nieuwe kom aan. * * @param eigenaar * @param aantalStenenPerKom */ protected Kom(Speler eigenaar, int aantalStenenPerKom) { this(eigenaar, 0, aantalStenenPerKom); } /** * Maak een nieuwe kom aan. * * @param eigenaar * @param aantalKommen * @param aantalStenenPerKom */ public Kom(Speler eigenaar, int aantalKommen, int aantalStenenPerKom) { this.eigenaar = eigenaar; this.aantalStenen = aantalStenenPerKom; aantalKommen--; if (aantalKommen > 0) { this.volgendeKom = new Kom(eigenaar, aantalKommen, aantalStenenPerKom); } else if (aantalKommen == 0) { this.volgendeKom = new Kalaha(eigenaar); } } /** * @return het aantal stenen */ protected int getAantalStenen() { return aantalStenen; } /** * @return de eigenaar van deze kom */ public Speler getEigenaar() { return this.eigenaar; } /** * Voeg een aantal stenen toe aan deze kom. * * @param aantal aantal stenen dat toegevoegd moet worden */ protected void voegStenenToe(int aantal) { this.aantalStenen += aantal; } /** * @return de volgende kom, relatief vanaf deze kom */ public Kom getVolgendeKom() { return this.volgendeKom; } /** * @param volgendeKom de volgende kom, relatief vanaf deze kom */ public void setVolgendeKom(Kom volgendeKom) { this.volgendeKom = volgendeKom; } /** * @return de kom tegenover deze kom */ public Kom getTegenoverliggendeKom() { return this.getKalaha().getVolgendeKom().getKom(this.getDistanceToKalaha()); } /** * @return de afstand tot de Kalaha, relatief vanaf deze kom */ public int getDistanceToKalaha() { return 1 + this.volgendeKom.getDistanceToKalaha(); } /** * @return de Kalaha van deze helft van het bord */ public Kalaha getKalaha() { return this.volgendeKom.getKalaha(); } /** * @param nummer het volgnummer van de gewenste kom, relatief vanaf de deze kom * @return de opgevraagde kom */ public Kom getKom(int nummer) { if (nummer == 1) { return this; } else { int nieuwNummer = nummer - 1; return this.volgendeKom.getKom(nieuwNummer); } } /** * Voer een zet uit op deze kom. */ public void doeZet() { if (!this.kanZetten()) { throw new IllegalStateException("Deze kom kan niet gezet worden."); } else { int stenenVoorZet = this.aantalStenen; this.aantalStenen = 0; this.volgendeKom.geefDoor(stenenVoorZet); } } /** * Neem een steen van het meegegeven 'stapeltje' en geef de rest door. * Als er geen stenen meer over zijn om door te geven, roep 'eindeZet' aan. * * @param aantalStenen */ protected void geefDoor(int aantalStenen) { aantalStenen--; this.aantalStenen++; if (aantalStenen > 0) { this.volgendeKom.geefDoor(aantalStenen); } else { this.eindeZet(); } } /** * Voer de actie uit die bij het einde van een zet hoort. */ protected void eindeZet() { if (this.kanSlaan()) { this.sla(); } this.eigenaar.wisselBeurt(); } /** * @return of er op deze kom een zet uitgevoerd kan worden */ public boolean kanZetten() { return this.eigenaar.isAanDeBeurt() && this.aantalStenen > 0; } /** * @return of de eigenaar van deze kom een zet kan doen */ public boolean kanEigenaarZetten() { return this.kanZetten() || this.volgendeKom.kanEigenaarZetten(); } /** * @return of de huidige stand voldoet aan de 'slaan conditie' */ private boolean kanSlaan() { return this.eigenaar.isAanDeBeurt() && this.aantalStenen == 1; } /** * Voer een slag uit op deze kom. */ private void sla() { this.geefStenenAanKalaha(this.getKalaha()); this.getTegenoverliggendeKom().wordtGeslagen(); } /** * Voer de actie uit die hoort bij 'geslagen worden'. */ private void wordtGeslagen() { this.geefStenenAanKalaha(this.getTegenoverliggendeKom().getKalaha()); } /** * Geef de stenen van deze kom aan de meegegeven Kalaha. * * @param kalaha de Kalaha waar de stenen aan gegeven moeten worden */ private void geefStenenAanKalaha(Kalaha kalaha) { kalaha.voegStenenToe(this.aantalStenen); this.aantalStenen = 0; } /** * Geef de stand relatief vanaf deze kom in het volgende formaat: * "<#stenenKom1>|<#stenenKom2>|...|<#stenenKomN>|<#stenenKalaha>". * * @return de stand als String */ public String getStand() { return this.getAantalStenen() + "|" + this.volgendeKom.getStand(); } /** * @return het aantal stenen van de eigenaar, relatief vanaf deze kom. */ public int getAantalStenenEigenaar() { return this.aantalStenen + this.volgendeKom.getAantalStenenEigenaar(); } }