package adamira.cz; import sugar.Sys; public class Dama { // hraci pole final static int sirka = 8; // a .. h (zleva doprava) final static int vyska = 8; // 1 .. 8 (zdola nahoru) static char[][] pole = new char[sirka][vyska]; // znaky, pouzite v hracim poli final static char znakNic = '.'; // volne policko final static char znakJa1 = 'j'; // jeden kamen hrace final static char znakJa2 = 'J'; // dva kameny (dama) hrace final static char znakPC1 = 'p'; // jeden kamen pocitace final static char znakPC2 = 'P'; // dva kameny (dama) pocitace /////////////////////////////////////////////////////////////////////////////// // metoda, ktera nasadi vsechny kameny na hraci pole static void nasadit() { for (int i = 0; i < sirka; i++) for (int j = 0; j < vyska; j++) pole[i][j] = znakNic; for (int i=0; i= 0; j--) { Sys.p(' '); Sys.p(j+1); for (int i = 0; i < sirka; i++) { Sys.p(' '); if (i % 2 == j % 2) // zobrazim pouze pole, na kterych se hraje Sys.p(pole[i][j]); else Sys.p(" "); // na ostatnich pozicich je mezera } Sys.pln(); } Sys.p(" "); for (int i = 0; i < sirka; i++) { Sys.p(' '); Sys.p((char) (i + 'a')); } Sys.pln(); } /////////////////////////////////////////////////////////////////////////////// // funkce signum (znamenko) static int signum(int x) { if (x < 0) return -1; if (x > 0) return 1; return 0; } /////////////////////////////////////////////////////////////////////////////// // funkce, ktera zkontroluje, zdaje zadany tah napsany spravne (syntaxi) a // zda je mozne tento tah provest. Pokud ne, vrati hodnotu 0. Pokud ano, // vrati ciselnou hodnotu, predstavujici vyhodnost tohoto tahu (napr. // vyhozeni damy predstavuje vyhodnost 10, vyhozeni kamene = 1). static int zkontrolujTah(boolean hrajePC, String tah) { // prevedu retezec na ciselne souradnice if (tah.length() != 5) return 0; int x1 = tah.charAt(0) - 'a'; int y1 = tah.charAt(1) - '1'; int x2 = tah.charAt(3) - 'a'; int y2 = tah.charAt(4) - '1'; // kontrola rozsahu zadanych souradnic, // zda je volne ciloveho pole // a zda tah probiha po diagonale if (x1 < 0 || y1 < 0 || x1 >= sirka || y1 >= vyska || // tah - odkud x2 < 0 || y2 < 0 || x2 >= sirka || y2 >= vyska || // tah - kam pole[x2][y2] != znakNic || // cilove pole musi byt volne (x2 - x1 != y2 - y1 && x2 - x1 != y1 - y2)) // tah po diagonale return 0; // kontrola: kdo hraje? (hrac / pocitac) if ((hrajePC && !jeZnakPC(x1, y1)) || (!hrajePC && !jeZnakJa(x1, y1))) return 0; // tah jednoduchym kamenem if (pole[x1][y1] == znakJa1 || pole[x1][y1] == znakPC1) { // vyhodne je vytvorit si damu (tak, ze dojdu na konec hraciho pole) int vyhodnost = 0; if ((hrajePC && y2 == 0) || (!hrajePC && y2 == vyska - 1)) vyhodnost = 10; // pouhy posun o jeden dilek (po diagonale) if ((!hrajePC && y2 == y1 + 1) || (hrajePC && y2 == y1 - 1)) return 1 + vyhodnost; // vyhozeni kamene protihrace if ((!hrajePC && y2 == y1 + 2) || (hrajePC && y2 == y1 - 2)) { char coVyhazuji = pole[(x1 + x2) / 2][(y1 + y2) / 2]; if (hrajePC) { if (coVyhazuji == znakJa1) return 2 + vyhodnost; if (coVyhazuji == znakJa2) return 11 + vyhodnost; } else { if (coVyhazuji == znakPC1) return 2 + vyhodnost; if (coVyhazuji == znakPC2) return 11 + vyhodnost; } } } // tah dvojitym kamenem (damou) if ((pole[x1][y1] == znakJa2 || pole[x1][y1] == znakPC2) && x1 != x2) { int smerX = signum(x2 - x1); int smerY = signum(y2 - y1); int vzdalenost = (x2 - x1) * smerX; int vyhodnost = 1; for (int i = 1; i < vzdalenost; i++) { int x = x1 + i * smerX; int y = y1 + i * smerY; // zadny hrac nemuze vyhazovat sam sebe if ((hrajePC && jeZnakPC(x, y)) || (!hrajePC && jeZnakJa(x, y))) return 0; // ohodnotim vyhozeny kamen if (pole[x][y] == znakPC1 || pole[x][y] == znakJa1) vyhodnost += 1; if (pole[x][y] == znakPC2 || pole[x][y] == znakJa2) vyhodnost += 10; } return vyhodnost; } return 0; } /////////////////////////////////////////////////////////////////////////////// // metoda, ktera provede zadany tah static void provedTah(String tah) { int x1 = tah.charAt(0) - 'a'; int y1 = tah.charAt(1) - '1'; int x2 = tah.charAt(3) - 'a'; int y2 = tah.charAt(4) - '1'; pole[x2][y2] = pole[x1][y1]; if (y2 == 0 && pole[x2][y2] == znakPC1) pole[x2][y2] = znakPC2; // vytvorim damu pocitace if (y2 == vyska - 1 && pole[x2][y2] == znakJa1) pole[x2][y2] = znakJa2; // vytvorim damu lidskeho hrace int smerX = signum(x2 - x1); int smerY = signum(y2 - y1); int vzdalenost = (x2 - x1) * smerX; for (int i = 0; i < vzdalenost; i++) pole[x1 + i * smerX][y1 + i * smerY] = znakNic; } /////////////////////////////////////////////////////////////////////////////// // metoda, ktera najde nejvyhodnejsi tah (vyhozeni damy, vyhozeni kamene...) static String nejlepsiTah(boolean pocitace) { int nejVyhodnost = 0; String nejTah = ""; for (int x1 = 0; x1 < sirka; x1++) for (int y1 = 0; y1 < vyska; y1++) if ((pocitace && jeZnakPC(x1, y1)) || (!pocitace && jeZnakJa(x1, y1))) for (int x2 = 0; x2 < sirka; x2++) for (int y2 = 0; y2 < vyska; y2++) { String tah = tahNaString(x1, y1, x2, y2); int vyhodnost = zkontrolujTah(pocitace, tah); if (vyhodnost > nejVyhodnost || // pokud je nekolik tahu stejne vyhodnych, vybiram nahodne (vyhodnost == nejVyhodnost && vyhodnost > 0 && Math.random() < 0.25) ) { nejVyhodnost = vyhodnost; nejTah = tah; } } return nejTah; } /////////////////////////////////////////////////////////////////////////////// // hlavni metoda public static void main(String[] args) { // nasadim kameny na vychozi pozice nasadit(); // cyklus jednotlivych tahu while (true) { // zobrazim hraci pole Sys.pln(); zobraz(); Sys.pln(); // prectu z klavesnice tah hrace a provedu jej String tah; while (true) { // nactu z klavesnice tah hrace Sys.p("Zadejte tah (napr. 'a2 b3' nebo 'auto'): "); tah = Sys.readLine().toLowerCase(); // velka pismena prevedu na mala // vygeneruji automaticky tah if (tah.compareTo("auto") == 0) { tah = nejlepsiTah(false); Sys.pln(); if (tah.length() == 0) Sys.pln("Nemuzete tahnout zadnym kamenem! PROHRAL JSTE."); else Sys.pln("Automaticky tah: " + tah); } // konec hry if (tah.length() == 0) break; // provedu zadany tah if (zkontrolujTah(false, tah) > 0) { provedTah(tah); break; } } // konec hry if (tah.length() == 0) break; // zobrazim hraci pole Sys.pln(); zobraz(); Sys.pln(); // najdu nejvyhodnejsi tah pocitace tah = nejlepsiTah(true); // pocitac jiz nemuze tahnout => konec if (tah.length() == 0) { Sys.pln("Pocitac nemuze tahnout zadnym kamenem. VYHRAL JSTE."); break; } // zobrazim a provedu tah pocitace Sys.pln("Tah pocitace: " + tah); provedTah(tah); } // konec hry Sys.pln(); Sys.pln("===== KONEC ====="); } }