Skip to content

Latest commit

 

History

History
63 lines (40 loc) · 6.68 KB

File metadata and controls

63 lines (40 loc) · 6.68 KB

Documentation

Beskrivelse

Dette sjakkprogrammet, laget i JavaFX, gir en visuell og interaktiv plattform for å spille sjakk mot deg selv eller en annen spiller. Programmet tilbyr et brukervennlig grensesnitt med et 2D-sjakkbrett og brikker som kan flyttes med musen. Det går også ann å lagre spilltilstanden og fortsette et spill senere, eller starte et helt nytt spill om en ønsker det. Programmet passer selv på at trekkene som spiller er lovlige og at spillet følger sjakkreglene. Dette er en enkel implementasjon av sjakk, og det er ikke implementert alle spesialtrekkene som finnes i sjakk, som rokade, bondebytte og én passant.

Funksjoner:

  • Et enkelt og intuitivt grensesnitt.
  • Visuell brettvisning: Se sjakkbrettet og brikkene i et attraktivt 2D-design.
  • Visuell indikasjon på mulige trekk: Se hvilke felt du kan flytte brikkene dine til.
  • Lagret spilltilstand: Fortsett et spill der du slapp.

Ting som ikke er implementert:

  • Enkelte spesialtrekk som rokade, bondebytte og én passant.
  • Sjakkregler som trekkgrense og trekktrippel.

Hvis vinduet applikasjonen åpnes i er for lite, eller for stort, kan dette endres i App.java-filen. Her kan en endre på SCALE variabelen for å endre størrelsen på brettet.

Diagram

Klassediagram

Spørsmål

  1. Dette prosjektet bruker en god del av teknikkene pensum har tatt for seg. Prosjektet har med alle elementene av prosedyreorientert programmering som pensum har tatt for seg, samt de fleste av grunnelementene innenfor objektorientert programmering. De eneste teknikkene som mangler her er arv.

    Alle klassene i prosjektet er innkapslet, og interagerer med hverandre på en forventet måte. Grensesnitt og observatør-observert teknikken er brukt som en måte å sende signal mellom brukergrensesnittet og kontrollklassen. Kontrollklassen implementerer brukergrensesnittet for alle som skal lytte på om en brikke blir flyttet, og klassen som håndterer at brikke kan bli flyttet sender signal tilbake til kontrollklassen med info om hvilken node som har blitt flyttet, og dens posisjon.


  1. Den eneste teknikken innenfor objektorientert programmering som ikke er brukt i dette prosjektet er arv. Når det gjelder hvordan arv kunne blitt brukt i appen, er det ikke noe klart svar. Arv brukes som regel når flere klasser har lik oppførsel, og brukes derfor som regel for å maksimere kodegjenbruk. Arv muliggjør også polymorfi, der objekter av forskjellige underklasser kan behandles på samme måte gjennom en felles baseklassemetode. Det er ingen steder i prosjektet der disse oppførslene har noen positiv effekt på hverken organisasjon eller vedlikehold av kode. Alle klassene i prosjektet er unike med ingen felles elementer, så arv hadde mest sannsynlig bare bidratt til en større og mer kompleks kodebase, uten noen reel gevinst.

  1. Koden forholder seg veldig godt i forhold til Model-View-Controller-prinsippet. Kontroller klassen har ikke noe av logikken som en kan tenke seg at en klasse i modell-delen egentlig skulle hatt. Det kontrollklassen har er en "oversetter" fra brukergrensesnittet til modelldelen av applikasjonen. Dette er noe som kanskje burde ha vært avskilt i modell-delen. Skillet mellom brukergrensesnittet og kontrolleren er litt mer abstrakt. Enkelte av funksjonene som tar seg av brukergrensesnittet er av avskilt i egne klasser, som i Model-View-Controller-prinsippet, men metoden som tegner brukene på brettet er en del av kontrollerklassen. Dette ble gjort på grunn av at å lage en egen klasse for denne metoden var ulogisk, både fordi den består av bare én metode, men også fordi den avhenger av flere variabler som evt. måtte bli tatt inn i en konstruktør. Valget å ha denne metoden i kontrollerklassen var for å unngå å gjøre koden unødvendig komplisert.

  1. De fleste klassene i appen har assosierte tester som sjekker at oppførselen er som forventet, og at ingen feilmeldinger oppstår under kjøring. Unntakene er App, Scene, og kontrollerklasen, samt klassene som tar seg brukergrensesnittet – en klasse som tar seg av canvas, og en klasse som gjør slik at brikkene kan dras i brukergrensesnittet. Klassene for brukergrensesnittet er umulige å teste siden resultatet av kjøring er visuell. App og Scene er klasser for å starte opp, og er derfor ikke en del av selve applikasjonen, mens kontrollerklasen – som nevnt i spørsmål 3 – fungerer mest som en "oversetter" mellom brukergrensesnitt-delen og modell-delen. Testklassene som ble skrevet var derfor alle for modell-delen av applikasjonen.

    Piece og Move klassene er datalagringsklasser med assosierte getter-metoder. Her ble det bare testet om getter-metodene ga riktig forventet verdi basert på argumentene i konstruktøren, samt at feilmeldinger ble gitt om konstruktøren fikk inn ugyldige verdier. Testen for FileHandler gjør mye av det samme, men siden jeg valgte at brukeren kan velge selv hvor hen vil lagre det gjeldene brettet måtte test-filen bruke mockito for å simulere hva som hadde skjedd, og gi verdier ut ifra det. Board-klassen er forsovet også en datalagringsklasse der en kan endre på posisjonen til brikkene i en array. Testen for Board-klassen sjekker om alle metodene i klassen har forventet oppførsel, mye på samme måte som Piece og Move klassene, men litt mer kompleks.

    MoveGenerator klassen var vanskelig å lage en test for, siden for å vite om klassen fungerer som den skal, må en vite hvor mange trekk en spiller kan oppnå på en gitt posisjon. Heldigvis finnes det en oversikt over det på wiki-sidene til chessprogramming. I testen er blitt laget en egen metode som teller opp totalt antall mulige trekk etter et søk i ev viss dybde:

    public int MoveGenerationTest(int deapth) {
        if (deapth == 0)
            return 1;
    
        int numPositions = 0;
        List<Move> moves = new MoveGenerator().getAllLegalMoves(board);
        for (Move move : moves) {
            Piece capture = board.makeMove(move);
            numPositions += MoveGenerationTest(deapth - 1);
            board.undoMove(move, capture);
        }
        return numPositions;
    }

    Denne sammen med noen av verdiene på wikisidene ble brukt til å teste at klassen fungerte som forventet. På wikisidene var jeg forsiktig med å ta verdier som ikke hadde med spesialtrekk – som rokade, bondebytte og én passant – siden disse ikke er implementert i applikasjonen. Jeg måtte også velge å ikke ta med verdier hvis antall forventede trekk ble for stort, siden tiden testklassen brukte på å validere at det ble riktig tok for lang tid – opptil flere minutter. Hvis dette hadde vert et ekte, større, mer seriøst prosjekt hadde jeg testet for flere verdier.