Kumusta mga kaibigan at mga kasamahan sa hinaharap! Kamakailan lang, kumuha ako ng pagsusulit para makasali sa isang tunay na proyekto, naipasa ko ito, ngunit nagkataon na dahil sa mga personal na pangyayari ay hindi ako nakasali sa mismong RP. Pagkatapos ng mga kagiliw-giliw na problema tulad ng pagsusulit sa RP, ang karaniwang mga problema sa kurso ay naging hindi gaanong kaakit-akit na libangan, lalo na't nalutas ko na ang karamihan sa mga ito. Samakatuwid, upang hindi masayang ang aking talento sa patuloy na pag-aaral, nagpasya akong lumikha ng isang multiplayer web game. Mga link sa iba pang laro:
Tic Tac Toe tila ang pinakasimpleng laro para sa akin, kaya nagpasya akong hatiin ang gawain sa ilang mga subtask:
Ang pinakaunang algorithm ay sinusuri ang buong field
- Console application para sa pagsubok ng lohika ng laro
- Multiplayer
- Pag-attach ng database ng player sa isang console application
- Paglikha ng front-end na disenyo, pagsusulat ng mga template ng pahina, interface ng laro
- Pinagsasama-sama ang lahat
- patlang
- dalawang manlalaro na humalili, ang isa ay naglalagay ng krus, ang pangalawa ay zero. ito ay simple.
String[][] strings = {{"O", "O", "_"},
{"_", "X", "O"},
{"X", "X", "X"},
for (String [] ss : strings){
for (String s : ss) System.out.print(s + " ");
System.out.println(); //для перевода строки
}
ipapakita ng screen ang:
O O _
_ X O
X X X
Ngunit bilang karagdagan sa pagpapakita, mayroon din kaming paghahambing ng mga halaga, at dito posible na ang mga opsyon. Maaari mong ihambing ang mga string, maaari kang lumikha ng isang espesyal na klase ng enumeration ( enum
), ngunit mas gusto kong ihambing ang mga numero, at palitan ang mga ito ng "X" at "O" lamang kapag ipinapakita sa screen. Hayaan ito, halimbawa, 1 - "X", 2 - "O", 0 - "_". Kaya, paano mo susuriin ang isang field para sa isang triple X o O na tugma?
Ang pinakaunang algorithm ay sinusuri ang buong field
int[][] canvas = {{00, 01, 02},
{10, 11, 12},
{20, 21, 22}}
Mga panalong kumbinasyon:
00-01-02, 10-11-12, 20-21-22, 00-10-20, 01-11-21, 02-12-22, 00-11-22, 20-11-02 — всего 8.
Pagsuri sa pamamagitan ng paghahambing ng mga numero, ngunit lumalabas na kailangan mong suriin ang BUONG field, lahat ng 8 kumbinasyon, sa bawat oras. Siyempre, hindi ito magkano, hindi ito isang paghahanap para sa mga numero ng Armstrong sa saklaw mula 0 hanggang 1 bilyon, mayroong kaunti pa kaysa sa walang mga kalkulasyon dito, ngunit nais mo pa rin ang isang bagay na mas mahusay kaysa sa pagsuri sa buong larangan. Ang pangalawang ideya na dumating sa akin ay suriin lamang ang cell na minarkahan sa nakaraang paglipat, upang matukoy pa rin natin ang nanalo, dahil malalaman natin kung sino ang gumawa ng hakbang na ito. Kaya, sa halip na lahat ng 8 kumbinasyon, nakakakuha lamang tayo ng 2, 3 o 4 na kumbinasyon, depende sa cell, tingnan ang larawan: Ngayon kailangan nating malaman kung paano matukoy kung aling kumbinasyon ang kailangang ilunsad? Dito ko napagtanto na ang paggamit ng two-dimensional array ay hindi masyadong maginhawa. Nagpasya akong isaalang-alang ang iba pang mga pagpipilian. Sa una ay nagkaroon ako ng ideya na ang field ay maaaring itago sa isang siyam na digit na numero, halimbawa, ang parehong field na ipinakita namin sa screen ay maaaring isulat ng ganito: 220012111, ipapaliwanag ko sa aking mga daliri kung ano ito ay... Ang code ay pareho, 1 - “X”, 2 - “O” , 0 – " ", na nangangahulugang 220012111 = "OO__XOXXX", o kung pagkatapos ng bawat ikatlong digit ay nagpasok ka ng line break at magdagdag ng mga puwang para sa kalinawan:
О О _
_ Х О
Х Х Х
dito muli, maginhawa para sa imbakan, isang aparato para sa pagpapakita ay naimbento, ngunit hindi maginhawa para sa paghahambing! Ang solusyon ay natagpuan noong binilang ko ang mga cell 1-9, pagkatapos ay naisip ko, dahil sa programming ang countdown ay nagsisimula sa 0 at binibilang ito tulad ng sa larawan. Hindi mo ba napansin ang anumang mga kakaiba? kung titingnan mo ang larawan sa itaas, magiging malinaw na ang mga solusyon na may 2 kumbinasyon ay may kakaibang serial number, 4 na kumbinasyon ay may serial number 4, 3 kumbinasyon ang natitira. Kaya't dumating ako sa konklusyon na kailangan mong panatilihin ang larangan ng paglalaro sa isang regular na hanay ng mga numero: simpleng pag-ulit sa pagitan ng mga numero, ang kakayahang maghambing ayon sa algorithm na napili, simpleng output sa screen. Tulad ng para sa paghahambing algorithm mismo. Pumunta tayo sa pagkakasunud-sunod: sa lahat ng mga pagpipilian mayroong isang tseke ng hilera at haligi, ang mga ito lamang ang sinusuri namin. kung ang paghahanap ay hindi nagreresulta, sinusuri namin ang numero ng cell para sa kahit na / kakaiba, kung ito ay kakaiba, pagkatapos ay bumalik kami sa laro, walang saysay na suriin pa, kung ito ay kahit na, tinitingnan namin kung ang cell na ito ay namamalagi sa kaliwang dayagonal, ang mga numero ng dayagonal na ito kapag hinati sa 4 ay may natitirang 0. Kung ito ay kasinungalingan, tinitingnan namin ang mga tugma, kung walang nakitang mga tugma, pagkatapos ay tinitingnan namin ang numero 4, kung hindi, bumalik sa laro, kung oo, dumaan pa kami sa code at ibabalik ang resulta ng pagsuri sa huling dayagonal. Marahil, para sa isang hindi handa na tao, mahirap itong maunawaan pagkatapos basahin ang hanay ng mga titik sa itaas, ngunit maaaring sabihin ng isang tao na maraming mga titik sa code mismo, na maaaring maging mas simple, ikalulugod kong talakayin ito. Inayos namin ang field, ngayon kailangan naming harapin ang dalawang user na humalili at bawat isa sa kanila ay may sariling sign, X o O. Sa unang yugto, wala kaming anumang multi-user functionality, kaya ang ang pinakamadaling paraan ay ang paggamit ng mga icon nang paisa-isa. Palaging si X ang gumagawa ng unang galaw, palaging ginagawa ni O ang pangalawa, pagkatapos ay muli ang X, at iba pa. Ito ay humihiling na suriin ( true/false ), at kung totoo – kung gayon ang kasalukuyang manlalaro ay X, kung mali – pagkatapos ay O at sa simula ng bawat galaw flag=!flag Ito ay nananatiling kahit papaano ay tumanggap ng senyales mula sa mga manlalaro tungkol sa kung alin cell na kanilang pinili. Dito kakailanganin namin ang aming hindi malilimutang BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
mga Manlalaro ay ipasok ang mga numero ng cell sa console, at ang pagpindot sa Enter ay gagawa ng isang hakbang. Ang cell na naaayon sa ipinasok na numero ay babaguhin ang halaga nito mula 0 hanggang 1 o 2, depende sa kasalukuyang estado ng checkbox, na tinalakay sa talata sa itaas. Dito mahalaga na i-validate ang input para walang makapagpalit ng X sa O kapag napuno na ang cell :) Ano ang maipasok ng player sa console?
- walang laman na linya
- mga titik, mga bantas, mga bracket... sa isang salita, hindi mga numero
- maling mga numero - negatibo o sa labas ng laki ng array, mga cell na inookupahan.
Integer.parseInt("2");
Naghagis ito ng exception NumberFormatException
kung hindi ito makakuha ng digit mula sa isang string. Maaari tayong magbigay ng proteksyon mula sa unang dalawang puntos sa pamamagitan ng pagharang sa exception na ito. Para sa pangatlong punto, gagawa ako ng isa pang paraan na sumusuri sa inilagay na halaga, ngunit ito ay pinakatama na ilipat ang kahilingan ng string sa isang hiwalay na paraan kung saan isasagawa ang pagpapatunay, at magbabalik lamang ito ng isang numero. Upang buod, gumawa kami ng field, gumawa ng paraan na nagpapakita nito, gumawa ng paraan na nagsusuri ng "kung nanalo ba ang manlalarong ito sa loob ng isang oras?", at napatunayan ang mga inilagay na numero. Napakakaunti na lang ang natitira, tingnan kung may draw - isang hiwalay na paraan na tumatakbo sa array at naghahanap ng 0, at ipinapakita ang mga resulta ng laro. Iyon lang, handa na ang code, ang laro ay naging maliit, isang klase lamang, kaya ang mga mahihirap na copy-pasters ay maaaring, nang walang pag-unawa, kopyahin lamang ang lahat sa kanilang proyekto at patakbuhin ito sa kanilang sarili, ako mismo ay ganoon, ngunit ngayon sinusubukan kong huwag gawin iyon at hindi sa sinumang inirerekumenda ko ito :) Good luck sa lahat sa pag-aaral ng JAVA! ps the rest of the points - multiplayer and database will come later, sinimulan ko na pag-aralan ang material :)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class GameField {
static int [] canvas = {0,0,0,
0,0,0,
0,0,0};
//012, 345, 678, 036, 147, 258, 048, 246
public static void main(String[] args){
boolean b;
boolean isCurrentX = false;
do {
isCurrentX = !isCurrentX;
drawCanvas();
System.out.println("mark " + (isCurrentX ? "X" : "O"));
int n = getNumber();
canvas[n] = isCurrentX ? 1 : 2;
b = !isGameOver(n);
if (isDraw()){
System.out.println("Draw");
return;
}
} while (b);
drawCanvas();
System.out.println();
System.out.println("The winner is " + (isCurrentX ? "X" : "O") + "!");
}
static int getNumber(){
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true){
try {
int n = Integer.parseInt(reader.readLine());
if (n >= 0 && n < canvas.length && canvas[n]==0){
return n;
}
System.out.println("Choose free cell and enter its number");
} catch (NumberFormatException e) {
System.out.println("Please enter the number");
} catch (IOException e) {
}
}
}
static boolean isGameOver(int n){
// 0 1 2
// 3 4 5
// 6 7 8
//поиск совпадений по горизонтали
int row = n-n%3; //номер строки - проверяем только её
if (canvas[row]==canvas[row+1] &&
canvas[row]==canvas[row+2]) return true;
//поиск совпадений по вертикали
int column = n%3; //номер столбца - проверяем только его
if (canvas[column]==canvas[column+3])
if (canvas[column]==canvas[column+6]) return true;
//мы здесь, значит, первый поиск не положительного результата
//если meaning n находится на одной из граней - возвращаем false
if (n%2!=0) return false;
//проверяем принадлежит ли к левой диагонали meaning
if (n%4==0){
//проверяем есть ли совпадения на левой диагонали
if (canvas[0] == canvas[4] &&
canvas[0] == canvas[8]) return true;
if (n!=4) return false;
}
return canvas[2] == canvas[4] &&
canvas[2] == canvas[6];
}
static void drawCanvas(){
System.out.println(" | | ");
for (int i = 0; i < canvas.length; i++) {
if (i!=0){
if (i%3==0) {
System.out.println();
System.out.println("_____|_____|_____");
System.out.println(" | | ");
}
else
System.out.print("|");
}
if (canvas[i]==0) System.out.print(" " + i + " ");
if (canvas[i]==1) System.out.print(" X ");
if (canvas[i]==2) System.out.print(" O ");
}
System.out.println();
System.out.println(" | | ");
}
public static boolean isDraw() {
for (int n : canvas) if (n==0) return false;
return true;
}
}
GO TO FULL VERSION