
Java programátor expert
V rámci článkov Ako naprogramovať hru v Java sme si pre teba pripravili známu hru, ktorú sme hrávali už na základnej škole. Úlohou hry je uhádnuť skryté slovo, poprípade viac slov, alebo dokonca celú vetu postupným hádaním písmen, z ktorých sa skladá. Výzva však spočíva v tom, že počet hádaní je dopredu limitovaný množstvom neuhádnutých písmen. Ak počet neúspešných pokusov dosiahne istú hranicu, tak hráč tajničku neuhádol a prehral.
Asi už tušíš o akú hru ide. Je to hra Šibenica (resp. Obesenec alebo Kat), v angličtine známa ako hra Hangman. Dnes si ju budeš môcť naprogramovať vo svojom obľúbenom programovacom jazyku – napr. v Jave.
Hra Obesenec je tipovacia hra pre dvoch alebo viac hráčov, ktorá sa obyčajne hráva s perom a papierom. To sú všetky pomôcky, ktoré hráči potrebujú. Cieľom hry je v písmeno po písmene odhaliť skryté slovo. Jeden z hráčov vymyslí tajničku a naznačí počet jeho písmen nakreslením zodpovedajúcim počtom prázdnych políčok. Zvyšní hráči potom tipujú jednotlivé písmena, ktoré si myslia, že by mohla tajnička obsahovať.
Po každom vyslovenom písmene, prvý hráč zakreslí na všetkých pozíciách tajničky dané písmeno, kde sa v tajničke vyskytuje. Alebo, ak sa písmeno v tajničke nevyskytuje vôbec, tak nakreslí jednu časť obrázka panáčika na šibenici.
Hru vyhrá hráč, ktorý tajničku vymyslel, ak sa druhému hráčovi (alebo hráčom) nepodarí uhádnuť tajničku skôr, ako je tento obrázok domaľovaný do konca. Naopak, ak sa tajnička uhádne skôr, tak hru vyhral hádajúci hráč, resp. spoluhráči.
Presná schéma obrázku panáčika na šibenici a z koľkých častí je zložený nie je súčasťou pravidiel, a tak závisí od dohody hráčov. Obťažnosť hry sa dá rôzne upravovať, napr. okrem spomínaných častí šibenice, sa dajú obmedziť tipy častých spoluhlások a samohlások. Na uľahčenie hry sa môže použiť špecifikácia kategórie, do ktorej slovo patrí, napr. rastliny, zvieratá atď.
Ako a kedy presne hra vznikla nie je známe, predpokladá sa že sa tak stalo v 19. storočí. Na podobnom princípe vzniklo množstvo televíznych súťaží, kde sú súťažiaci za správne tipy písmen a uhádnutie tajničky finančne odmeňovali.
Vedeli ste že?
Hra Obesenec sa často hráva aj na vyučovacích hodinách na škole, napr. v rámci vyučovania cudzích jazykov. Namiesto morbídnej šibenice sa používa jabloň s určitým počtom jabĺk, ktoré sa preškrtávajú alebo zotierajú z tabule.
Keďže Vianoce nedávno skončili, v našej hre budeme hádať výrazy s vianočnou tematikou. Náš program si najskôr načíta zo slovníka (dátového súboru) vianoce.txt nachádzajúci sa na classpath všetky riadky, ktoré budú predstavovať slová, ktoré majú istý súvis s Vianocami. Hra následne náhodne vyberie jedno z nich a zobrazí ho na konzole pomocou podčiarkovníkov oddelených medzerou. Napríklad ak hra vyberie slovo sneh, zobrazí sa na obrazovke ako: _ _ _ _.
Hra vyzve hráča na hádanie písmena, ktoré si myslí, že sa nachádza v tajničke. Písmena, ktoré sa hádajú nemajú žiadne interpunkčné znamienka ako sú dĺžne a mäkčene. Pre zjednodušenie hry sa všetky písmena do tajničky zapisujú veľkými písmenami.
Takže ak hráč napíše do konzole svoj tip, že písmeno je „s“, alebo „S“ (tieto sú ekvivalentné), tak hra ho skonvertuje na veľké písmeno a hľadá v tajničke. V prípade, že hádané písmeno sa v tajničke nachádza, tak ho doplní na všetky relevantné miesta.
Ak sa nenachádza, tak sa miesto kreslenia šibenice bude priebežne vypisovať stav hry – počet písmen slova „KONIEC HRY“, ktoré bude zodpovedať počtu neúspešných tipov písmen, ktoré sa nenachádzali v tajničke.
To znamená, že po 10 neúspešných tipoch sa vypíše celé spojenie „KONIEC HRY“ a kolo hry končí a začne nová hra, s novým vianočným slovom. V našom prípade sa písmeno „S“ v tajničke nachádza, tak sa doplní tajnička o toto písmeno: S _ _ _. Správne uhádnuté písmeno môžeme hráčovi zobraziť zelenou farbou, neuhádnuté písmeno červenou farbou. Neúspešné tipy písmen sa môžu zobraziť na obrazovke modrou farbou oddelené čiarkou.
Hru budeme hrať na predom definovaný počet kôl, ktoré sa zadajú pri vytváraní inštancie hry.
Tento program je jednoduchá konzolová hra, kde si hra vyberie jedno zo slov s vianočnou tematikou a hráč háda písmena, ktoré sa nachádzajú v tajničke. Kolo hry skončí po uhádnutí tajničky alebo po 10 neúspešných tipoch.
Trieda ChristmasHangman
Trieda ChristmasHangman implementuje celkovú hernú logiku s vianočnými frázami.
package games;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class ChristmasHangman {
private static final String COLOR_RESET = "\u001B[0m";
private static final String COLOR_RED = "\u001B[31m";
private static final String COLOR_GREEN = "\u001B[32m";
private static final String COLOR_BLUE = "\u001B[34m";
private List<String> words;
private int rounds;
private static final int MAX_WRONG_GUESSES = 10;
public ChristmasHangman(String dictionaryPath, int rounds) throws IOException {
this.words = Files.readAllLines(Paths.get(dictionaryPath));
this.rounds = rounds;
}
public void startGame() {
Scanner scanner = new Scanner(System.in);
int currentRound = 1;
while (currentRound <= rounds) {
System.out.println("\nKolo " + currentRound + "/" + rounds);
String word = getRandomWord().toUpperCase();
playRound(word, scanner);
currentRound++;
}
System.out.println("\nHra skončila. Ďakujeme za hranie!");
}
private String getRandomWord() {
Random random = new Random();
return words.get(random.nextInt(words.size()));
}
private void playRound(String word, Scanner scanner) {
StringBuilder hiddenWord = initializeHiddenWord(word);
List<Character> wrongGuesses = new ArrayList<>();
int wrongGuessCount = 0;
while (wrongGuessCount < MAX_WRONG_GUESSES) {
System.out.println("\nTajnička: " + hiddenWord);
System.out.println("Zlé tipy: " + formatWrongGuesses(wrongGuesses));
System.out.print("Hádať písmeno: ");
String guess = scanner.nextLine().toUpperCase();
if (guess.length() != 1 || !Character.isLetter(guess.charAt(0))) {
System.out.println("Neplatný vstup! Skús jedno písmeno.");
continue;
}
char guessedChar = guess.charAt(0);
if (hiddenWord.toString().contains(String.valueOf(guessedChar)) || wrongGuesses.contains(guessedChar)) {
System.out.println("Písmeno už bolo hádané! Skús iné.");
continue;
}
if (word.contains(String.valueOf(guessedChar))) {
revealLetter(hiddenWord, word, guessedChar);
System.out.println(COLOR_GREEN + "Písmeno " + guessedChar + " bolo doplnené." + COLOR_RESET);
if (!hiddenWord.toString().contains("_")) {
System.out.println("\nGratulujem! Uhadol si výraz: " + word);
return;
}
} else {
wrongGuesses.add(guessedChar);
wrongGuessCount++;
System.out.println(COLOR_RED + "Písmeno " + guessedChar + " nie je v tajničke." + COLOR_RESET);
System.out.println("Stav: " + "KONIEC HRY".substring(0, wrongGuessCount));
}
}
System.out.println("\nPrehral si! Hľadaný výraz bol: " + word);
}
private StringBuilder initializeHiddenWord(String word) {
StringBuilder hiddenWord = new StringBuilder();
for (char c : word.toCharArray()) {
if (Character.isLetter(c)) {
hiddenWord.append("_ ");
} else {
hiddenWord.append(c).append(" ");
}
}
hiddenWord.deleteCharAt(hiddenWord.length() - 1); // Remove last space
return hiddenWord;
}
private void revealLetter(StringBuilder hiddenWord, String word, char guessedChar) {
for (int i = 0; i < word.length(); i++) {
if (word.charAt(i) == guessedChar) {
hiddenWord.setCharAt(i * 2, guessedChar);
}
}
}
private String formatWrongGuesses(List<Character> wrongGuesses) {
StringBuilder formatted = new StringBuilder();
for (char c : wrongGuesses) {
formatted.append(COLOR_BLUE).append(c).append(COLOR_RESET).append(", ");
}
return formatted.length() > 0 ? formatted.substring(0, formatted.length() - 2) : "žiadne";
}
}
ChristmasHangman(String dictionaryPath, int rounds)
Načíta slová zo súboru vianoce.txt a uloží ich do zoznamu words.
Nastaví počet kôl (rounds).
startGame()
Spustí hru na stanovený počet kôl.
Náhodne vyberie slovo na hádanie a volá metódu playRound().
getRandomWord()
Náhodne vyberie jedno slovo zo zoznamu words.
playRound(String word, Scanner scanner)
Implementuje hlavnú logiku jedného kola hry nasledovne:
Tajnička (hiddenWord) nahrádza písmená podčiarkovníkmi, pričom iné znaky (napr. medzery) ostávajú.
Hráč háda písmená, ktoré sa kontrolujú vo výraze. Správne tipy dopĺňajú tajničku, nesprávne sa evidujú v zozname nesprávnych pokusov. Ak hráč uhádne celé slovo, kolo končí s gratuláciou. Po dosiahnutí maximálneho počtu nesprávnych pokusov sa kolo ukončí prezradením hľadaného výrazu.
initializeHiddenWord(String word)
Vytvorí tajničku: podčiarkovníky pre písmená a ponechanie ostatných znakov.
revealLetter(StringBuilder hiddenWord, String word, char guessedChar)
Nahrádza podčiarkovníky správnym písmenom na všetkých miestach, kde sa nachádza v slove.
formatWrongGuesses(List<Character> wrongGuesses)
Zlúči nesprávne písmená do reťazca s modrou farbou.
Trieda Main
import games.ChristmasHangman;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String dictionary = "vianoce.txt";
int rounds = 10;
try {
ChristmasHangman game = new ChristmasHangman(dictionary, rounds);
game.startGame();
}
catch (IOException e) {
System.out.println("Chyba pri načítavaní slovníka: " + e.getMessage());
}
}
}
Trieda Main skontroluje, že zadaný slovník s výrazmi je k dispozícií, vytvorí inštanciu hry a spustí ju.
Výstup jedného kola hry môže vyzerať nasledovne:
S programom sa dá ďalej pohrať a hádanie výrazov uľahčiť, či naopak sťažiť. Ako cvičenie môžeš skúsiť do hry zabudovať aj štatistiku, koľko kôl hráč vyhrá a koľko z nich naopak prehrá. Taktiež si môžeš vytvoriť rôzne druhy slovníkov na rozličné témy a vyberať tajničku náhodne z viacerých slovníkov s tým, že hádačovi naznačíš, do ktorej kategórie daný výraz patrí.
Stiahni si zdrojové kódy hry ChristmasHangman.