[JAVA] Wir haben das "Bingo Judgement Program" überarbeitet.

Nachdem ich @ johejos Beitrag "Bingo Judgement Program" gesehen hatte, dachte ich, dass es eine interessante Geschichte war, aber es war alles ein statisches Methodenprozedurprogramm. Ich war enttäuscht, dass es war. Da es sich um Java handelt, können wir es objektorientiert umgestalten. Dies ist natürlich nicht die endgültige Form. Ich denke, wir können besser umgestalten, also probieren Sie es bitte durch Ausprobieren aus.

3. Refactoring

Ich erhielt erneut einen Kommentar von @ k73i55no5 und überarbeitete nur die Bingo-Klasse.

Übersicht über die Klassenstruktur

Klassen Diagramm

image.png

Code (nur Bingo-Klasse)

public class Bingo {
    public static void main(String[] args) throws Exception {
        Bingo bingo = new Bingo(loadCardNumbers("board.txt"));
        bingo.select(loadSelectionNumbers("selected.txt"));
        bingo.show();
    }

    public static int[][] loadCardNumbers(String filename) throws IOException {
        return Files.readAllLines(Paths.get(filename))
                    .stream()
                    .map(line -> Arrays.stream(line.split(" "))
                                       .mapToInt(Integer::parseInt)
                                       .toArray())
                    .toArray(int[][]::new);
    }

    public static int[] loadSelectionNumbers(String filename) throws IOException {
        return Files.readAllLines(Paths.get(filename))
                    .stream()
                    .mapToInt(Integer::parseInt)
                    .toArray();
    }

    private final BingoCard card;

    public Bingo(int[][] numbers) {
        this(new BingoCard(numbers));
    }

    Bingo(BingoCard card) {
        this.card = card;
    }

    public void select(int[] numbers) {
        Arrays.stream(numbers).forEach(card::select);
    }

    public void show() {
        System.out.println("BINGO:" + card.countBingo());
        System.out.println("REACH:" + card.countReach());
    }
}

Zweites Refactoring

Basierend auf den Kommentaren von @ k73i55no5 haben wir das zweite Refactoring durchgeführt. Die Masse der Bingokarte ist auf 5 x 5 festgelegt, und die Konsistenzprüfung der Datengröße entfällt. Wenn Sie weitere Verbesserungen haben, kommentieren Sie bitte.

Code

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Stream;

public class Bingo {
    public static void main(String[] args) throws Exception {
        //Lesen Sie die numerischen Daten der Bingokarte und erstellen Sie eine Bingokarte
        int[][] numbers = Files.readAllLines(Paths.get("board.txt"))
                               .stream()
                               .map(line -> Arrays.stream(line.split(" "))
                                                  .mapToInt(Integer::parseInt)
                                                  .toArray())
                               .toArray(int[][]::new);
        BingoCard card = new BingoCard(numbers);
        //Lesen Sie die vom Veranstalter des Bingo-Turniers ausgewählte Zahlenfolge und spiegeln Sie sie auf der Bingokarte wider
        Files.readAllLines(Paths.get("selected.txt"))
             .stream()
             .map(Integer::parseInt)
             .forEach(card::select);
        //Zeigen Sie den Status der Bingokarte an
        System.out.println("BINGO:" + card.countBingo());
        System.out.println("REACH:" + card.countReach());
    }
}

class BingoCard {
    private final SelectableNumbers numbers;
    private final BingoLines lines;

    public BingoCard(int[][] numbers) {
        this.numbers = new SelectableNumbers(numbers);
        this.lines = new BingoLines(this.numbers);
    }

    public void select(int number) {
        numbers.select(number);
    }

    public long countReach() {
        return lines.countReach();
    }

    public long countBingo() {
        return lines.countBingo();
    }
}

class SelectableNumber {
    public final int number;
    private boolean selected = false;

    public SelectableNumber(int number) {
        this.number = number;
    }

    public void select() {
        selected = true;
    }

    public boolean isSelected() {
        return selected;
    }
}

class SelectableNumbers {
    private final SelectableNumber[] numbers;

    private static SelectableNumber[] flattenNumbers(int[][] numbers) {
        return Stream.of(numbers)
                     .flatMapToInt(Arrays::stream)
                     .mapToObj(SelectableNumber::new)
                     .toArray(SelectableNumber[]::new);
    }
    
    public SelectableNumbers(int[][] numbers) {
        this.numbers = flattenNumbers(numbers);
    }
    
    public SelectableNumber getAt(int index) {
        return numbers[index];
    }

    public void select(int number) {
        Stream.of(numbers)
              .filter(n -> n.number == number)
              .forEach(n -> n.select());
    }
}

class BingoLine {
    private final SelectableNumber[] numbers;

    public BingoLine(SelectableNumber[] numbers) {
        this.numbers = numbers;
    }

    private long countSelectedNumbers() {
        return Stream.of(numbers).filter(number -> number.isSelected()).count();
    }

    public boolean isReach() {
        return countSelectedNumbers() == numbers.length - 1;
    }

    public boolean isBingo() {
        return countSelectedNumbers() == numbers.length;
    }
}

class BingoLines {
    //Zeilenindexnummer Array, Indexnummer ist 0 bis 24 fest
    private static final int[][] LINES = new int[][] {
        //Horizontale Linie Vertikale Linie
        { 0,  1,  2,  3,  4}, {0, 5, 10, 15, 20},
        { 5,  6,  7,  8,  9}, {1, 6, 11, 16, 21},
        {10, 11, 12, 13, 14}, {2, 7, 12, 17, 22},
        {15, 16, 17, 18, 19}, {3, 8, 13, 18, 23},
        {20, 21, 21, 23, 24}, {4, 9, 14, 19, 24},
        //Diagonale Linie von links oben nach links unten, von rechts oben nach links unten
        { 0,  6, 12, 18, 19}, {4, 8, 12, 16, 20},
    };
    
    private static BingoLine[] makeBingoLines(SelectableNumbers numbers) {
        return Stream.of(LINES)
                     .map(line -> Arrays.stream(line)
                                        .mapToObj(numbers::getAt)
                                        .toArray(SelectableNumber[]::new))
                     .map(BingoLine::new)
                     .toArray(BingoLine[]::new);
    }

    private final BingoLine[] lines;

    public BingoLines(SelectableNumbers numbers) {
        lines = makeBingoLines(numbers);
    }
    
    public long countReach() {
        return Stream.of(lines).filter(line -> line.isReach()).count();        
    }
    
    public long countBingo() {
        return Stream.of(lines).filter(line -> line.isBingo()).count();        
    }
}

1. Refactoring

Zufallszahlen in 5 Zeilen und 5 Spalten sind auf die Bingokarte geschrieben. Genau genommen ist der Zahlenbereich für jede Spalte festgelegt, aber das interessiert mich nicht. Beim Bingo-Turnier erhält jede Person eine Papierkarte mit einer anderen Nummer, der Veranstalter wählt zufällig einen Ball mit der darauf geschriebenen Nummer aus, und wenn diese Nummer auf der Karte steht, diese Nummer Falten Sie es in den ausgewählten Zustand. Die Karte enthält Zeilen, Spalten und diagonale Zeilen, wobei eine Zeile fünf Zahlen enthält. Wenn alle Zahlen in einer Zeile ausgewählt sind, wird es zu einem "Bingo" und Sie erhalten einen Preis. Der Zustand, ein Bingo zu werden, wenn ein weiteres ausgewählt wird, wird als "Reichweite" bezeichnet.

Die Wörter "Karte", "Nummer" und "Linie" sind aufgetaucht. Machen wir sie also zu den Klassen "Karte", "Nummer" und "Linie". Wenn der Organisator eines Bingoturniers eine Nummer auswählt, sucht er normalerweise nach der Nummer auf seiner eigenen Bingokarte und faltet das Papier, um sie auszuwählen. In der objektorientierten Welt kann die Klasse jedoch anthropomorphisiert und verwendet werden. Ich werde. Leute: Hey Card, hast du diese Nummer? Wenn ja, wählen Sie bitte. Card-Kun: Oh, da war. Zahlen, Sie wurden ausgewählt. Number-Kun: Oh, hast du mich gewählt? Sag mir, wozu du gehörst. Nami-kun: Oh, die ausgewählte Anzahl hat sich um eins erhöht. Card-Kun, die Anzahl der ausgewählten Nummern in Übereinstimmung mit mir ist jetzt vier. Card-Kun: Oh, hatten Sie alle vier, haben Sie eine Reichweite? Bald noch einmal.

Ich habe versucht, eine solche Situation zu programmieren.

Code

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Stream;

//Bingokarte
class Card {

    //Zahlen auf der Bingokarte
    class Number {

        final int value;
        private boolean isSelected = false;
        private final List<Line> lines = new ArrayList<>();

        Number(int value) {
            this.value = value;
        }

        //Gehört zu vertikalen, horizontalen, diagonalen Reihen
        void belong(Line line) {
            lines.add(line);
        }

        //Nummer wurde gewählt
        void selected() {
            if (!isSelected) {
                isSelected = true;
                //Gehören und informieren
                lines.stream().forEach(line -> line.selected());
            }
        }
    }

    //Anordnung auf der Bingokarte (vertikal, horizontal, diagonal)
    class Line {

        private int selectedCount = 0;

        //Die Nummern in der Zeile wurden ausgewählt
        void selected() {
            selectedCount++;
            //Kartenstatus aktualisieren
            judge(this);
        }
    }

    final int size;
    int bingo = 0, reach = 0;
    private final HashMap<Integer, Number> myNumbers = new HashMap<>();

    //Bingokartengenerierung
    Card(int[][] numbers) {
        //Bilden Sie vertikale, horizontale und diagonale Reihen
        size = numbers.length;
        Line[] rowLines = new Line[size];   //Seite an Seite
        Line[] colLines = new Line[size];   //Vertikale Anordnung
        Line backslashLine = new Line();    //Diagonale Anordnung von links oben nach rechts unten
        Line slashLine = new Line();        //Diagonale Anordnung von rechts oben nach links unten
        for (int i = 0; i < size; i++) {    //Initialisieren, da der Inhalt des Arrays leer ist
            rowLines[i] = new Line();
            colLines[i] = new Line();
        }
        //Machen Sie und gehören Sie zu jeder Nummer
        for (int row = 0; row < size; row++) {
            for (int col = 0; col < size; col++) {
                Number number = new Number(numbers[row][col]);
                number.belong(rowLines[row]);
                number.belong(colLines[col]);
                if (row == col) {
                    number.belong(backslashLine);
                }
                if (row == size - col - 1) {
                    number.belong(slashLine);
                }
                myNumbers.put(number.value, number);
            }
        }
    }

    //Wenn es eine Nummer gibt, wählen Sie sie aus
    void selected(int number) {
        Number myNumber = myNumbers.get(number);
        if (myNumber != null) {
            myNumber.selected();
        }
    }

    //Aktualisieren Sie die Anzahl der Reichweiten und das Bingo entsprechend der Anzahl der ausgewählten Nummern in der Zeile
    void judge(Line line) {
        if (line.selectedCount == size - 1) {
            reach++;
        } else if (line.selectedCount == size) {
            reach--;    //Reduzieren Sie es, da es zum Zeitpunkt der Reichweite gezählt wird
            bingo++;
        }
    }
}

//Bingo-Turnier
public class Bingo {

    public static void main(String[] args) throws Exception {
        //Lesen Sie die numerischen Daten der Bingokarte und erstellen Sie eine Bingokarte
        List<String> board = Files.readAllLines(Paths.get("board.txt"));
        int size = board.size();
        int[][] numbers = new int[size][size];
        for (int row = 0; row < size; row++) {
            String[] values = board.get(row).split(" ");
            for (int col = 0; col < size; col++) {
                numbers[row][col] = Integer.parseInt(values[col]);
            }
        }
        Card card = new Card(numbers);
        //Lesen Sie die vom Veranstalter des Bingo-Turniers ausgewählte Zahlenfolge und spiegeln Sie sie auf der Bingokarte wider
        Stream<String> selected = Files.lines(Paths.get("selected.txt"));
        selected.forEach(number -> card.selected(Integer.parseInt(number)));
        //Zeigen Sie den Status der Bingokarte an
        System.out.println("BINGO:" + card.bingo + "\nREACH:" + card.reach);
    }
}

Eingabedatei

biard.txt


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

selected.txt


1
7
13
19
2
3
4

Recommended Posts

Wir haben das "Bingo Judgement Program" überarbeitet.
Bingo-Beurteilungsprogramm
Wir haben die besten Kunststoffe von Dockerfile extrahiert!
Beurteilung des Kalenders