[Java] Stenen omdraaien in Reversi-spel

Pagina: 1
Acties:
  • 875 views sinds 30-01-2008

  • Phrantic
  • Registratie: Oktober 2003
  • Laatst online: 06-09-2022
Het is moeilijk te zeggen wat het probleem precies is bij mijn vraag. Laten we het zo stellen: ik moet een feature in mijn Reversi-spel inbouwen die de ingesloten stenen op een speelbord omdraait. Mocht je niet bekend zijn met de regels: elke speler legt op een bord naast de steen van de tegenstander een eigen steen neer, waardoor de steen of stenen van de tegenstander ingesloten worden door je nieuwe steen en een andere steen op het speelbord. Voorbeeld: http://www.goedspel.nl/games.php?id=164

Nu heb ik een methode die controleert of een zet op een bepaald vakje toegestaan is. Deze methode levert een boolean true of false op. In deze methode kan ik echter niet gelijk de ingesloten stenen omkeren, 1) omdat in de methode 'return true' het proces onderbroken wordt zodra een mogelijkheid wordt gevonden en 2) omdat er acht verschillende richtingen worden gecontroleerd en het niet de bedoeling is dat de staat van het bord wordt veranderd voordat alle acht richtingen zijn gecontroleerd.

Nu heb ik dus een aparte doeZet-methode die dit zou moeten oplossen. In feite een kopie van de boolean checkZet methode, maar dan zonder return-opdrachten. Alleen lijkt deze methode niets te veranderen. Ik heb ook geprobeerd een aparte array aan te maken en die buiten de hele methodes (pas in mouseClicked) de waarden van de stenen te veranderen, maar dat lukt me niet.

Wie kan me helpen mijn spel in orde te brengen? Ik zit nu zo'n beetje vast in de laatste fase en ik moet de opdracht om middernacht inleveren. 8)7

Hier is mijn broncode. De in array vakje[x][y] staan x en y voor de positie (rijen & kolommen) op het speelveld en de waarde hiervan is 0 (leeg), 1 (blauw) of 2 (rood). Wat gaat er hier fout, en hoe moet het goed? Iedereen die meedenkt krijgt een koekje. Alvast hartelijk bedankt. :)

Reversi.java (te groot om in de post bij te voegen 8)7
Reversi.java (mirror lol O_O)

hoi


  • momania
  • Registratie: Mei 2000
  • Laatst online: 14:04

momania

iPhone 30! Bam!

Phrantic schreef op vrijdag 20 oktober 2006 @ 20:34:
Wie kan me helpen mijn spel in orde te brengen? Ik zit nu zo'n beetje vast in de laatste fase en ik moet de opdracht om middernacht inleveren. 8)7
[moraalridder]
Dan had je eerder moeten beginnen, dan had je je leraar om hulp kunnen vragen ;)
[/moraalridder]

Verder lijkt het me handiger als je gewoon wat relevante code hier neerzet om je probleem te omschrijven. Denk niet dat iemand hier de moeite gaan nemen om al je code door te gaan nemen.
(plus dat je link het niet eens doet ;) )

Neem je whisky mee, is het te weinig... *zucht*


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 13:10

Creepy

Tactical Espionage Splatterer

En wat lukt er dan niet? Wat heb je zelf al geprobeerd om dat op te lossen? Al met een debugger aan de slag gegaan?

De link naar je volledige broncode is niet relevant. We zijn er hier niet om je code te debuggen (al helemaal niet voor middernacht). Debuggen is iets wat je voor software ontwikkeling zelf onder de knie moet krijgen. Lukt dat niet? Prima. Dan kan je hier een topic openen, maar geef dan wel aan welke zaken je nu hebt geprobeerd. Nu komt het over als een "dit is mijn code, fix het even voor me" en dat is hier niet de bedoeling ;)

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • Phrantic
  • Registratie: Oktober 2003
  • Laatst online: 06-09-2022
momania schreef op vrijdag 20 oktober 2006 @ 21:00:
[moraalridder]
Dan had je eerder moeten beginnen, dan had je je leraar om hulp kunnen vragen ;)
[/moraalridder]
Het is een tentamenonderdeel voor een cijfer, leraren zijn al bang om je TE ver op weg te helpen, op z'n best sturen ze je nog vage hints waar je moet wezen om het te verbeteren, maar verder moet je het allemaal zelf maar uitzoeken... :P

Ik zal even de meest relevante methodes hier neerzetten, hoewel het hele gebeuren zich een beetje over het hele applet spreidt:

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
    private boolean checkZet(int x, int y) {
        
        // neem de kleur van de speler als uitgangspunt
        int waarde;
        if(beurt) waarde = 1;
        else waarde = 2;
            
        // maak een array met alle mogelijke richtingen
        int [][] richting = new int[8][2];
        richting[0][0] = -1; richting[0][1] = -1;
        richting[1][0] = 0;  richting[1][1] = -1;
        richting[2][0] = 1;  richting[2][1] = -1;
        richting[3][0] = -1; richting[3][1] = 0;
        richting[4][0] = 1;  richting[4][1] = 0;
        richting[5][0] = -1; richting[5][1] = 1;
        richting[6][0] = 0;  richting[6][1] = 1;
        richting[7][0] = 1;  richting[7][1] = 1;
        
        for(int z=0; z<8; z++) {
            
            int a; int [] b;
            // kopieer de waarden zodat we die kunnen manipuleren in de loop
            b = new int[2];
            b[0] = richting[z][0];
            b[1] = richting[z][1];
            
            if(x+b[0] >= 0 && x+b[0] < breedte && y+b[1] >= 0 && y+b[1] < hoogte) {
                
                a = vakje[x+b[0]][y+b[1]];
                
                if  (a != waarde && a != 0) { 
                    while(x+b[0] >= 0 && x+b[0] < breedte && y+b[1] >= 0 && y+b[1] < hoogte && vakje[x+b[0]][y+b[1]] != 0) {
                        
                        if(vakje[x+b[0]][y+b[1]] == waarde) {
                            return true;
                        }
                        else {
                            b[0] += richting[z][0];
                            b[1] += richting[z][1];
                        }
                    }
                    
                }
            }
        }
        return false;
    }
    
    private void doeZet(int x, int y) {
        
        // neem de kleur van de speler als uitgangspunt
        int waarde;
        if(beurt) waarde = 1;
        else waarde = 2;
            
        // maak een array met alle mogelijke richtingen
        int [][] richting = new int[8][2];
        richting[0][0] = -1; richting[0][1] = -1;
        richting[1][0] = 0;  richting[1][1] = -1;
        richting[2][0] = 1;  richting[2][1] = -1;
        richting[3][0] = -1; richting[3][1] = 0;
        richting[4][0] = 1;  richting[4][1] = 0;
        richting[5][0] = -1; richting[5][1] = 1;
        richting[6][0] = 0;  richting[6][1] = 1;
        richting[7][0] = 1;  richting[7][1] = 1;
        
        for(int z=0; z<8; z++) {
            
            int a; int [] b;
            // kopieer de waarden zodat we die kunnen manipuleren in de loop
            b = new int[2];
            b[0] = richting[z][0];
            b[1] = richting[z][1];
            
            if(x+b[0] >= 0 && x+b[0] < breedte && y+b[1] >= 0 && y+b[1] < hoogte) {
                
                a = vakje[x+b[0]][y+b[1]];
                
                if  (a != waarde && a != 0) { 
                    while(x+b[0] >= 0 && x+b[0] < breedte && y+b[1] >= 0 && y+b[1] < hoogte && vakje[x+b[0]][y+b[1]] != 0) {
                        
                        if(vakje[x+b[0]][y+b[1]] == waarde) {
                            
                        }
                        else {
                            omdraaien[x+b[0]][y+b[1]] = 1;
                            b[0] += richting[z][0];
                            b[1] += richting[z][1];
                        }
                    }
                    
                }
            }
        }


Om nog maar eens duidelijk te maken: hier zitten geen bugs in, er is geen debugger die zegt wat er goed of fout is, ik vraag me alleen af hoe het komt dat de nieuwe waarden niet worden doorgespeeld en hoe ik er voor moet zorgen dat ik dat wel moet doen.

Ik begrijp dat het nogal een opgave is voor de medetweaker maar nooit geschoten is altijd mis en dit is m'n laatste hoop omdat ik na een week intensief werken Java-oogjes begin te krijgen. 8)7

[ Voor 5% gewijzigd door Phrantic op 20-10-2006 21:08 ]

hoi


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 13:10

Creepy

Tactical Espionage Splatterer

???? Een debugger zegt niet of iets goed is of fout. Met een debugger kan je bijv. door je code heen lopen en stoppen en op dat moment controleren welke variabelen welke waarden hebben zodat je kan controleren of bepaalde zaken goed gaan of niet. Een foutmelding van een debugger zelf zal je niet al te snel krijgen ;)

Nogmaals: wat gaat er nu precies mis? Wat werkt er nu niet, en wat heb je nu zelf al gedaan om het op te lossen? We zijn er hier niet om jouw code te debuggen

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • user109731
  • Registratie: Maart 2004
  • Niet online
Mede student meld zich :)

Werkt je help-functie al wel goed? Zie je de hulp-cirkels op de goede plaats?
Waarom gebruik je omdraaien[], en niet vakje[]? Kopieer je die wel terug? En hoe doe je dat?

Wat ikzelf erg handig vond tijdens deze opdracht is op cruciale punten breakpoints zetten, zodat je snel de waarden van alle variabelen kunt bekijken, en veel debug-messages wegschrijven, dat helpt echt. Dus zoiets:
Java:
1
2
System.out.println("Change direction to: left");
System.out.println("Checking stone at ("+x+", "+y+")");

:)

  • Phrantic
  • Registratie: Oktober 2003
  • Laatst online: 06-09-2022
Grote prutser schreef op vrijdag 20 oktober 2006 @ 21:55:
Mede student meld zich :)

Werkt je help-functie al wel goed? Zie je de hulp-cirkels op de goede plaats?
Waarom gebruik je omdraaien[], en niet vakje[]? Kopieer je die wel terug? En hoe doe je dat?

Wat ikzelf erg handig vond tijdens deze opdracht is op cruciale punten breakpoints zetten, zodat je snel de waarden van alle variabelen kunt bekijken, en veel debug-messages wegschrijven, dat helpt echt. Dus zoiets:
Java:
1
2
System.out.println("Change direction to: left");
System.out.println("Checking stone at ("+x+", "+y+")");

:)
De help-functie werkt, en dat is het gekke. De cirkels worden op de goede plaats getekend, en ook als een zet meer dan 1 steen slaat (dus hij telt gewoon door tot het eind, zonder fouten).

Ik heb het niet in vakje[] aangepast omdat deze array in de functie zelf verder nog gebruikt moest worden.. Ik kan wel middenin de methode het speelbord gaan aanpassen maar dat is van invloed op de verdere uitkomst van de methode. Daarom heb ik het in omdraaien[] opgeslagen, en aan het eind van de doeZet methode (als alle loops afgelopen zijn) heb ik dit gezet:

Java:
1
2
3
4
5
6
7
8
        for(int a = 0; a<breedte; a++) {
            for(int b = 0; b<hoogte; b++) {
                if(omdraaien[a][b] == 1) {
                    if(vakje[a][b] == 1) vakje[a][b]++;
                    else if(vakje[a][b] == 2) vakje[a][b]--;
                }
            }
        }

Ik zal nog even kijken of het wat oplevert om met dat System.out.println aan de slag te gaan, heb nog 2 uur en m'n HTML-bestand is ook verder helemaal af, dus kan nog wel ff wat aanklooien. :) Bedankt

hoi


  • user109731
  • Registratie: Maart 2004
  • Niet online
Phrantic schreef op vrijdag 20 oktober 2006 @ 22:07:
[...]
Ik heb het niet in vakje[] aangepast omdat deze array in de functie zelf verder nog gebruikt moest worden.. Ik kan wel middenin de methode het speelbord gaan aanpassen maar dat is van invloed op de verdere uitkomst van de methode.
Als je de stenen in een bepaalde richting aan gaat passen, heeft dat toch geen invloed op de andere richtingen? Ik doe het dus wel gewoon direct op het speelbord, maar het zou kunnen dat jouw functie iets anders werkt. :)

Als ik jou was zou ik nu eerst de totale output van je omdraaien-array op het scherm zetten, door een extra regel (regel 4) toe te voegen aan jouw code:
Java:
1
2
3
4
5
6
7
8
9
        for(int a = 0; a<breedte; a++) {
            for(int b = 0; b<hoogte; b++) {
                if(omdraaien[a][b] == 1) {
                    System.out.println("Omdraaien: "+a+", "+b);
                    if(vakje[a][b] == 1) vakje[a][b]++;
                    else if(vakje[a][b] == 2) vakje[a][b]--;
                }
            }
        }

Als dat er goed uitziet, kijk je naar de output van vakje[][]. Dit kan veel handiger als je weet hoe je debugger werkt, maar dat kost ook tijd. En je doet wel een repaint he? ;)

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12-02 15:05

Robtimus

me Robtimus no like you

Half offtopic, maar je richting matrix blijft altijd constant, in beide methods. Je kunt daar beter een constante van maken:
Java:
1
private static final int[][] RICHTING = new int[][] {{-1, -1}, ..., {1, 1}};
Zo hoef je dit maar 1x te declareren en definieren, en daarna gebruik je hem. Ook heb je maar 1 instantie voor al je instanties van je class.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Not Pingu
  • Registratie: November 2001
  • Laatst online: 30-01 15:48

Not Pingu

Dumbass ex machina

Wat hierbij denk ik handig is, is het gebruik van vectoren.

Neem het punt A waar je je steen wilt neerzetten. Ga vervolgens je array met stenen door en trek punt A af van positie B van de steen. Als de resulterende vector een component heeft dat 0 is, of beide componenten zijn even groot, dan weet je dat je een match hebt. Je kunt dan je vector normalizeren naar unit lengte (lengte = 1) en zo posities vinden van de stenen die je moet omdraaien.

[edit]
hm, eigenlijk doe je dit in principe al op een ingewikkeldere manier, maar je checkt altijd alle richtingen, of er nu stenen van je eigen kleur liggen of niet.

[offtopic]
overigens kun je de volgende twee logische vergelijkingen samenvoegen tot 1:

Java:
1
2
3
vakje[x+b[0]][y+b[1]] != 0
                        
vakje[x+b[0]][y+b[1]] == waarde


door gewoon ineens al te checken of (vakje[i,j] == waarde)

[ Voor 32% gewijzigd door Not Pingu op 20-10-2006 22:53 ]

Certified smart block developer op de agile darkchain stack. PM voor info.


  • Jk_W
  • Registratie: Februari 2003
  • Niet online

Jk_W

I Think...

Imp-student! :w

Ik heb hem reeds klaar, en je mag gerust in mijn code kijken, maar je DM staat niet aan. Je zou ook eens kunnen googlen op reversi.java. Dan vind je werkende codes, waar je inspiratie uit kan halen. Hoe hebben zij het opgelost? Probeer dat eens als je er niet uitkomt voor vanacht!

En alvast sterkte met SchetsPlus ;)

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12-02 15:05

Robtimus

me Robtimus no like you

Not Pingu schreef op vrijdag 20 oktober 2006 @ 22:38:
Wat hierbij denk ik handig is, is het gebruik van vectoren.Lists
Met Lists kun je later je implementatie veranderen zonder veel te moeten veranderen. Het is dan ook goed om zoveel mogelijk tegen interfaces en base classes te programmeren.

Dus niet "Vector items = new Vector();" maar "List items = new Vector();".

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • whoami
  • Registratie: December 2000
  • Laatst online: 15:26
Het is een tentamenonderdeel voor een cijfer, leraren zijn al bang om je TE ver op weg te helpen, op z'n best sturen ze je nog vage hints waar je moet wezen om het te verbeteren, maar verder moet je het allemaal zelf maar uitzoeken...
Een beetje zoals GoT dus.
Iig is het hier niet de bedoeling dat wij jouw code gaan debuggen of oplossen.

En tja, je had idd maar eerder moeten beginnen. Il ne sert a rien de courir, il faut partir à temps.

https://fgheysels.github.io/

Pagina: 1

Dit topic is gesloten.