Archief - [PROG]JAVA ganzenbord

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

gamer1

Legacy Member
Ik heb bij het maken van het spel ganzenbord aparte classes voorzien voor:
kleur, positie
pion
het ganzenbord zelf
dobbelsteen
beurt spelen (moet ik nog schrijven)
(mss nog een overkoepelende nodig voor het gehele spel)

Op zon ganzenbord zijn er een heel hoop vakjes. Nu zijn der ook speciale vakjes, waar ge een beurt moet overslaan of terug naar start, of nog eens gooien ed.
Waar kan ik dan het beste de code voor die vakjes schrijven? Kan ik dan best een aparte class SpecialeVakjes extends Positie ofzo make? Of beter ze bijvoegen bij de class voor het bord of een andere?

NecroNeo

Legacy Member
ik zou gewoon aan uw ganzenbord class, een lijst hangen van vakjes die een type hebben. (ben wel vrij onbekend met java, maar in c# zou ik het zo dus maken zal wel geen fundamenteel verschil zijn) En dan laat je de spelclasse kijken op welk soort vak de pion terechtkomt en gepast reageren.

gamer1

Legacy Member
Dus dan in class Ganzenbord, onder de code van de gewone vakjes [benoemd dmv een for lus met teller i] een lijstje met voorwaarden maken [if (i == 19) then overslaan()] en dan onder heel die lijst zo de verschillende void's [bv void overslaan()]?

NecroNeo

Legacy Member
heb je een class voor je vakjes ?

wat ik zou doen is in die vakjes classe een type toevoegen vb normal, skip, return...

Komt je pion op een vakje ga je kijken welk type het vakje heeft en gepast reageren.

QplQyer

Legacy Member
Of je maakt een constructor voor alle vakjes waarin je de positieverandering meegeeft. Bijvoorbeeld voor een gewoon vakje geef je "0" mee, voor een terugkeren vakje "-1", etc. Elke keer iemand verplaatst, controleer je hoe de positie verandert door zijn positie op te tellen bij de positieVeranderingswaarde van dat vakje en wordt dat zijn nieuwe positie.

Dus in pseudocode: nieuwePositie = oudePositie + dobbelsteenWaarde + spelbord[oudePositie+dobbelsteenWaarde].getPositieVerandering()

Tenzij er nog andere vakjes zijn die iets anders doen dan de positie veranderen, ganzenbord is nogal lang geleden.

gamer1

Legacy Member
PHP:
public Ganzenbord()
	{	for (int i=1;i<=63;i++)
		vakje[i] = new Positie(this,i);
		
		if (i==19) overslaan(); else
		if (i==42) gaNaar39(); else
		if (i==58) gaNaar1(); else
		if (i==63) stop();
	}


	void overslaan()
	{
	}
	void gaNaar39()
	{
	}
	void gaNaar1()
	{
	}
	void stop()
	{
	}
}
Moge die void methodes(overslaan,gaNaar1,...) ook in een andere class uitgewerkt worden, of moet da in deze class?

maxdevis

Legacy Member
of je werkt met overerving
de classen gewoon vakje, overslaan terug naar start,...
erven allemaal van vakje
en dan moet je maar telkens 1 method aanroepen bv doe()

tis maar een idee van een beginneling

gamer1

Legacy Member
Ik heb dus een class Ganzenbord (zie mn post hierboven) en een class Positie:
PHP:
public class Positie
{	public final int x;										
	public final Ganzenbord bord;

	public Positie();										
	{	x = 1;
	}
	public Positie(Ganzenbord b,int xPos);	
	{	bord = b;
		x = xPos;
	}
	public void zet(Pion s)									
	{ 	
	}
}

Dan heb ik ook nog een class Pion:
PHP:
public class Pion
{	public final Kleur kleur;								
	protected Positie pos;									
	
	public Pion(Kleur k,Positie positie)		
	{	kleur = k;
		pos = positie;		
	}
	public void verplaatsNaar(Positie p)		
	{ 
	}
}

Hoe kan ik dan best de methodes verplaatsNaar en zet invulle? Heb hier al zoveel op ligge klommele, ma vind nix wa gaat. Ik moet dus na de worp mn pion late verplaatse, zoveel als aangegeve met de dobbelsteen (dus huidige positie + som van de 2 stenen, hierna moet huidige positie vervange worde door de nieuwe positie).
Als iemand een beter idee heeft, door bv die class positie weg te late en de class ganzenbord en pion aan te passe, mag da natuurlijk ook. Dit model is zowa analoog aan da voor t schaakbord in onze cursus.

Timmos

Legacy Member
Je declareert je variable 'x' als een final. Aangezien die moet veranderen is het niet goed dat je 'final' opneemt in je declaratie.

Ten tweede is je veld 'x' public gedeclareerd en dat is op zich geen syntaxfout maar een zeer slechte programmeerstijl in Java. Velden moet je in 99% van de gevallen private maken.

Ten derde, als gevolg van het tweede, kan je velden (die dus private zijn) enkel benaderen met een accessormethode in de klasse waarin dat veld is gedeclareerd.

Het lijkt mij het best dat ge gewoon de klasse Positie verwijdert en ge uw positie bijhoudt per pion (dus 'x' hebt ge nergens meer nodig). Da's vrij logisch want iedere Pion heeft een positie he. En kleur zou ik ook in Pion zetten.

Een klasse Positie en Kleur is nogal vreemd, omdat ge nooit in het echte leven een 'kleur' of een 'positie' aanmaakt, dat zijn eigenschappen van iets anders. Maar ik zal kleur voorlopig negeren.

Code:
public class Pion
{
    public final Kleur kleur;
    protected int positie;

    public Pion (Kleur kleur, int positie){
         this.kleur = kleur;
         this.positie = positie;
    }

    public void verplaatsNaar (int nieuwePositie){
        positie = nieuwePositie;
    }
}


public void verplaatsNaar (int positie){

gamer1

Legacy Member
Timmos zei:
Je declareert je variable 'x' als een final. Aangezien die moet veranderen is het niet goed dat je 'final' opneemt in je declaratie.

Ten tweede is je veld 'x' public gedeclareerd en dat is op zich geen syntaxfout maar een zeer slechte programmeerstijl in Java. Velden moet je in 99% van de gevallen private maken.

Ten derde, als gevolg van het tweede, kan je velden (die dus private zijn) enkel benaderen met een accessormethode in de klasse waarin dat veld is gedeclareerd.

Het lijkt mij het best dat ge gewoon de klasse Positie verwijdert en ge uw positie bijhoudt per pion (dus 'x' hebt ge nergens meer nodig). Da's vrij logisch want iedere Pion heeft een positie he. En kleur zou ik ook in Pion zetten.

Een klasse Positie en Kleur is nogal vreemd, omdat ge nooit in het echte leven een 'kleur' of een 'positie' aanmaakt, dat zijn eigenschappen van iets anders. Maar ik zal kleur voorlopig negeren.

Code:
public class Pion
{
    public final Kleur kleur;
    protected int positie;

    public Pion (Kleur kleur, int positie){
         this.kleur = kleur;
         this.positie = positie;
    }

    public void verplaatsNaar (int nieuwePositie){
        positie = nieuwePositie;
    }
}


public void verplaatsNaar (int positie){

En dan moet ik nieuwePositie=positie+som //=som van de dobbelsteenworpen
in die methode verplaatsnaar zette of beter in SpelTest declarere en tusse de haakskes van de methode zette? Kan ik die som wat ik in SpelTest gebruik hier overnemen?

Hoe moet ik dan de class ganzenbord aanpasse? Gewoon overal Positie weg en daar int's van make?

Dit is de class speltest:

PHP:
public class SpelTest
{  public static void main(String[] args)					
	{  Ganzenbord b = new Ganzenbord();
	
	    Dobbelsteen ds1 = new Dobbelsteen();
  	    Dobbelsteen ds2 = new Dobbelsteen();

	    Pion s1 = new Pion(Kleur.ROOD,1);
	    //Pion s2 = new Pion(Kleur.BLAUW,1);
		
	    int worp1 = ds1.werp();
   	    int worp2 = ds2.werp();
  	    int som = worp1+worp2;
   	    System.out.println("Ik heb juist " + worp1 + " en " + worp2 + " geworpen! Dit is samen: "+som);

 	    s1.verplaatsNaar (b.vakje[i+som]);
 	    i=i+som;
	}
}

jodeman

Legacy Member
Houd de logica van uw spel in uw spel... Integreer die dobbelstenen in ganzenbord en maak iets als 'playermove' ofzo.

Timmos

Legacy Member
De indeling van uw klassen trekt inderdaad, excuseer mij, op niets.

Ik zou een klasse Spel maken, de main klasse die een Ganzenbord aanmaakt in zijn constructor, die 1 of 2 instanties van Dobbelsteen aanmaakt, die x aantal instanties van Pion aanmaakt.

4 klassen dus. (Tenzij ge natuurlijk al een klasse hebt die grafisch werkt)

In Dobbelsteen hebt ge één veld nodig, van het type Random, met één constructor en één accessormethode om uw randomgetal op te halen.

In Pion houdt ge zowel de positie bij als uw kleur. Kleur geeft ge mee in de constructor en positie ook. In Pion maakt ge een methode die uw positie incremeert met het aantal ogen dat ge gooit met uw twee dobbelstenen.

In Spel maakt ge dan methodes zoals public int gooi() die nen dobbelsteen gooit en de waarde teruggeeft. Een andere methode zoals public void zetPion(Pion pion) verzet dan de pion volgens het aantal ogen dat ge gooit.

...zo bouwt ge verder.

Timmos

Legacy Member
Code:
public class Spel
{
    private Ganzenbord spelbord;
    private Dobbelsteen teerling1, teerling2;
    private Pion[] pionnen;
    private int huidigPionNummer;
    private String[] kleuren = {"Rood", "Blauw", "Geel", "Groen"};
    
    public Spel (int aantalPionnen){
        if (aantalPionnen < 1) aantalPionnen = 1;
        if (aantalPionnen > 4) aantalPionnen = 4;
        
        spelbord = new Ganzenbord();
        teerling1 = new Dobbelsteen();
        teerling2 = new Dobbelsteen();
        pionnen = new Pion[aantalPionnen];
        
        for (int i = 0; i < aantalPionnen; i++){
            pionnen[i] = new Pion(kleuren[i]);
        }
        huidigPionNummer = 1;
    }
    
    public Pion geefHuidigePion (){
        return pionnen[huidigPionNummer];
    }
    
    public int getHuidigePionPositie (){
        return geefHuidigePion().getPositie();
    }
    
    public void verzetPion(){
       pionnen[huidigPionNummer].gaVooruit(teerling1.getOgen() + teerling2.getOgen());
       gaNaarVolgendePion();
    }

    public void gaNaarVolgendePion(){
        huidigPionNummer = (huidigPionNummer + 1)%pionnen.length;
    }
}
Code:
public class Pion
{
    private int positie;
    private String kleur;
    
    public Pion (String kleur){
        positie = 1;
        this.kleur = kleur;
    }
    
    public void gaVooruit(int aantalVakjes){
        positie += aantalVakjes;
    }
    
    public int getPositie (){
        return positie;
    }
        
}
Code:
import java.util.Random;

public class Dobbelsteen
{
    private Random rg;
    
    public Dobbelsteen (){
        rg = new Random();
    }
    
    public int getOgen(){
        return rg.nextInt(6) + 1;
    }
        
}
zo zou ik het doen, maar dit is zeker nog niet perfect. Maar ge houdt dus wel uw zaken gescheiden, dwz methodes die bij dobbelstenen horen gaat ge enkel en alleen implementeren in Dobbelsteen, en dus gaat ge gene Random gaan maken in Ganzenbord of Pion of whatever.

gamer1

Legacy Member
Om dan aan te geven dat ge als ge bv op vakje 42 komt ge terug moet naar 39. Moet ik da dan gewoon implementere in de class Spel? Na verzetPion bijvoorbeeld een paar if-constructies (mss eerst positie opvrage en dan pas if)?
Code:
public void verzetPion(){
       pionnen[huidigPionNummer].gaVooruit(teerling1.getOgen() + teerling2.getOgen());
       gaNaarVolgendePion();
    }

Timmos

Legacy Member
Dan zou ik u eerst aanraden om een implementatie te schrijven voor Ganzenbord (want dat heb ik nog niet gedaan), waar ge bijhoudt welke opdracht voor welk vakje dient. Bvb nen tabel van Strings met lengte = aantal vakskes, met op positie a, b, c en d (in die tabel) de string "drieVakkenAchteruit", of "gaNaarBegin", of ... .

Als ge in Spel dan de methode verzetPion oproept, dan voegt ge aan het einde van de body van die methode een statement toe dat zegt dat ge aan de instantie van Ganzenbord vraagt om te checken of er een opdracht nodig is (ge checkt of de String in de tabel gelijk is aan "drieVakkenAchteruit" of...).

bvb.

Code:
...
if (tabel[geefHuidigePionPositie()].equals("drieVakkenAchteruit")){
    pionnen[getHuidigePionPositie()] = geefHuidigePion().gaVooruit(-3);
}

gamer1

Legacy Member
Morge es probere. Merci voor de hulp alvast e! Iedereen trouwens.

tmagus

Legacy Member
opdract met een string is mss nie echt zo super...als dat er veel zijn is da ook wel nie echt leuk om te vergelijken..., mss best om daar een enum te gebruiker..

Extra Klasse aan vb SoortVak en dan maakte daar nen Enum van
met vb (3vooruit,3acteruit) en wa whatever ge nog wilt:p

if(veld.geefHuidigePositie().SoortVak == SoortVak.3vooruit)

waar bij dus geefhuidigepositie u een object vakje terug heeft...
is dan veel gemakkelijker om later uit te breiden, gewoon extra iets bij de enum en tis opgelost

natuurlijk kunde gewoon ook speciale vakjes maken...

dus klasse 3stappenvoorruit extends Vakje

en dan kunde in uw bord, als je vakjes ini, vb zeggen Vakje30 = new 3stappenvoorruit("naamvakjeofzo")

en dan kunde
if(veld.geefHuidigePositie().geefSoort() == 3stappenvoorruit.Class)

en geefSoort geeft dan de class terug van uw object Vakje

nuja my two cents

gamer1

Legacy Member
Zo, ik heb de veranderinge es doorgevoerd en probere iets te fabricere voor dubbelVooruit()/gaNaar39()/gaNaar1().
Als ge es zou wille kijke of da mag en kan zoals ik da gedaan heb. Ook staan er hier en daar vraagjes bij als commentaar(in class ganzenbord). Zou leuk zijn mocht iemand die ook ff wille beantwoorden. Ik vind persoonlijk dat het er al een stuk beter uitziet als in het begin.
Code:
package ganzenbordoef;

public class SpelTest
{
    private Ganzenbord spelbord;
    private Dobbelsteen teerling1, teerling2;
    private Pion[] pionnen;
    private int huidigPionNummer;
    private String[] kleuren = {"Rood", "Blauw", "Geel", "Groen"};
    
    public Spel (int aantalPionnen)
    {	if (aantalPionnen < 1) aantalPionnen = 1;
     	if (aantalPionnen > 4) aantalPionnen = 4;
        
     	spelbord = new Ganzenbord();
     	teerling1 = new Dobbelsteen();
     	teerling2 = new Dobbelsteen();
     	pionnen = new Pion[aantalPionnen];
        
     	for (int i = 0; i < aantalPionnen; i++)
     	{	pionnen[i] = new Pion(kleuren[i]);
     	}
     	huidigPionNummer = 1;
    }
    
    public Pion geefHuidigePion ()
    {	return pionnen[huidigPionNummer];
    }
   
    public int getHuidigePionPositie ()
    {	return geefHuidigePion().getPositie();
    }
    
    public void verzetPion()
    { pionnen[huidigPionNummer].gaVooruit(teerling1.getOgen() + teerling2.getOgen()); 
    	spelbord.controleerVakje();
    	gaNaarVolgendePion();
    }
    
    public void gaNaarVolgendePion()
    {	huidigPionNummer = (huidigPionNummer + 1)%pionnen.length;
    }
}

Code:
package ganzenbordoef;

public class Ganzenbord
{	int[] vakje = new int[63]
	
	public Ganzenbord()
	{	for (int i=1;i<=63;i++)
		vakje[i] = new int(i);
	}

	public void controleerVakje()	// moet ik i hiervoor bovenaan declarere?
	{	if (i==10) dubbelVooruit(); else   // kan ik hier zette:if i==11 of 21 of 31? 
		if (i==42) gaNaar39(); else
		if (i==58) gaNaar1(); 
	}
}

Code:
package ganzenbordoef;
import java.util.Random;

public class Dobbelsteen									
{  public int getOgen()											
   {  Random willekeurig = new Random();        
      int worp = willekeurig.nextInt(6) + 1;    
      return worp;
   }
}

Code:
package ganzenbordoef;

public class Pion
{  private String kleur;							
   private int positie;									
	
   public Pion(String kleur,int positie)			
   {  this.kleur = kleur;
        this.positie = positie;		
   }
	
   public void gaVooruit(int aantalVakjes)
   {  positie += aantalVakjes;
   }
    
   public int getPositie ()
   {  return positie;
   }
	
   public void dubbelVooruit()
   {  positie += aantalVakjes;
   }
   public void gaNaar39()
   {  positie = 39;
   }
   public void gaNaar1()
   {  positie = 1;
   }
}

Dit zijn dus alle classes, kleur en positie heb ik weggelaten op aanraden van verschillende mense.

Timmos

Legacy Member
owkeey... ik merk toch een paar vreemde dingen.

1) int i = new int (i) :wtf: ik denk dat je bedoelt: int i = new Integer (i), de wrapperklasse van int. Alhoewel dit heb je toch niet nodig, want ints kunnen in een Array opgeslaan worden zonder eerst te wrappen. Dus dit wordt: vakje = i;

2) i moet inderdaad gedeclareerd worden. i zou infeite de positie van ne Pion moeten zijn. Dus ik vraag mij af van waar die i komt. Beter zou zijn dat je na het verzetten van je Pion ergens een methode in Pion aanroept die verwijst naar die controleermethode, en daarbij als parameter meegeeft wat zijn huidige positie is.

3) Bij een if kan je inderdaad zeggen if (a == 1 || b == 2 || c == 3...), dus || betekent 'of'. && betekent 'en'. ! betekent 'niet'.

4) Bij je dobbelsteen heb je geen constructor, ik zou je toch aanraden om je Random variabele als een veld te declareren en niet als een dummy in je methode. Op die manier wordt 'een dobbelsteen' veel te veel aangemaakt en vernietigd en bezorg je de pc meer werk dan nodig is. Niet dat je het merkt bij dit simpel ding, maar toch, voor later moet je onthouden dat ge zulke dingen niet moogt doen. Dus declareer ne random en construct die dan in uw constructor. In je methode getOgen() verwijder je dan de declaratie.

QplQyer

Legacy Member
-Moet public Spel (...) niet public SpelTest (...) zijn? Ik ga er toch vanuit dat je dat als constructor gebruikt, indien niet, maak er dan een constructor van.
-Een array initialiseren met de index als waarde, dat lijkt me nutteloos.
Je gebruikt een array door hem te indexeren, dus heb je een index nodig. Op het moment dat je je index hebt, heb je echter onmiddellijk je waarde uit je array zonder dat je de array nodig hebt gehad. Die array is dus overbodig.

De klasse spelbord zou er beter zo uitzien imo:

Code:
public class Spelbord {
         TreeMap posities;
         
         public Spelbord () {
                  posities.add("Rood",1);
                  posities.add("Blauw",1);
                  posities.add("Groen",1);
                  posities.add("Geel",1);
         }
         // @param stappen De waarde van de dobbelsteenworp
         public void verzetPion (int stappen, String kleur) {
                  // Natuurlijk niet vergeten controleren of hij niet voorbij 60 ofzo zit
                  int nieuwePositie = posities.get(kleur)+stappen;
                  posities.put(kleur,controleerPositie (nieuwePositie));
                  return;
         }
        
          public int controleerPositie (int positie) {
                   if (....)
                   return; // Return de nieuwe positie!
          }
}
Je vervangt best de kleuren die ik gehardcode heb door pion-instanties, als je dan een grafische voorstelling zou willen maken is dat gemakkelijker uit te breiden door enkel de pion-klasse uit te breiden. De posities zou ik echter wel enkel in de spelbord-klasse bijhouden (dmv de Map dus).
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan