Diskuze: Pomoc s piškvorky (algoritmus pro zjištění vítěze)
V předchozím kvízu, Online test znalostí Java, jsme si ověřili nabyté zkušenosti z kurzu.
pocitac770:14.1.2017 15:40
Je to docela primitivní, dokonce, pokud jde o univerzální kód. Mám tu dokonce dvě možnosti, jedna pochopitelnější, kterou můžeš použít na pochopení celého systému, a jedna "kompaktnější"
Po každém tahu si zavoláš metodu, která projede celou tabulku podle
následujícího systému (bereme souřadnice [x][y], viz obrázek:
Budeš mít 2 proměnné, jedna, která bude ozančovat, který hráč má
"sérii", tzn. u koho počítáš řadu jeho znaků, a druhá, která bude
označovat, kolik jich už v ředě měl.
- vodorovné čáry (oranžová)
Jednoduché, vezmeš si každý prvek pole, který má index [0][?], a kontrolouješ, pokud je tam nějaká značka, pokud ano, tak se koukneš, jestli je to ten samý hráč, co je označen v sérii, pokud ano, nebo žádný ozančen není, pak ho označíš a přičteš v každém případě 1, pokud ne, tak vynuluješ obě. Dál přičteš index [0][+1] a jdeš dál, takto, dokud nenarazíš na index pole, co je mimo hranice (jakýkoliv z dvou). Pokud kdykoliv dojdeš k tvému výhernímu počtu, tak vyhlásíš výherce, ukončíš cyklus i hru.
- svislé (zelená)
stejné jako 1, ale jdeš od [?][0] a přičítáš [+1][0]
- šikmo dolu (modrá)
zde je to už komplikovanější, protože se žádné strany nedotýkají všechny vyznačené čáry. Proto musíš projet obě modré strany. U levé ([0][?]) přičítáš [+1][+1] a u pravé ([MAX][?]) přičítáš [-1][-1]
- šikmo nahoru (červená)
jako 3, ale bereš horní a spodní, u horní ([?][0]) přičítáš [-1][+1], u spodní ([?][MAX]) přičítíš [+1][-1]
Pak jsou tu 2 možnosti, jak to urychlyt, zkrátit. Jednak se nabízí to, že jeden tah ovvlivní pouze to, kde je, tzn. si můžeš zkontrolovat pouze ty čáry, na kterých se tah nachází, stejným systémem jako výše. Dále, máš nějakou délku vítězné série, tzn. stačí zkontrolovat pouze tu část tabulky, která je vzdálená od těch souřadnic tahu (délka - 1)
+20 Zkušeností
+2,50 Kč
David Kroupa:14.1.2017 19:09
Nebyl by nějaký stručný kód pro inspiraci? Vím jak to myslíš, ale programuju teprv chvíli a docela se s tím peru.
1. vodorovné čáry (oranžová)
pocitac770:15.1.2017 18:20
Rovnou jsem tam přidal zlepšení, že nemusíš kontrolovat druhé, pouze toho, který táhl, jak říkám, jde to mnoha způsoby vylepšit, stačí trochu popřemýšlet. Máš to jako příklad toho 1), zbytek si musíš dodělat
public boolean zkontrolovat(){
int serie = 0;
for(int i = 0; i < herniPole.length(); i++){
for(int j = 0; j < herniPole[i].length(); j++){
if(herniPole[i][j] == hrajicihoZnacka){
serie ++;
if(serie == vyherniPocet){
return true;
}
}
else{
serie = 0;
}
}
serie = 0;
}
return false;
}
A pár poznámek, jedna jsem špatně v bodě 1 a 2 napsal to přičítání, je to naopak, dále tenhle kód jsem psal jenom tak z hlavy bez IDE, můžou tam být chyby, a k tvému kódu, v některých místech používáš dynamické hodnoty (přes délku pole), a jindy zase máš hodnoty napsané natvrdo (vypisování do konzole, některé podmínky...) musíš se tedy rozhodnout, jestli to chceš mít krátké, nebo upravitelné (jako že upravíš jednu hodnotu a máš kompletně změněnou velikost tabulky s tím, že všechno pořád funguje jak má). Pak máš nešikovně použité zjišťování délky pole, nerozlišuješ řádky a sloupce.... Co kdyby jsi měl pole o velikosti 10x20? To by jsi například pořád bral hodnotu 20, a dostával by jsi ArrayIndexOutOfBoundsException a nevěděl by jsi, kde je problém. To, jak si bezpečně zjistit ty délky u dvourozměrného pole (i když tohle není skutečné dvourozměrné pole, ale pouze pole polí, u dvourozměrného by to vypadalo ještě trochu jinak) máš v mém kódu.
Díky moc
Jak říkáš toho problému s délkou pole jsem si vědom. Ještě to
upravím.
Já po trošce přemýšlení stvořil tohle, není to uplně ideální, ale
funguje to.
Určitě to ještě upravím podle tebe.
public void vyhra() { //Hledá v poli vítěznou řadu // Kontroluje řádky, pokud nalezne 5 stejných políček za sebou, vyhlásí vítěze
for(int i=0; i<10;i++) { // Projede řadek
for(int j=0; j<6;j++){ // Postoupí o sloupec dolů
if (herniPole[i][j] == hrajicihoZnacka && herniPole[i][j+1] == hrajicihoZnacka && herniPole[i][j+2] ==hrajicihoZnacka
&& herniPole[i][j+3] ==hrajicihoZnacka && herniPole[i][j+4] ==hrajicihoZnacka) {
System.out.printf("Vítězem se stává: [%c]\n",hrajicihoZnacka); // Vyhlásí vítěze, ukončí program
System.exit(0);
}
}
}
for(int i=0; i<6; i++) { // Kontroluje sloupce, pokud nalezne 5 stejných piškvorek pod sebou, vyhlásí vítěze
for(int j=0; j<10; j++) { // Postoupí o sloupec dolů
if(herniPole[i][j] == hrajicihoZnacka && herniPole[i+1][j] == hrajicihoZnacka && herniPole[i+2][j] == hrajicihoZnacka
&& herniPole[i+3][j] == hrajicihoZnacka && herniPole[i+4][j] == hrajicihoZnacka) {
System.out.printf("Vítězem se stává: [%c]\n", hrajicihoZnacka); // Vyhlášení vítěže
System.exit(0); // Ukončení programu
}
}
}
for(int i=0; i<6; i++) { //Kontroluje diagonály ve směru šikmo vpravo dolů
for(int j=0; j<6; j++) {
if(herniPole[i][j] == hrajicihoZnacka && herniPole[i+1][j+1] == hrajicihoZnacka && herniPole[i+2][j+2] == hrajicihoZnacka
&& herniPole[i+3][j+3] == hrajicihoZnacka && herniPole[i+4][j+4] == hrajicihoZnacka) {
System.out.printf("Vítězem se stává: [%c]\n", hrajicihoZnacka); // Vyhlášení vítěže
System.exit(0); // Ukončení programu
}
}
}
for(int i=9; i>4; i--) { //Kontroluje diagonály ve směru šikmo vlevo dolů
for(int j=0; j<6; j++) {
if(herniPole[i][j] == hrajicihoZnacka && herniPole[i-1][j+1] == hrajicihoZnacka && herniPole[i-2][j+2] == hrajicihoZnacka
&& herniPole[i-3][j+3] == hrajicihoZnacka && herniPole[i-4][j+4] == hrajicihoZnacka) {
System.out.printf("Vítězem se stává: [%c]\n", hrajicihoZnacka); // Vyhlášení vítěže
System.exit(0); // Ukončení programu
}
}
}
}
Zobrazeno 5 zpráv z 5.