Files
oops/oppgavetekster/oving5/StringGrid.md
Andreas Omholt Olsen 55c36a603a Add oving 5
2026-02-09 15:28:09 +01:00

74 lines
5.6 KiB
Markdown

# Interface - StringGrid-oppgave
Denne oppgaven handler om et grensnitt (interface) for rutenett som holder strenger (StringGrid), hvordan slike implementeres og hvordan en kan iterere gjennom et slikt rutenett ved hjelp av en [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable).
I denne oppgaven tar vi utgangspunkt i et `StringGrid`-grensesnitt som definerer metodene til et rutenett som holder strenger. Et rutenett er firkantet og består av et antall rader og kolonner. Det skal være mulig å spørre rutenettet hvilken streng som er på angitt rad og kolonne i tillegg til å endre strengen på angitt rad og kolonne. Denne oppførselen er oppsummert i det definerte `StringGrid`-grensesnittet under:
Filene i denne oppgaven skal ligge i [`oving5/stringgrid`](../../src/main/java/oving5/stringgrid).
```java
package oving5.stringgrid;
/**
* An interface with methods for managing the content of a String grid. The grid has a number of
* rows (the grid's height) and columns (the grid's width). In each cell in the grid there is a
* String that can be set with the setElement method and read with the getElement method.
*/
public interface StringGrid {
// Returns the number of rows in this StringGrid
int getRowCount();
// Returns the number of columns in this StringGrid
int getColumnCount();
// Returns the String at the given row and column. Throws an IllegalArgumentException if the
// row or column is out of range
String getElement(int row, int column);
// Sets the String at the given row and column. Throws an IllegalArgumentException if the row
// or column is out of range
void setElement(int row, int column, String element);
}
```
Alle klasser som implementerer **StringGrid**-grensesnittet må støtte de fire definerte metodene.
## Del 1 - StringGrid-grensesnitt og implementerende StringGridImpl-klasse
Lag en `StringGridImpl`-klasse som implementerer `StringGrid`-grensesnittet definert over. Merk at grensesnitt ikke kan brukes til å spesifisere konstruktører, så du må selv definere en eller flere egnede konstruktører. Det er imidlertid nødvendig å implementere en konstruktør som tilsvarer den JUnit-testen forventer:
- `StringGridImpl(int rows, int columnCount)` - konstruktør som tar inn antall rader som `rows` og antall kolonner som `columnCount`.
Du står fritt til å velge hvordan metodene definert av grensesnittet skal implementeres så lenge de tilfredsstiller den definerte oppførselen.
**Hint:** Bruk en enkel `ArrayList<String>` eller en dobbel `ArrayList<ArrayList<String>>` (se wiki-siden om [todimensjonale matriser](https://www.ntnu.no/wiki/display/tdt4100/Todimensjonale+matriser)). Du kan også bruke en enkel `String[]` eller en todimensjonal `String[][]` for å lagre strengene. Implementasjonen er helt opp til deg, så lenge den oppfører seg som beskrevet i grensesnittet.
## Del 2 - StringGridIterator-klasse
Det er hensiktmessig å kunne iterere over alle elementene i et rutenett som implementerer grensesnittet `StringGrid`, f.eks. når en bygger en streng i en `toString()`-metode eller skal sjekke om et spill har blitt avsluttet/vunnet. I denne deloppgaven skal du lage en slik [`Iterator`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable)-implementasjon, kalt `StringGridIterator`. Denne klassen må implementere grensesnittet `Iterator<String>`, siden `StringGrid` inneholder `String`-objekter. I tillegg til metodene som er definert i `Iterator`-grensesnittet, må `StringGridIterator` ha en konstruktør som tar imot hvilken `StringGrid` det skal itereres over og i hvilken rekkefølge elementene skal returneres i. Disse verdiene må huskes, så koden i `Iterator`-metodene kan brukes dem til å styre iterasjonen. `StringGridIterator`-klassen må altså støtte følgende konstruktør/metoder:
- `StringGridIterator(StringGrid, boolean rowMajor)` - konstruktør som tar inn `StringGrid`-objektet som `StringGridIterator`-klassen skal iterere over i tillegg til en logisk verdi som angir om iterasjonen skal være bortover først (`rowMajor` er `true`) eller nedover først (`rowMajor` er `false`).
- `boolean hasNext()` - returnerer `true` så lenge det er flere `String`-objekter igjen i `StringGrid`-objektet som ikke ennå er blitt iterert over (med andre ord, sjekk om du har kommet til siste rute i rutenettet).
- `String next()` - returnerer det neste `String`-objektet i rutenettet. Hvilken `String` som er den neste, avhenger av hvordan rutenettet skal itereres (med andre ord, hvorvidt om `rowMajor` er `true` eller `false`).
- `void remove()` - denne metoden skal bare utløse et unntak av typen `UnsupportedOperationException` siden det ikke skal være mulig å fjerne `String`-objekter fra rutenettet.
## Del 3 - Iterable-grensesnittet
Endre `StringGrid`-grensesnittet slik at det utvider (med `extends`) [`Iterable<String>`](https://www.ntnu.no/wiki/display/tdt4100/Iterasjon+med+Iterator+og+Iterable). Dette skal gjøre det mulig å skrive for-setningen under, for å gå gjennom alle elementene i rutenettet.
```java
StringGrid stringGrid = ... // her initialiseres stringGrid
// gå gjennom alle elementene i stringGrid
for (String s : stringGrid) {
// gjør noe med s her
}
```
Rekkefølgen som en slik `for`-løkke går gjennom elementene på, skal være hele første rad, så hele andre rad osv. til og med siste rad.
Hva slags følger får det for `StringGridImpl`? Gjør nødvendige endringer i den også, og test at det virker!
Testkode for del 1 og del 2 finner du her: [oving5/stringgrid/StringGridTest.java](../../src/test/java/oving5/stringgrid/StringGridTest.java).