Pocztkujcy, program lotto

0

Cześć, niedawno zacząłem przygodę z Javą. Chciałbym prosić o opinię i wskazówki jak mogę napisać to prościej. Dopiero się uczę i chciałbym wyrobić sobie dobre praktyki. Kod jest rozwlekły i zapewne mało czytelny. Co poprawić? :) Najbardziej nie podoba mi się redundancja i z jednej strony prosta z drugiej nieczytelna walidacja.

W skrócie:
Program do zabawy w lotto.
Wybieramy przedział liczb z których chcemy wybrać naszą szóstkę. Różnica jak wiadomo musi wynosic przynajmniej 6 pomiędzy min i max
Podajemy pokolei liczby, oczywiście nie mogą się powtarzać i nie mogą wychodzić za przedział.
Komputer losuje unikalne liczby z przedziału.
Porównujemy i wyświetlamy informacje o wygranej

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public class Lotto {
    Scanner input = new Scanner(System.in);

    int min, max;
    int[] player = new int[6];
    int[] comp = new int[6];
    int[] wins = new int[6];

    void setMinMax() {
        System.out.print("Podaj wartość minimalną większą od zera: ");
        min = input.nextInt();
        while (min < 1) {
            System.out.print("Podaj liczbę większą od zera: ");
            min = input.nextInt();
        }

        System.out.print("Podaj wartość maksymalną: ");
        max = input.nextInt();
        while (max < min + 5) {
            System.out.print("Podaj przynajmniej o 5 większą od minimalnej ");
            max = input.nextInt();
        }

        System.out.println("============================================");
        System.out.println("Wartość minimalna w grze: " + min + ", maksymalna: " + max);
        System.out.println("============================================");
    }

    void setNumbers() {
        System.out.print("Podaj pierwszą liczbę z przedziału od " + min + " do " + max + ": ");
        player[0] = input.nextInt();
        while (player[0] < min || player[0] > max) {
            System.out.print("Podaj liczbę z wybranego przedziału: ");
            player[0] = input.nextInt();
        }

        System.out.print("Podaj drugą liczbę: ");
        player[1] = input.nextInt();
        while (player[1] == player[0] || player[1] < min || player[1] > max) {
            while (player[1] == player[0]) {
                System.out.print("Podana liczba została już przez Ciebie podana, podaj inną: ");
                player[1] = input.nextInt();
            }
            while (player[1] < min || player[1] > max) {
                System.out.print("Podaj liczbę z wybranego przedziału: ");
                player[1] = input.nextInt();
            }
        }

        System.out.print("Podaj trzecią liczbę: ");
        player[2] = input.nextInt();
        while (player[2] == player[0] || player[2] == player[1] || player[2] < min || player[2] > max) {
            while (player[2] == player[0] || player[2] == player[1]) {
                System.out.print("Podana liczba została już przez Ciebie podana, podaj inną: ");
                player[2] = input.nextInt();
            }
            while (player[2] < min || player[2] > max) {
                System.out.print("Podaj liczbę z wybranego przedziału: ");
                player[2] = input.nextInt();
            }
        }

        System.out.print("Podaj czwartą liczbę: ");
        player[3] = input.nextInt();
        while (player[3] == player[0] || player[3] == player[1] || player[3] == player[2] || player[3] < min || player[3] > max) {
            while (player[3] == player[0] || player[3] == player[1] || player[3] == player[2]) {
                System.out.print("Podana liczba została już przez Ciebie podana, podaj inną: ");
                player[3] = input.nextInt();
            }
            while (player[3] < min || player[3] > max) {
                System.out.print("Podaj liczbę z wybranego przedziału: ");
                player[3] = input.nextInt();
            }
        }

        System.out.print("Podaj piątą liczbę: ");
        player[4] = input.nextInt();
        while (player[4] == player[0] || player[4] == player[1] || player[4] == player[2] || player[4] == player[3] || player[4] < min || player[4] > max) {
            while (player[4] == player[0] || player[4] == player[1] || player[4] == player[2] || player[4] == player[3]) {
                System.out.print("Podana liczba została już przez Ciebie podana, podaj inną: ");
                player[4] = input.nextInt();
            }
            while (player[4] < min || player[4] > max) {
                System.out.print("Podaj liczbę z wybranego przedziału: ");
                player[4] = input.nextInt();
            }
        }

        System.out.print("Podaj szóstą liczbę: ");
        player[5] = input.nextInt();
        while (player[5] == player[0] || player[5] == player[1] || player[5] == player[2] || player[5] == player[3] || player[5] == player[4] ||player[5] < min || player[5] > max) {
            while (player[5] == player[0] || player[5] == player[1] || player[5] == player[2] || player[5] == player[3] || player[5] == player[4]) {
                System.out.print("Podana liczba została już przez Ciebie podana, podaj inną: ");
                player[5] = input.nextInt();
            }
            while (player[5] < min || player[5] > max) {
                System.out.print("Podaj liczbę z wybranego przedziału: ");
                player[5] = input.nextInt();
            }
        }

        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = new Date();

        System.out.println("============ KUPON " + dateFormat.format(date) + " ============");
        System.out.println("Wybrane przez Ciebie liczby to: " + player[0] + ", " + player[1] + ", " + player[2] + ", " + player[3] + ", " + player[4] + ", " + player[5]);
        System.out.println("===================================================");
    }

    void lottery() {
        Random generator = new Random();
        comp[0] = generator.nextInt(max) + min;

        comp[1] = generator.nextInt(max) + min;
        while (comp[0] == comp[1]) {
            comp[1] = generator.nextInt(max) + min;
        }

        comp[2] = generator.nextInt(max) + min;
        while (comp[2] == comp[0] || comp[2] == comp[1]) {
            comp[2] = generator.nextInt(max) + min;
        }

        comp[3] = generator.nextInt(max) + min;
        while (comp[3] == comp[0] || comp[3] == comp[1] || comp[3] == comp[2]) {
            comp[3] = generator.nextInt(max) + min;
        }

        comp[4] = generator.nextInt(max) + min;
        while (comp[4] == comp[0] || comp[4] == comp[1] || comp[4] == comp[2] || comp[4] == comp[3]) {
            comp[4] = generator.nextInt(max) + min;
        }

        comp[5] = generator.nextInt(max) + min;
        while (comp[5] == comp[0] || comp[5] == comp[1] || comp[5] == comp[2] || comp[5] == comp[3] || comp[5] == comp[4]) {
            comp[5] = generator.nextInt(max) + min;
        }

        System.out.println("Komora maszyny losującej jest pusta");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }

        System.out.println("Zwalniamy blokadę");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }

        System.out.println("Losujemy sześć liczb z przedziału od " + min + " do " + max);
        try {
            Thread.sleep(3000);
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }

        System.out.println("Oto wylosowane liczby: " + comp[0] + ", " + comp[1] + ", " + comp[2] + ", " + comp[3] + ", " + comp[4] + ", " + comp[5]);
    }

    void check() {

        int i = 0;
        for (int j = 0; j < 6; j++) {
            for (int z = 0; z < 6; z++) {
                if (player[j] == comp[z]) {
                    wins[i] = player[j];
                    i++;
                }
            }
        }
    }

    void result() {

        int i = 0;
        int j = 0;
        boolean z = false;

        for (int x : wins) {
            if (x != 0) {
                z = true;
            }
        }

        if (z == true) {
            System.out.print("Trafiłeś następujące liczby: ");
        }

        for (int x : wins) {
            if (x == 0) {
                continue;
            } else {
                if (i == 0) {
                    System.out.print(x);
                    i++;
                    j++;
                } else {
                    System.out.print(", " + x);
                    j++;
                }
            }
        }

        System.out.println("\n===================================================");

        switch (j) {
            case 0:
                System.out.println("Niestety nie trafiłeś ani jednej liczby");
                break;
            case 1:
                System.out.println("Trafiłeś jedną liczbę, niestety nie daje to wygranej");
                break;
            case 2:
                System.out.println("Trafiłeś dwie liczby, niestety nie daje to wygranej");
                break;
            case 3:
                System.out.println("Trafiłeś trójkę! Twoja wygrana to 24 zł");
                break;
            case 4:
                System.out.println("Trafiłeś czwórkę! Twoja wygrana to 200 zł!");
                break;
            case 5:
                System.out.println("Trafiłeś piątkę! Twoja wygrana to 6000 zł!");
                break;
            case 6:
                System.out.println("Trafiłeś szóstkę! Jesteś MILIONEREM!");
                break;

        }
        System.out.println("===================================================");

    }

    public static void main(String args[]) {
        Lotto coupon = new Lotto();
        coupon.setMinMax();
        coupon.setNumbers();
        coupon.lottery();
        coupon.check();
        coupon.result();

    }
}

5

user image
Następnie napisz to w troszeczkę zmienionej wersji: niech ilość liczb będzie zadana zmienną N. To znaczy nie masz konkretnie 6 liczb, tylko N liczb. Bez górnego limitu. Może wtedy właczysz myślenie a nie będziesz kopiował kodu...

0

Dzięki. A jak najlepiej np. przy podawaniu 6. liczby sprawdzić czy już wcześniej nie została podana?

0

Użyć kolekcji HashSet która pozwala w czasie stałym sprawdzić czy juz dana liczba nie została do niej dodana.
http://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html

Set<Integer> set = new HashSet<Integer>();
set.add(1);
set.add(2);
if(set.contains(1)){
    //zawiera! ;)
}
0

Dzięki :) Jeszcze do tego nie doszedłem, w sumie ćwiczę sobie póki co to co do tej pory przeczytałem :) Mam nadzieję, że wrócę tu wkrótce z eleganckim kodem :D

0

Lol... pewnie na studiach uczą pisać ten jakże elegancki kod.. ;)

0

@bakeraw2: zapewne Ty po hello world pisałeś już obiektowo i profesjonalny, czysty kod?
Napisał chłopak, że się dopiero uczy. Dobrze, że jest świadom, iż po napisaniu 2 programów nie jest się już najlepszym programistą, tylko pyta o poradę i wskazówki, co by w przyszłości unikać takich właśnie sytuacji :) Na początku nauki liczy się, żeby to działało, nie ważne jak... potem dopiero zajmować się poprawkami kodu. Nie od razu tak łatwo wyrażać myśli w programowaniu, jeżeli wcześniej się nie miało z tym styczności.

ps. Co do studiów - na studiach nawet nie uczą programować.. u mnie na 1 semestrze tylko wymagają, a na drugim semestrze były tylko wykłady, na których opowiadali jak się deklaruje zmienne i funkcje :P

0

Tak jak napisał Shalom, fajnie byłoby przechowywać max 6 liczb, w ramach treningu możesz napisać swoją klasę która dziedziczy po TreeSet (domyślnie sortuje liczby w kolejności rosnącej) ale przyjmuje max 6 liczb. Przykład :

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

class LiczbyLotto extends TreeSet<Integer> {
	
	public LiczbyLotto() {
		min = 1;
		max = 49;
		System.out.println("Lotto");
	}
	
	public LiczbyLotto(int min, int max) {
		this.min = min;
		this.max = max;
		System.out.println("Lotto");
	}
	
	public boolean dodajLiczbe(int a) {
		if(this.size() >= 6)
			return false;
		
		if(a < min || a > max)
			return false;
	
		return add(a);
	}
	
	public void wprowadzLiczby() {
		 Scanner input = new Scanner(System.in);
		 String liczbyStr[] = {"pierwsza", "druga", "trzecia", "czwarta", "piata", "szosta"};
		 
		 for(int i = 0 ; i < 6 ; i++) {
			 int in;
			 do {
				 System.out.print("Podaj " + liczbyStr[i] + " liczbe : ");
				 in = input.nextInt();
			 }while(!dodajLiczbe(in));
		 }
	}
	
	@Override
	public String toString() {
		String result = "[ ";
		for(Integer i : this) {
			result += String.valueOf(i);
			
			//Dodaje przecinek po kazdej oprocz ostatniej liczby
			if(i != this.last())
				result += ", ";
		}
		
		result += " ]";
		return result;
	}

	private final int iloscLiczb = 6;
	private int min, max;
}

Wtedy w programie glownym odpalamy :

public class Lotto {
	 public static void main(String args[]) {
		 LiczbyLotto coupon = new LiczbyLotto(1, 49);
		 coupon.wprowadzLiczby();
	         System.out.println(coupon.toString());
	 }
}

Dodawanie liczb jest zrobione tak, ze wyrzuca false gdy liczba juz istnieje/jest juz 6 liczb/jest z poza zakresu. Przykladowe dzialanie programu :

Lotto
Podaj pierwsza liczbe : 37
Podaj druga liczbe : 	15
Podaj trzecia liczbe : 	49
Podaj czwarta liczbe : 	2
Podaj piata liczbe : 	1000
Podaj piata liczbe : 	10
Podaj szosta liczbe : 	-2
Podaj szosta liczbe : 	2
Podaj szosta liczbe : 17
[ 2, 10, 15, 17, 37, 49 ]
0

@evensense ciekawa propozycja ale źle zaimplementowana moim zdaniem. Bo kupon lotto nie jest szczególnym przypadkiem TreeSet! Powinieneś tu zrobić delegacje a nie dziedziczenie. Tzn KuponLotto powinien zawierać w sobie odpowiedniego seta. Poza tym ilość liczb też zadałbym parametrem a nie ustawiał na sztywno na 6. No i aż się prosi te "for" zamienić na Java 8 Stream API! Np. ten toString:

return this.stream().map(Object::toString).collect(Collectors.joining(","));

(oczywiście ten this powinien zniknąć i zastąpi go nazwa pola klasy przechowująca agregowany set!)

0

Póki co to co podpowiadasz Shalom jest dla mnie niejasne. Mam nadzieję, że ogarnę to wkrótce :-) zastanawiam się nad kolejnymi zadaniami do pocwiczenia. Mam problem z wymyśleniem sobie czegoś do napisania do pocwiczenia w miarę na moim poziomie. Macie jakieś pomysły? Bo ja albo sobie wymyślam za proste albo takie, że dochodzę do momentu, że nie wiem kompletnie co dalej. Może ktoś ma coś do napisania na studia na wrzesień? :-D kwestie sumienia pozostawiam, ja natomiast chętnie pocwicze i może kogoś wyrecze. Wiecie co jest jeszcze śmieszne? Jestem teraz na stażu i klepie w php ale szczerze mówiąc dostaje same bzdety, nic ambitnego i w miedzy czasie dłubie na boku w javie

1

Ty tak poważnie? Jesteś na stażu, tzn że klepiesz w jakieś firmie i jednocześnie robisz takie ifologie i copy-paste i nie wiesz co to jest HashSet? o_O Brak mi słów.

0

Jestem jeszcze na studiach, nie miałem tego. Zresztą w ogóle na studiach miałem bardzo niewiele programowania... Nie czuje jakbym odbiegal specjalnie wiedzą od kolegów z roku...

0

No to "miej" to i po problemie ;)

0

No uczę się przecież nie wiem tylko po co to "dobijanie" :>

0

Bo tłumaczenie się słowami, że "jeszcze tego nie miałem" jest śmieszne...

0

A co w tym śmiesznego? Nie miałem tego i tyle. Dopiero się uczę. A co do stażu to najpierw byłem na bezpłatnej praktyce i mnie wzięli na płatny staż. Na studiach miałem wszystkiego po trochu dopiero teraz uczę się sam czegoś konkretnego.

3

zastanów się nad korzystaniem z różnych fajnych javowych kolekcji;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

class LottoMachine {
    List<Integer> numbers;

    public LottoMachine(int maxNum) {
        numbers = IntStream.range(1, maxNum + 1)
                .boxed().collect(Collectors.toList());
    }

    public Set<Integer> drawResults(int nOfNums) {
        Collections.shuffle(numbers);
        return numbers
                .stream()
                .limit(nOfNums)
                .collect(Collectors.toSet());
    }
}

public class MainApp {
    public static void main(String[] args) {
        LottoMachine lottoMachine = new LottoMachine(49);
        Set<Integer> ticket = new TreeSet<>(Arrays.asList(5,45,25,4,19,4));
        Set<Integer> lotteryResult = lottoMachine.drawResults(6);
        System.out.println("Wyniki: " + lotteryResult);
        ticket.retainAll(lotteryResult);
        System.out.println("Trafiles: " + ticket);
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1