Java programátor expert
Mastermind je logická hra, ktorá precvičí analytické myslenie a strategické plánovanie. V Jave si ju naprogramujeme od nuly – od generovania tajnej kombinácie farieb až po spätnú väzbu cez ANSI escape kódy. Je to praktická príležitosť precvičiť si cykly, kolekcie a spracovanie vstupu v reálnom projekte.

V článku sa dozvieš:
Mastermind je hra, kde jeden hráč háda tajnú kombináciu farieb – pričom záleží na poradí. Hru hrávajú najčastejšie dvaja hráči, alebo jeden hráč proti počítaču. Tajná kombinácia obsahuje v klasickej verzii štyri farby zo šiestich možných. Existujú aj viacmiestne verzie – napríklad hra Logik, ktorá je populárna na Slovensku a v Čechách, používa päťmiestny kód z ôsmich možných farieb.
Po každom pokuse hráč dostane spätnú väzbu vo forme kolíkov:
Čierny ani biely kolík neprezradí, ktorú konkrétnu farbu hráč tipol správne – to musí odvodiť sám. Hra rozvíja pamäť a schopnosť systematicky vylučovať možnosti na základe predchádzajúcich pokusov.
Hra sa končí, keď hráč uhádne všetky štyri farby na správnych miestach. Hru Mastermind vynašiel v roku 1970 Mordecai Meirowitz, izraelský poštmajster a odborník na telekomunikácie. Po predaji nápadu sa hra rozšírila do celého sveta – dnes existuje viac ako 20 verzií.
…matematická analýza ukázala, že ideálnu kombináciu v klasickej verzii (4 farby zo 6 možných) je možné uhádnuť v maximálne piatich ťahoch, ak sa používa optimálna stratégia? V našej implementácii máš k dispozícii 10 pokusov.
Vytvoríme klasickú verziu hry Mastermind v Jave. Počítač si zvolí tajnú kombináciu štyroch farieb zo šiestich možných, každú použije maximálne raz. Hráč má 10 kôl – v každom zadá štvorznakovú kombináciu. Každá farba je identifikovaná písmenom:
Počítač v rámci každého kola poskytne spätnú väzbu vo forme čiernych a bielych kolíkov. Pre farebnú reprezentáciu na konzole použijeme ANSI escape kódy – každú farbu zobrazíme ako medzeru s farebným pozadím. Hra pokračuje až kým hráč neuhádne kombináciu, alebo nevyčerpá všetky pokusy.
Kompletný kód nájdeš v súbore – stiahnuť zdrojové kódy hry Mastermind.
Program je rozdelený do dvoch tried. Hlavná biznis logika je v triede Mastermind, vstupný bod programu v triede Main. Spolu pokrývajú celý herný cyklus od generovania tajnej kombinácie až po vyhodnotenie výsledku.
Hlavná trieda obsahuje všetky metódy potrebné na riadenie herného cyklu: generovanie tajnej kombinácie, validáciu vstupov, porovnávanie tipov a zobrazenie spätnej väzby.
package games;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Mastermind {
// Game settings
private static final int CODE_LENGTH = 4;
private static final int MAX_ATTEMPTS = 10;
// Define colors and their ANSI escape codes
private static final char[] COLORS = {'R', 'G', 'B', 'Y', 'C', 'M'};
private static final String[] COLOR_CODES = {
"\u001B[41m", // Red
"\u001B[42m", // Green
"\u001B[44m", // Blue
"\u001B[43m", // Yellow
"\u001B[46m", // Cyan
"\u001B[45m" // Magenta
};
private static final String COLOR_RESET = "\u001B[0m";
private static final String BLACK_PEG = "\u001B[40m \u001B[0m"; // Black
private static final String WHITE_PEG = "\u001B[107m \u001B[0m"; // Grey
private List<Character> secretCombination;
public Mastermind() {
this.secretCombination = generateSecretCombination();
}
public void startGame() {
Scanner scanner = new Scanner(System.in);
int attempts = 0;
boolean won = false;
System.out.println("Welcome to Mastermind! Try to guess the secret combination of " + CODE_LENGTH + " colors.");
displayColorLegend();
while (attempts < MAX_ATTEMPTS && !won) {
System.out.print("\nEnter your (" + CODE_LENGTH + " letters) guess: ");
String input = scanner.nextLine().toUpperCase();
if (input.length() != CODE_LENGTH || !isValidInput(input)) {
System.out.println("Invalid input! Please enter exactly " + CODE_LENGTH + " letters from the available colors.");
continue;
}
List<Character> guess = new ArrayList<>();
for (char c : input.toCharArray()) {
guess.add(c);
}
int correctPosition = 0;
int correctColor = 0;
List<Character> tempSecret = new ArrayList<>(secretCombination);
List<Character> tempGuess = new ArrayList<>(guess);
// Count correct positions
for (int i = 0; i < CODE_LENGTH; i++) {
if (guess.get(i).equals(tempSecret.get(i))) {
correctPosition++;
tempSecret.set(i, null);
tempGuess.set(i, null);
}
}
// Count correct colors in wrong positions
for (int i = 0; i < CODE_LENGTH; i++) {
if (tempGuess.get(i) != null && tempSecret.contains(tempGuess.get(i))) {
correctColor++; tempSecret.set(tempSecret.indexOf(tempGuess.get(i)), null);
}
}
// Display feedback with color pegs
System.out.print(formatGuess(guess) + " => ");
for (int i = 0; i < correctPosition; i++) {
System.out.print(BLACK_PEG + " ");
}
for (int i = 0; i < correctColor; i++) {
System.out.print(WHITE_PEG + " ");
}
System.out.println();
if (correctPosition == CODE_LENGTH) {
won = true;
System.out.println("\nCongratulations! You guessed the correct combination: " + formatGuess(secretCombination));
} else {
attempts++;
}
}
if (!won) {
System.out.println("\nYou lost! The correct combination was: " + formatGuess(secretCombination));
}
}
private List<Character> generateSecretCombination() {
Random random = new Random();
List<Character> availableColors = new ArrayList<>();
for (char color : COLORS) {
availableColors.add(color);
}
// Shuffle available colors
Collections.shuffle(availableColors, random);
return availableColors.subList(0, CODE_LENGTH);
}
private boolean isValidInput(String input) {
for (char c : input.toCharArray()) {
boolean valid = false;
for (char color : COLORS) {
if (c == color) {
valid = true;
break;
}
}
if (!valid) return false;
}
return true;
}
private void displayColorLegend() {
System.out.print("Available colors:");
for (int i = 0; i < COLORS.length; i++) {
System.out.print(COLOR_CODES[i] + " " + COLORS[i] + " " + COLOR_RESET);
}
System.out.println();
}
private String formatGuess(List<Character> guess) {
StringBuilder formatted = new StringBuilder();
for (Character color : guess) {
int index = new String(COLORS).indexOf(color);
if (index != -1) { formatted.append(COLOR_CODES[index]).append(" ").append(COLOR_RESET).append("");
} else {
formatted.append(color).append("");
}
}
return formatted.toString();
}
}
Vstupná trieda vytvorí inštanciu hry a spustí ju. Ide o minimalistický kód, ktorý volá metódustartGame().
import games.Mastermind;
public class Main {
public static void main(String[] args) {
Mastermind game = new Mastermind();
game.startGame();
}
}
Logiku hry Mastermind Java môžeme rozdeliť do piatich funkcionálnych celkov. Každý z nich zabezpečuje jednu konkrétnu časť herného cyklu.
Hra pracuje s tromi konfiguračnými parametrami definovanými ako konštanty:
Metóda generateSecretCombination() vytvorí tajnú kombináciu. Najprv zamieša všetky dostupné farby a potom vyberie prvé štyri z nich (bez opakovania farieb). Tajná kombinácia sa uloží do zoznamu secretCombination.
V metóde startGame() program zobrazí uvítaciu správu a zoznam dostupných farieb. Hráč zadáva tipy vo forme reťazca (napr. RGBY). Funkcia isValidInput() kontroluje, či zadaný kód obsahuje len platné farby v správnom počte. Ak nie, program vyzve hráča na opakovanie.
Pre každý tip program vypočíta dve hodnoty: počet správne umiestnených farieb (Black Peg) a počet správnych farieb na nesprávnej pozícii (White Peg). Program najprv identifikuje všetky správne pozície, zo zvyšných farieb následne vypočíta prienik oboch zoznamov. Výsledky sa zobrazia ako farebná spätná väzba po každom pokuse.
Ak hráč uhádne všetky farby na správnych miestach (correctPosition == CODE_LENGTH), hra sa končí výhrou a program zablahoželá. Ak po maximálnom počte pokusov kombinácia ešte nie je uhádnutá, program zobrazí správnu kombináciu.
Výstup jednej hry môže vyzerať nasledovne:

Ak máš vo vývojovom prostredí čiernu konzolu, zmeň si ANSI kód čiernej farby na inú – inak farebné štvorčeky splynú s pozadím a spätná väzba nebude viditeľná.
V našej implementácii nie – každá farba sa vyskytuje maximálne raz. Ak chceš povoliť opakovanie, stačí upraviť metódu generateSecretCombination() tak, aby nevyužívala zamiešavanie, ale náhodný výber s vrátením.
ANSI escape kódy sú štandardný spôsob, ako meniť farbu textu alebo pozadia v termináli na Unix, Mac aj Windows (od verzie 10). Každý kód je reťazec vo formáte \033[Xm, kde X je číslo farby. Počítač ich interpretuje priamo pri výstupe na terminál.
Program najprv odpočíta všetky správne pozície (Black Peg). Zo zvyšných farieb tipu a tajnej kombinácie potom vypočíta prienik – farby, ktoré sa nachádzajú v oboch zoznamoch, ale na iných miestach. Počet týchto spoločných farieb tvorí hodnotu White Peg.
Samozrejme. Podobný prístup (tajný kód, spätná väzba, obmedzenie pokusov) môžeš použiť pre Obesenec, hádanie čísel alebo wordlové hry. Na msgprogramator.sk nájdeš ďalšie tutoriály, napríklad Hádaj číslo, Obesenec a Kameň-papier-nožnice.
Hra Mastermind v Jave je viac ako zábava – v jednom projekte pokrýva základné koncepty OOP: triedy, metódy, kolekcie, cykly a spracovanie vstupu. ANSI kódy pridávajú reálny vizuálny efekt priamo v termináli. Cesta od prázdnej triedy k fungujúcej hre precvičí dosť na to, aby ostalo v pamäti.
Odporúčame ti sa s kódom ďalej pohrať a precvičiť si svoje Java znalosti. Hádanie farebných kombinácií môžeš uľahčiť, či naopak sťažiť. Napríklad môžeš urobiť variant hry Super Mastermind s kombináciou piatich farieb z ôsmich možných. Alebo do našej klasickej verzie doprogramovať možnosť opakovať farby v tajnej kombinácií. Pokročilí programátori môžu do hry vymyslieť algoritmus AI, ktorá bude hádať optimálne kombinácie za hráča na čo najmenší počet ťahov.
Súvisiace články