OO-Java spelletje Virus

Status
Niet open voor verdere reacties.

Chrile

Gebruiker
Lid geworden
5 dec 2011
Berichten
6
Beste,

Voor school moet ik een spelletje maken in Java (MVC). Het spel dat ik moet ontwerpen heet virus. (Link: http://www.gameonly.com/nl/games/denk-games/spelen-game-virus-3-1257.htm of http://www.gameonly.com/nl/tags/tag-virus.htm). Het principe van virus is heel eenvoudig: je moet het virus over het hele speelveld verspreiden. Kies met de muis een van de kleuren. Je kunt echter alleen de kleuren kiezen die het virus (of de virussen) omgeven. Naargelang je keuze, zal het virus zich al dan niet verder verspreiden. Het doel is om het virus te verspreiden in zo min mogelijk beurten.

Het spel bestaat dus uit een spelbord met 20x20 vierkantjes. Aan de rechterkant van het bord moet men de verschillende kleuren kunnen selecteren. Ik heb gekozen voor een ArrayList met 20x20 vierkantjes. Mijn idee was dus om ieder vierkantje dat je ingenomen of veroverd hebt met het virus, toe te voegen aan een andere ArrayList met ingenomen vierkantjes.

Ik heb al van alles geprobeerd maar er komt maar geen schot in de zaak. Na veel zwoegen heb ik toch een aantal methodes kunnen definiëren maar niets noemenswaardig om het spel daadwerkelijk te kunnen spelen. Ook heb ik al een resem methodes gedefinieerd waarvan ik niet eens weet of ik ze nodig zal hebben. Echter door al die methodes zie ik door de bomen het bos niet meer; ik heb geen idee hoe ik ze moet samenbrengen.

Enkele methodes die ik al heb: Als ik een vierkantje aanklik, kan ik het van kleur veranderen, toevoegen aan een nieuwe ArrayList, nagaan of het vierkantje tot de ingenomen vierkantjes behoort. Ook kan ik aan elke van de omliggende vierkantjes de kleur vragen. Om het spelbord op te vullen met gekleurde vierkantjes wordt er willekeurig gekozen tussen vijf verschillende kleuren. Deze methodes zijn echter nog niet 100% foutvrij.

Mijn probleem is dus dat ik geen idee heb hoe ik de verschillende methodes moet samenbrengen om zo een goed lopend spel te bekomen. Hierbij vraag ik of iemand mij hierbij kan helpen. Tips of raad is altijd welkom! Ik ben namelijk geen held in OO-Java.

Met vriendelijke groet, en alvast bedankt!
 
Laatst bewerkt:
Goedemiddag,
Ik heb door je code heen gekeken en ben tot de conclusie gekomen dat je het te moeilijk voor jezelf gemaakt hebt.
Om je in de goede richting te sturen wat tips:

- In je Vierkantje class heb je een x aantal methods getVierkantje boven, get vierkantje en nog meer. Deze heb je eigenlijk niet nodig. De volgende fields zijn eigenlijk alleen maar nodig in je vierkantje class: x,y en Color.
- aangezien je een random kleur maakt op basis van een integer, is het handig deze int direct om te zetten naar een Color. Dit voorkomt onnodige checks zoals je in je View.teken() doet. De if methods voor het checken van de kleur kan je dus weglaten als je de kleur als in je vierkantje hebt.
mijn voorstel hiervoor:

[cpp]
public class HelperClass {

private static HashMap<Integer,Color> colorParser;

public static HashMap<Integer,Color> getColorParser(){

//init object if its null
if (colorParser == null){
initColorParser();
}

return colorParser;


}

//object init method
private static void initColorParser(){
colorParser = new HashMap<Integer,Color>();

//waarom niet gewoon Color.Yellow etc ?


/*
* 1 = yellow
* 2 = green
* 3 = blue
* 4 = orange
* 5 = purple
*/

colorParser.put(1, new Color(238,238,0));
colorParser.put(2, new Color(0,205,102));
colorParser.put(3, new Color(99,184,255));
colorParser.put(4, new Color(255,185,15));
colorParser.put(5, new Color(205,0,205));
}
}
[/cpp]


je kunt het dan op de volgende manier in je construct van vierkantje gebruiken:
[cpp]
private Color color;
public Vierkantje(int x, int y){
color = HelperClass.getColorParser().get(1+(int)(Math.random()*5));
}

[/cpp]

- Om het makkelijker voor je te maken zou ik gewoon een vast begin maken. Bijvoorbeeld gewoon links boven ? of maak een random begin.

-In je controller class doe je ook een aantal dingen die niet echt nodig zijn:
[cpp]
bord.maakGeselecteerdVierkantjeOranje(x,y);
bord.maakGeselecteerdVierkantjeGeel(x,y);
bord.maakGeselecteerdVierkantjePaars(x,y);
bord.maakGeselecteerdVierkantjeBlauw(x,y);
bord.maakGeselecteerdVierkantjeGroen(x,y);
[/cpp]

je controller class zou ik op de volgende manier opbouwen: Op het click event (aan de rechterkant van de grid). haal daar de kleur op. Stuur deze kleur + de x en y waardes naar een infect methode in je Spelbord class.

deze methode zorgt voor alle afhandeling van kleur + infecteren.

Dit kan je op de volgende manier doen:

maak een int counter in je eerste regel. deze counter wordt met 1 verhoogt als een vierkant geinfecteerd is. dit zorgt ervoor dat als je erdooorheen geittereerd bent je een check kan doen om te kijken of je klaar bent (counter == arraymetvierkantjes.getSize())
loop door alle vierkantjes heen op de volgende manier:
[cpp]

//kijk of huidige vierkant geselecteerd is. zo nee, kan deze geselecteerd worden.
if (vierkant.IsGeselecteerd() == false ){
if (vierkant[i + 1].isGeselecteerd()){
// nu weten we dat vierkant geinfecteerd kan worden als de kleur gelijk is (check met de kleur die je als parameter aan deze methode meegestuurd hebt
}
}
[/cpp]

dit zou voldoende moeten zijn om het werkend te maken, als je nog vragen hebt hoor ik het.

ps. vergeet niet al geinfecteerde vierkantjes, de huidige kleur te maken
 
Laatst bewerkt:
Beste,

Eerst en vooral, bedankt voor het antwoord.

Ik snap niet zoveel van de hulpklasse die u hebt ingevoerd maar dat hoeft op zich geen probleem te zijn. Het werkt perfect maar ik zie het voordeel niet tegenover de methode die ik reeds had.
- Het probleem met de kleuren heb ik aangepast.
- Ook heb ik een methode gemaakt die het begin bepaalt zoals u hebt aangegeven.
- De handvol methodes die ik in de controller had gezet waren vooral om die methodes te testen.

- Ik heb nog een aantal problemen bij de infectMethode. Ik heb dus een counter aangemaakt die wordt verhoogd als een vierkantje geïnfecteerd is.

- Maar bij de methode die u hebt gegeven zie ik nog altijd niet wat die precies doet. De arraylist met vierkantjes wordt dus overlopen. Indien er een is dat niet geselecteerd is weten we dus dat die geïnfecteerd kan worden. Als de kleur gelijk is als de gekozen kleur wordt het vierkantje geïnfecteerd. Of zie ik dat verkeerd? Kunt u dat nog eventueel nog een beetje toelichten? Ik heb namelijk geen idee hoe ik dat nu verder moet uitwerken.

In ieder geval bedankt voor de hulp!
 
Laatst bewerkt:
het voordeel van de hulpmethode die ik gemaakt heb (in een aparte klasse) zorgt er voor dat verantwoordelijkheid voor de kleur in de klasse zelf zit. Als je HBO informatica doet (of mbo maar dat weet ik niet ) dan zul je ongetwijfeld het vak design patterns gaan krijgen waarin dit verteld wordt. maargoed voer de methode:

De methode die ik je eerder voortelde is inderdaad niet helemaal correct, ik ben namelijk een curciaal onderdeel vergeten ^^ het feit dat onder het hokje ook een geinfecteerde cel kan zitten. Kortom om te kijken of een hokje geinfecteerd mag worden, moet de huidige niet geinfecteerd zijn maar een aangrenzend hokje wel (kijk hiervoor naar de volgende cel en de cel direct er onder (kan je met de index doen, met wat rekenwerk weet je in welke rij en colum je zit aan de hand van de index)).
 
Aangezien ik een ingenieursopleiding volg is het vak informatica(VBA en Java) niet zo uitdiepend als een hbo informatica natuurlijk.

Ok, ik denk dat ik snap wat u bedoelt. Dus om te kijken of een hokje geinfecteerd mag worden, moet het huidige niet geinfecteerd zijn maar een aangrenzend hokje moet wel geinfecteerd zijn. Dus als ik een rooster met 20x20 vierkantjes heb en als i het vierkantje is dat geinfecteerd moet worden dan moet(en):
(i-1)= het hokje ervoor,
(i+1)= het hokje erna,
(i-20)= het hokje erboven of
(i+20)= het hokje eronder
geinfecteerd zijn?

Of zie ik dat verkeerd?
 
Het gaat moeizaam vooruit maar ik heb toch een aantal methodes proberen te definiëren:

- Aangezien de methode die ik had gemaakt om random een beginvierkantje te selecteren niet werkt heb ik maar een vast vierkantje bepaald waar het spel begint, namelijk het vierkantje (0,0).

- In de methode infect heb ik nu een counter die het aantal geïnfecteerde vierkantjes telt en aangeeft wanneer het spel gedaan is.

- Verder heb ik nog een lus die alle vierkantjes nagaat. Indien een vierkantje niet geselecteerd is gaat die na of een van de omliggende vierkantjes geïnfecteerd is. Zo ja, dan wordt het vierkantje geïnfecteerd en geselecteerd.

- Als het vierkantje geselecteerd is, dan wordt er nagegaan of het dezelfde kleur heeft als het vierkantje erboven, eronder, ervoor en erachter. Indien dit zo is worden de geïnfecteerde vierkantjes in dezelfde kleur veranderd als het geselecteerde vierkantje.

- Indien men op het rooster rechts van het spelbord drukt, veranderen de geïnfecteerde vierkantjes naar de betreffende kleur.

Ik ben ook hier weer het overzicht verloren. Ik weet niet of de methodes wel goed geimplementeerd zijn en of ze wel werken. Ik weet ook niet wat de volgende stap is die ik moet volgen en hoe ik het moet linken aan de controller. En moet ik met parameters werken of niet?
 
Laatst bewerkt:
Er zijn in je infecteer methode een aantal dingen die niet helemaal goed gedaan zijn.

je itteratie bijvoorbeeld:

Code:
for (Vierkantje v : vierkantjes){
  int counter = 0;
  for (int i=0; i < vierkantjes.size(); i++){
     
  }

je creert nu een dubbele for lus. Waarom ? aangezien je niks met de foreach lus doet. vervolgens doe je ongeveer hetzelfde nog 2/3 keer. De check kan allemaal in een enkele for lus:

Code:
    public void infectMethode(int color){
    	
    	int counter = 0;
    	final int totalCells = vierkantjes.size();
    	
    	for (int i = 0 ; i < vierkantjes.size(); i++){    		
    		
    		//deze kan mogelijk geinfecteerd worden.  check op nog niet geinfecteerd en kleur
    		if (vierkantjes.get(i).isGeinfecteerd == false && vierkantjes.get(i).getKleur() == color){
    		
    			//nu checken of 1 van de neighbours geinfecteerd zijn.
    			
    			//out of bounds error voorkomen
    			if (i +1 <= vierkantjes.size()){
    				
    				//check volgende cell en vergelijk meteen de kleur
    				if (vierkantjes.get(i + 1).isGeinfecteerd == true ){
    					vierkantjes.get(i).selecteer();
    					vierkantjes.get(i).infecteer();
    					counter++;
    					continue;
    				}
    			}
    			if (i - 1 >= 0){
    				
    				//check vorige cell en vergelijk meteen de kleur
    				if (vierkantjes.get(i -1).isGeinfecteerd == true){
    					vierkantjes.get(i).selecteer();
    					vierkantjes.get(i).infecteer();
    					counter++;
    					continue;
    				}
    			}
    			
    			// check neighbour boven
    			if (i + grootte <= vierkantjes.size()){
    				if (vierkantjes.get(i + grootte).isGeinfecteerd == true){
    					vierkantjes.get(i).selecteer();
    					vierkantjes.get(i).infecteer();
    					counter++;
    					continue;
    				}
    			}
    			// check neighbour onder
    			if (i -  grootte >= 0){
    				if (vierkantjes.get(i - grootte).isGeinfecteerd == true){
    					vierkantjes.get(i).selecteer();
    					vierkantjes.get(i).infecteer();
    					counter++;
    					continue;
    				}
    			}
    		}
    	}
    	
    	if (counter == vierkantjes.size()){
    		
    		System.out.println("We zijn klaar!");
    	}
    	
    }

deze for lus is niet optimaal maar wel duidelijk (de checks met neighbours kan je met wat moeite wel in 1 if statement zetten maar dat maakt het de code niet duidelijker op).

verder moet je nog even de kleur opvragen van het rooster rechts. Ik kan niet echt vinden waar je die heb neergezet ?

verder om het begin "random" te doen kan je het volgende doen: vierkantjes.get( 1 + (int)(Math.random() * vierkantjes.size() ).Infect(); of anders pak je gewoon 0. (de eerste).
 
Het ziet er nu een stuk beter uit met uw hulp, waarvoor dank!

Ik heb de methode aangemaakt die de kleur vraagt aan het rooster rechts. Echter als ik per ongeluk buiten dat rooster klik worden alle geïnfecteerde vierkantjes zwart. Hoe zou ik dat het beste kunnen oplossen?

Ook moet ik soms een aantal keer drukken op het rooster vooraleer de vierkantjes geïnfecteerd worden en veranderen van kleur. Hier bij krijg ik dan ook de foutmelding: ” Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index:…”

Indien de het eerste vierkantje paars is en er liggen bijvoorbeeld drie gele vierkantjes naast(op een rij) en als ik dan op de gele knop druk wordt alleen het vierkantje gelegen aan het paarse vierkantje geïnfecteerd. Terwijl ze allendrie geïnfecteerd zouden moeten worden aangezien ze dezelfde kleur hebben.

Link: http://www.mijnbestand.nl/Bestand-XDKS8XDWP33E.rar
 
Laatst bewerkt:
ja dat klopt de index out of bounds exception komt omdat er geen -1 na de size staat.
als je een check doet: if (i + grootte <= vierkantjes.size()) dan krijg je de volgende waardes: 400 <= 400 (wat dus mag). alleen de forloop is 0 based. wat dus in houdt dat de max waarde de size -1 is. kortom er moet ff een -1 naast.

voor de kleur zwart kan je het volgende doen.
je hebt nu een x aantal if statements. als je deze in if, else if else if.... etc.. else veranderd en dan bij else return -1 neerzet (geen kleur vonnden) kan je dus checken op -1. wanneer er -1 uit gekomen is dan roep je dus de infectMethode niet aan. dus in je controller:

int color = bord.getColor(x,y);
if (color != -1){
bord.infectMethod2(color);
}

verder heb ik een oplossing voor je probleem, vind hem zelf niet de meest elegante maargoed... het werkt. wat je feitelijk doet is wanneer er een hokje geinfect wordt, de forloop reset en opnieuw begint te kijken. dit zal ongetwijfeld beter kunnen en ik raad het je dus ook niet aan om deze manier te gebruiken maar een elegantere oplossing te zoeken ( denk aan een aparte methode die recursief aangeroepen wordt die als parameter een index meekrijgt en opnieuw aangeroepen wordt totdat er geen cellen in dat gebied meer kunnen worden geinfecteerd).

[cpp]

public void infectMethode2(int color){

int counter = 0;

for (int i = 0 ; i < vierkantjes.size(); i++){


if(vierkantjes.get(i).isGeinfecteerd == true){
vierkantjes.get(i).veranderKleur(color);
counter++;
}
else{
System.out.println("index " + i +" = open");
}
//deze kan mogelijk geinfecteerd worden. check op nog niet geinfecteerd en kleur
if (vierkantjes.get(i).isGeinfecteerd == false && vierkantjes.get(i).getKleur() == color){

//nu checken of 1 van de neighbours geinfecteerd zijn.

//out of bounds error voorkomen
if (i +1 <= vierkantjes.size() -1){

//check volgende cell en vergelijk meteen de kleur
if (vierkantjes.get(i + 1).isGeinfecteerd == true ){
vierkantjes.get(i).selecteer();
vierkantjes.get(i).infecteer();

counter = 0;
i = -1;
continue;
}
}
if (i - 1 >= 0){

//check vorige cell en vergelijk meteen de kleur
if (vierkantjes.get(i -1).isGeinfecteerd == true){
vierkantjes.get(i).selecteer();
vierkantjes.get(i).infecteer();
counter = 0;
i = -1;
continue;
}
}

// check neighbour boven
if (i + grootte <= vierkantjes.size() -1){
if (vierkantjes.get(i + grootte).isGeinfecteerd == true){
vierkantjes.get(i).selecteer();
vierkantjes.get(i).infecteer();
counter = 0;
i = -1;
continue;
}
}
// check neighbour onder
if (i - grootte >= 0){
if (vierkantjes.get(i - grootte).isGeinfecteerd == true){
vierkantjes.get(i).selecteer();
vierkantjes.get(i).infecteer();
counter = 0;
i = -1;
continue;
}
}
}
}
System.out.println(counter);

if (counter >= vierkantjes.size()){

System.out.println("We zijn klaar!");
}

}

[/cpp]
 
Het werkt en dat is het belangrijktste! Heel erg bedankt. Zonder uw hulp had ik het nooit voor elkaar gekregen!
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan