Tic-tac-toe-pelin luominen. Kehityksen teoreettiset perusteet

Tervehdys rakkaat ystävät! Tässä opetusohjelmassa näytän sinulle, kuinka voit tehdä selainpelin - tic-tac-toe, javascriptissä! Tiedätte kaikki, mikä tämä peli on ja kuinka sitä pelataan, mutta haluan muistuttaa teitä vielä kerran:

Tic-tac-toe on logiikkapeli kahden pelaajan välillä 3 x 3 neliökentällä (mahdollisesti suuremmalla). Yksi leikkii "risteillä" ja toinen - "tac-varpailla".

P.S. Kuten kaikissa vastaavissa javascript-opetusohjelmissa, artikkelin lopussa voit ladata lähdetiedoston sekä nähdä demoesimerkin työn tulokset!

Kuvaus luotavasta pelistä

Katsotaanpa pelin ominaisuuksia:

  • peli alkaa heti sivun latauksen jälkeen;
  • oikeus liikkua ensin valitaan satunnaisesti (joko alat kävellä tai tietokone);
  • merkki, jonka asetat, valitaan satunnaisesti (risti tai nolla);
  • jos pelaaja voittaa, voittosymbolit (ristinauha tai nollia) korostetaan vihreällä;
  • jos pelaaja häviää tietokoneelle, palkki on korostettu punaisella;
  • kentän yläpuolella on tietorivi, jossa tulos (voitto tai tappio) näkyy.

Logiikka

En keksinyt monimutkaisia ​​(yleisiä) algoritmeja pelikentälle 3 x 3 solua, menin toiseen suuntaan - raakaa voimaa! (tästä lisää myöhemmin). Olen tunnistanut kolme peräkkäistä päävaihetta, joihin koko logiikka perustuu:

Vaihe 1: Tarkista - voittiko pelaaja?

Tässä vaiheessa tarkistamme, onko 3 solua (samalla rivillä), jotka on täytetty samoilla pelaajasymboleilla (risteillä tai nollia). Nuo. riippumatta siitä, mikä tämä siirto on (jopa ensimmäinen), tarkistamme aina ensin, onko pelaaja voittanut. Voitto näyttää tältä:

Vaihe 2: Tarkista - voiko tietokone voittaa seuraavalla siirrolla?

Tässä vaiheessa etsimme linjaa, jossa olisi 2 solua täynnä tietokonetta ja yksi tyhjä solu - eli yritämme voittaa pelaajan huolimattomuuden takia. Tältä tappio näyttää (eli tietokonevoitto):

Vaihe 3: älä anna meidän voittaa!

Tässä etsitään samaa riviä kuin toisessa vaiheessa, vain 2 solua tulee täyttää pelaajan pelimerkeillä, eli tässä vaiheessa emme anna tietokoneen hävitä laittamalla merkki tyhjään soluun. Jokainen vaihe on itsenäinen toiminto - näet tämän alla olevasta js-koodista.

Toteutus

Pelikentän asettelu on hyvin yksinkertainen - päälohko sisältää tietorivin (luokka - tulos) ja 9 lohkoa, jotka ovat soluja (luokka - lohko) HTML-solujen merkintä:

Sinun vuorosi!

Soluapuluokkaa tarvitaan halutun solun tarkkaan tunnistamiseen pelikentällä. CSS-tyylit pelikentille:

Krestiki_noliki( leveys: 306px; margin: 0 auto; ) .krestiki_noliki .block( leveys: 100px; korkeus: 100px; reunus: 1px solid #cc; kursori: osoitin; float: vasemmalle; tekstin tasaus: keskellä; fontin koko: 100 kuvapistettä; rivin korkeus: 94 kuvapistettä;)

Katsotaanpa nyt koko JS-koodia, jonka jälkeen puhun pääkohdista:

$(dokumentti).ready(function()( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1)); jos (rand_num > 3)( var znak_comp = "O"; var znak_user = "X"; $(".solu"+rand_num).text(znak_comp); ) var exit_flag = false; var win_user_array = ["123"," 456","789","147","258","369","159","357"]; //Määritä pelaajan voittofunktio check_3_user(znak)( for (var i = 0; i< 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first+",."+second+",."+third).css("background-color", "#83e2c3"); $(".result").text("Вы выиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем возможность победы компьютера function check_2_comp(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == "" && exit_flag == false){ $("."+third).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak && exit_flag == false){ $("."+second).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak && exit_flag == false){ $("."+first).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем ход компьютера function check_2_user(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == ""){ $("."+third).text(znak_comp); exit_flag = true; } } if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak){ $("."+second).text(znak_comp); exit_flag = true; } } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first).text(znak_comp); exit_flag = true; } if(exit_flag) break; } } $(".krestiki_noliki .block").click(function(){ //Если клетка пустая if($(this).text() == ""){ $(this).text(znak_user); check_3_user(znak_user); check_2_comp(znak_comp); check_2_user(znak_user); if(exit_flag == false){ for (var i = 1; i < 10; i++) { if($(".cell"+i).text() == ""){ $(".cell"+i).text(znak_comp); break; } } }else exit_flag = false; } }); });

Ensin määritetään muuttujat: znak_user - tähän muuttujaan tallennamme merkin, jonka käyttäjä soittaa (oletuksena sinne on tallennettu nolla - tämä on englanninkielinen "O"). znak_comp - tähän muuttujaan tallennamme merkin, että tietokone soittaa (oletusarvoisesti sinne on tallennettu risti - tämä on englanninkielinen koppi "x").

Logiikka on seuraava: jos satunnaisluku on suurempi kuin 3, niin tietokone pelaa nollien kanssa ja se (tietokone) tekee ensimmäisen liikkeen.

Voit muuttaa tätä logiikkaa mieleiseksesi, esimerkiksi luoda satunnaisia ​​numeroita saadaksesi enemmän vaihtoehtoja sille, kuka on ainakin ensimmäinen ja mitkä hahmot. exit_flag - tämä lippu (muuttuja) vastaa funktiosta poistumisesta, eli esimerkiksi silloin, kun tietokone on jo tehnyt liikkeensä ja sinun on poistuttava funktiosta ja siirrettävä siirto soittimelle. win_user_array - tämä matriisi tallentaa kaikki voittovaihtoehdot solujen täyttöä varten. Selvyyden vuoksi katsotaanpa tätä kuvaa:

Jokainen taulukon elementti on kolminumeroinen merkkijono, joka on voittava yhdistelmä, eli jos esimerkiksi täytät solut numeroiden 1, 2 ja 3 alle, niin voitto (tai tappio) tulee. Kuten näet, voittovaihtoehtoja on yhteensä 8, tehtävämme on lajitella kaikki nämä vaihtoehdot. Seuraavassa on 3 toimintoa:

  1. check_3_user();
  2. check_2_comp();
  3. check_2_user();

Näiden toimintojen tarkoitus on kuvattu (kolmessa vaiheessa) Logiikka-osiossa (yllä). Nämä funktiot kutsutaan napsauttamalla mitä tahansa kentän solua. Parametri (znak) välitetään jokaiselle funktiolle - tämä on pelaajan tai tietokoneen merkki (risti tai nolla), esimerkiksi funktiossa, joka määrittää pelaajan voiton (check_3_user), välitämme merkin pelaajalta löytääkseen 3 identtistä merkkiä samalta riviltä.

Kolmen toiminnon jälkeen (jos tietokone ei ole vielä liikkunut) tietokone täyttää yhden vapaasta solusta. Täällä voit monimutkaistaa pelaamista esimerkiksi tekemällä siitä niin, että jos keskussolu on vapaa (solu numero 5), panosta ensin siinä, jos se on varattu, sitten johonkin vapaasta kulmasta (nämä ovat solut nro 1, 3, 7 ja 9) ja niin edelleen - yleensä tässä se on sinun.

Se on periaatteessa kaikki, mitä tällaisen pelin luomiseen tarvitaan.

Nyt voit katsella peliä demona ja ladata lähdetiedoston (vain 1 tiedosto).

08.06.2018 - kiitos huomiosta kirjeen kirjoittajalle: Patvakan Baghdasaryan, virhe korjattiin kun tietokoneessa oli useita vaihtoehtoja voitot ja kaikki hänen voittoliikkeensä maalattiin päälle (4 - 6 solua 3 sijasta).

Siinä kaikki minulle, toivottavasti tämä opetusohjelma oli hyödyllinen sinulle, toivotan sinulle onnea, hei!

Kuinka kirjoittaa botti, jota ei voi lyödä tic-tac-toe tai Johdanto minimax-sääntöön

On mahdollista, että satojen tic-tac-toe-pelien jälkeen mietit: mikä on optimaalinen algoritmi? Mutta jos olet täällä, yritit todennäköisesti myös kirjoittaa toteutuksen tästä pelistä. Menemme pidemmälle ja kirjoitamme botin, jota on mahdotonta päihittää tic-tac-toe. Ennakoituaan kysymyksesi "miksi?", vastaamme: algoritmin ansiosta.

Kuten ammattisahkinpelaaja, tämä algoritmi laskee vastustajan toimet useiden siirtojen ajan eteenpäin - kunnes se saavuttaa pelin loppuun, oli kyseessä voitto, tappio tai tasapeli. Tässä lopullisessa tilassa tekoäly antaa itselleen positiivisen pistemäärän (+10 meidän tapauksessamme) voitosta, negatiivisen pistemäärän (-10) tappiosta ja neutraalin pistemäärän (0) tasapelistä.

Samaan aikaan algoritmi suorittaa samanlaisia ​​laskelmia pelaajan liikkeille. Se valitsee suurimman pistemäärän saaneen liikkeen, jos tekoäly liikkuu, ja pienimmän pistemäärän saaneen liikkeen, jos pelaaja liikkuu. Tätä strategiaa käyttämällä minimax välttää tappion.

Kokeile pelata tätä peliä.

Minimax-algoritmi kuvataan yksinkertaisimmin rekursiivisena funktiona, joka:

  1. palauttaa arvon, jos lopputila löytyy (+10, 0, -10),
  2. käy läpi kaikki kentän tyhjät solut,
  3. kutsuu minimax-funktiota kullekin niistä (rekursio),
  4. arvioi vastaanotetut arvot
  5. ja palauttaa parhaan.

Jos et ole perehtynyt rekursioon, kannattaa katsoa tämä Harvardin CS50-kurssin luento:

Ymmärtääksemme, miten minimax toimii, kirjoitetaan sen toteutus ja mallinnetaan sen käyttäytymistä. Käsittelemme tätä kahdessa seuraavassa jaksossa.

Minimax toteutus

Otamme tilanteen huomioon, kun peli päättyy (katso kuva alla). Koska minimax käy läpi kaikki mahdolliset pelitilat (ja niitä on satoja tuhansia), on järkevää harkita loppupeliä - näin joudumme seuraamaan vähemmän rekursiivisia funktiokutsuja (yhteensä 9).

Anna tekoälyn leikkiä risteillä, miehen - nolilla.

Yksinkertaistaaksemme kentän kanssa työskentelyä määritetään se 9 elementin joukoksi, joiden arvot ovat yhtä suuret kuin solujen sisältö. Täytetään se ristillä ja nollalla, kuten yllä olevassa kuvassa, ja kutsutaan sitä origBoardiksi.

Var origBoard = ["O", 1 "X", "X", 4 "X", 6 "O", "O"];

Sitten määritämme muuttujat aiPlayer ja huPlayer ja annamme niille arvot "X" ja "O".

Lisäksi tarvitsemme funktion, joka etsii voittavia yhdistelmiä ja palauttaa arvon tosi, jos haku onnistuu, sekä funktion, joka tallentaa käytettävissä olevien solujen indeksit.

/* alkutila levyt O | | X --------- X | | X --------- | O | O */ var origBoard = ["O",1 "X", "X", 4 "X", 6 "O", "O"]; // human var huPlayer = "O"; // AI var aiPlayer = "X"; // palauttaa luettelon taulun tyhjien solujen indekseistä funktio emptyIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // voittoyhdistelmät, ottaen huomioon tiliindeksit funktio voitto == pelaaja && lauta == pelaaja && lauta == pelaaja) || (lauta == pelaaja && lauta == pelaaja && lauta == pelaaja) || (lauta == pelaaja && lauta == pelaaja && lauta == pelaaja) || (lauta == pelaaja && lauta == pelaaja && lauta == pelaaja) || (lauta == pelaaja && lauta == pelaaja && lauta == pelaaja) || (lauta == pelaaja && lauta == pelaaja && lauta == pelaaja)) (palauta tosi; ) else (palauta false; ) )

Joten määritellään minimax-funktio kahdella argumentilla: newBoard (uusi lauta) ja pelaaja (soitin). Sitten etsimme kentältä vapaiden solujen indeksit ja välitämme ne availSpots-muuttujaan.

// pääminimax-funktion funktio minimax(newBoard, player)( //käytettävissä olevat solut var availSpots = emptyIndices(newBoard);

Lisäksi meidän on seurattava lopputiloja ja palautettava asianmukaiset arvot. Jos nolla voittaa, sinun on palautettava -10 , jos "risti" - +10 . Jos availSpots-taulukon koko on nolla, vapaita soluja ei ole, peli päättyy tasapeliin ja nolla tulee palauttaa.

// tarkista päätetila (voitto/häviö/tasapeli) //ja palauttaa arvon vastaavasti if (voittava(newBoard, huPlayer))( return (pisteet:-10); ) else if (voittava(newBoard, aiPlayer)) ( paluu (pisteet:10); ) else if (availSpots.length === 0)( paluu (pisteet:0); )

Sen jälkeen sinun on kerättävä pisteitä jokaisesta tyhjästä solusta. Tätä varten luodaan joukko liikkeitä ja käydään läpi kaikki tyhjät solut asettamalla kunkin liikkeen indeksit ja pisteet siirtoobjektiin.

Sitten asetamme tyhjän solun indeksiksi, joka oli tallennettu numerona origBoardiin, siirtoobjektin indeksiominaisuuteen. Sitten menemme nykyisen pelaajan uuden kentän newBoard tyhjään soluun ja kutsumme toiselta pelaajalta minimax-funktion ja tuloksena olevan kentän newBoard . Tämän jälkeen meidän on asetettava minimax-funktion palauttaman objektin pistemäärä ominaisuus liikkuvan kohteen pistemäärään.

Jos minimax ei löydä lopullista tilaa, se jatkaa rekursiivisesti syvenemistä peliin, kunnes se saavuttaa päätetilan. Sen jälkeen se ohittaa tämän rekursion "tason" pisteet yhden tason korkeammalla.

Lopuksi funktio nollaa newBoardin ja sijoittaa siirtoobjektin siirtotaulukkoon.

// matriisi kaikkien objektien tallentamiseen var moves = ; // selata käytettävissä olevia soluja kohteelle (var i = 0; i< availSpots.length; i++){ //create an object for each and store the index of that spot var move = {}; move.index = newBoard]; // совершить ход за текущего игрока newBoard] = player; //получить очки, заработанные после вызова минимакса от противника текущего игрока if (player == aiPlayer){ var result = minimax(newBoard, huPlayer); move.score = result.score; } else{ var result = minimax(newBoard, aiPlayer); move.score = result.score; } // очистить клетку newBoard] = move.index; // положить объект в массив moves.push(move); }

Minimaxin on sitten valittava paras liike siirtotaulukosta. Hän tarvitsee liikkeen, jolla on korkein pistemäärä, jos se on tekoälyliike, ja pienimmän, jos se on ihmisen liike. Siten, jos pelaajan arvo on aiPlayer , algoritmi alustaa bestScore-muuttujan hyvin pieneen määrään ja käy läpi siirtotaulukon: jos siirtosiirto saa enemmän pisteitä kuin bestScore , algoritmi muistaa kyseisen liikkeen . Liikkeiden ollessa samoilla pisteillä algoritmi muistaa ensimmäisen.

Siinä tapauksessa, että pelaaja on yhtä suuri kuin huPlayer, kaikki on sama - vain nyt bestScore alustetaan suurella numerolla, ja minimax etsii siirtoliikettä, jolla on vähiten pisteitä.

Lopuksi minimax palauttaa bestMoveen tallennetun objektin.

// jos kyseessä on tekoälyliike, selaa liikkeet läpi ja valitse korkein pistemäärä var bestMove; if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >parasScore)( parasScore = liikkuu[i].score; parasMove = i; ) )else( // muussa tapauksessa selaa siirtoja ja valitse siirto, jolla on pienin pistemäärä var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

Seuraavassa osiossa simuloimme ohjelmaamme ymmärtääksemme, miten se toimii.

Minimax toiminnassa

Alla olevan kaavion avulla analysoimme algoritmin vaiheittaisen mallin.

Huomautus: Kaaviossa suuret luvut osoittavat funktiokutsun järjestysnumeron ja tasot osoittavat kuinka monta liikettä eteenpäin algoritmi meni.

  1. Algoritmiin syötetään origBoard ja aiPlayer. Se tekee luettelon kolmesta löydetystä tyhjästä solusta, tarkistaa, onko tila äärellinen, ja käy läpi kaikki tyhjät solut. Algoritmi muuttaa sitten newBoardia sijoittamalla aiPlayerin ensimmäiseen tyhjään soluun. Sen jälkeen se kutsuu itseään newBoardista ja huPlayeristä ja odottaa toista kutsua palauttaakseen arvon.
  2. Kun ensimmäinen funktiokutsu on vielä käynnissä, toinen suoritetaan luoden luettelon kahdesta tyhjästä solusta, tarkistaen, onko tila äärellinen, ja kiertäen kaikki tyhjät solut. Toinen kutsu muuttaa sitten newBoardia asettamalla huPlayerin ensimmäiseen tyhjään soluun. Sen jälkeen se kutsuu itseään newBoardista ja aiPlayeristä ja odottaa kolmatta kutsua palauttamaan arvon.

  3. Koska toinen kutsu löysi kaksi tyhjää solua, minimax muokkaa newBoardia sijoittamalla huPlayerin toiseen vapaaseen soluun. Sitten se kutsuu itseään newBoardista ja aiPlayeristä.

  4. Algoritmi kokoaa listan tyhjistä soluista ja vahvistaa pelaajan voiton tarkistettuaan tilan rajallisuuden. Siksi se palauttaa objektin, jonka laskentakenttä on yhtä suuri kuin (-10).

    Toisessa funktiokutsussa algoritmi vastaanottaa kolmannen ja neljännen funktiokutsun alemmalta tasolta palauttamat arvot. Koska huPlayer-siirto tuotti nämä kaksi tulosta, algoritmi valitsee niistä pienimmän. Koska ne ovat samat, algoritmi valitsee ensimmäisen ja välittää sen ensimmäiselle funktiokutsulle.

    Tässä vaiheessa ensimmäinen funktiokutsu on vastaanottanut arvion aiPlayerin siirtymisestä ensimmäiseen tyhjään soluun. Sitten se muokkaa newBoardia sijoittamalla aiPlayerin toiseen tyhjään soluun. Sen jälkeen se kutsuu itseään newBoardista ja huPlayerista.

  5. Viidennessä funktiokutsussa algoritmi kokoaa luettelon tyhjistä soluista ja korjaa AI-voiton tilan äärellisyyden tarkistamisen jälkeen. Joten se palauttaa objektin, jonka laskentakenttä on +10.

    Sen jälkeen ensimmäinen kutsu muuttaa newBoardia asettamalla aiPlayerin kolmanteen tyhjään soluun. Sitten se kutsuu itseään newBoardista ja huPlayerista.

  6. Kuudes kutsu kokoaa luettelon kahdesta tyhjästä solusta, tarkistaa, onko tila äärellinen, ja käy läpi kaikki tyhjät solut. Sitten se muokkaa newBoardia sijoittamalla huPlayerin ensimmäiseen tyhjään soluun. Sitten se kutsuu itseään newBoardista ja aiPlayeristä ja odottaa seitsemättä kutsua palauttaakseen arvon.
  7. Uusi kutsu listaa yhden tyhjän solun, tarkistaa, onko tila äärellinen, ja muuttaa newBoardia sijoittamalla aiPlayerin tyhjään soluun. Sen jälkeen se kutsuu itseään newBoardista ja huPlayeristä ja odottaa tämän kutsun palauttavan arvon.
  8. Kahdeksas haaste on tyhjä lista tyhjiä soluja ja korjaa aiPlayerin voiton tilan rajallisuuden tarkistamisen jälkeen. Siksi se palauttaa objektin, jonka laskentakenttä on yhtä suuri kuin (+10), yhden tason ylöspäin, seitsemänteen kutsuun.

    Seitsemäs kutsu sai vain yhden, positiivisen arvon alemmista tasoista. Koska tämä arvo vastaanotettiin aiPlayerin aikana, algoritmi palauttaa suurimman vastaanotetuista arvoista. Joten se palauttaa positiivisen arvon (+10) yhden tason ylöspäin, kuudenteen kutsuun.

    Koska kuudes kutsu löysi kaksi tyhjää solua, minimax muokkaa newBoardia sijoittamalla huPlayerin toiseen tyhjään soluun. Sitten se kutsuu itseään newBoardista ja aiPlayeristä.

  9. Tämän jälkeen algoritmi kokoaa luettelon tyhjistä soluista ja korjaa aiPlayerin voiton tilan rajallisuuden tarkistamisen jälkeen. Siksi se palauttaa objektin, jonka laskentakenttä on yhtä suuri (+10) yhden tason ylöspäin.

    Tässä vaiheessa kuudennen kutsun on valittava seitsemännen kutsun palauttaman pistemäärän (+10) ja yhdeksännen kutsun palauttaman pistemäärän (-10) välillä. Koska huPlayerin siirto tuotti nämä kaksi tulosta, algoritmi valitsee niistä pienimmän ja palauttaa sen tason ylöspäin objektina piste- ja indeksikentillä.

    Lopuksi ensimmäisen kutsun kaikki kolme haaraa arvioidaan (-10, +10, -10). Koska aiPlayerin siirto tuotti nämä kolme tulosta, algoritmi valitsee kohteen, joka sisältää korkeimman pistemäärän (+10) ja sen indeksin (4).

Yllä olevassa skenaariossa minimax päättää sen paras valinta tulee muutto kentän keskussoluun.

Loppu!

Tähän mennessä sinun pitäisi ymmärtää, miten minimax-algoritmi toimii. Kokeile kirjoittaa toteutus itse tai katso esimerkki GitHubista tai CodePenistä ja optimoi se.

Jos olet kiinnostunut AI-aiheesta peleissä, suosittelemme lukemaan materiaalimme tästä aiheesta.

VAIHE 1. LOMAKEPARAMETRIEN ASETTAMINEN1. Mukauta lomaketta määrittämällä sen koko
510 vaakapistettä ja 480 pystypistettä
pystysuora. Maksimi ja minimi
määritä koko, joka vastaa samoja arvoja.
2. Nimeä muoto sanalla "Tic Tac Toe".
3. Käytä lomakkeen taustana kansion tiedostoa
Kuvat nimellä background.png ja aseta se
lomakkeen keskellä.
4. Otsikkorivin kuvakkeelle
käytä tiedostoa kansiosta
Kuvat nimeltä menu4.ico.
5. Lomakkeen taustaväri on asetettava
MintCream.

VAIHE 2. LISÄÄ LOMAKKEEN PAINIKE JA LUOKKA

1. Muuta sijoitetuille elementeille
fonttikoko 12 ja tausta asetettu
läpinäkyvä.

1. Luo valikkopalkki, jossa on kohteita
kuten kuvassa näkyy.

VAIHE 3. VALIKKOPAVIN LISÄÄMINEN LOMAKKEEN

1. Luo komento valikkokohdassa Tiedosto
Poistu.
2. Sillä
komentoja
Poistu
määrätä
ohjelmakoodi on sama kuin
edellinen hakemus.

VAIHE 3. VALIKKOPAVIN LISÄÄMINEN LOMAKKEEN

1. Luo joukkue valikkokohdassa Peli
Uusi peli.
2. Kirjoita New Game -joukkueelle
ohjelmakoodi tulevaisuudessa kautta
muutaman askeleen.

VAIHE 3. VALIKKOPAVIN LISÄÄMINEN LOMAKKEEN

1. Luo komento Ohje-valikkokohdassa
Tietoja ohjelmasta.
2. Luo Tietoja-komentoa varten uusi
muodosta ja kirjoita ohjelmakoodi
samanlainen kuin edellisessä
sovellus.

1. Vedä PictureBox lomakkeelle
muuta sen koko 100x100.
2. Aseta läpinäkyvä tausta.
3. Järjestä PictureBox kuvan osoittamalla tavalla
kuva pelikentän ensimmäisen solun yläpuolella.

VAIHE 4. LISÄÄ PICTUREBOX-OBJEKTEJA LOMAKKEEN

1
2
3
4
5
6
7
8
9
1. Asetamme muiden solujen yläpuolelle
PictureBox-objektit, kopiot ensimmäisestä
esine, ilmoitetun numeroinnin mukaan
Kuvat.

1. Ennen kuin kirjoitat koodia
tarvitaan kansioon
\Visual Studio
2010\Projects\Tic Tac Toe \ Tic Tac Toe
zeros\bin\Debug\ on ohjattava uudelleen
x.png-, 0.png-, none.png-tiedostot Kuvat-kansiosta.
2. Kaksoisnapsauta hiiren vasemmalla painikkeella ensimmäistä
PictureBox.

VAIHE 5. LISÄÄ KOODI PICTUREBOX-OBJETEILLE

1. Luo kaksiulotteinen taulukko, joka on kaikkien elementtien käytettävissä
luotu 3x3-elementin muodossa, joka koostuu kokonaisluvuista. Heti
täytämme sen nollilla ilmoittaessamme. Tyhjille soluille me
käytämme arvoa 0, "risteille" - 1 ja "nolille" -1.

VAIHE 5. LISÄÄ KOODI PICTUREBOX-OBJETEILLE

Menettelyssä, kun napsautat ensimmäistä
PictureBox, operaattorin lisääminen
valinta
mikä
tahtoa
suorittaa tilantarkistus
taulukkosolut. Jos arvo
taulukon solu on 0, mikä
Se tarkoittaa, että siinä ei ole "nollaa".
"risti", sitten tässä solussa
taulukko on kirjoitettu 1 ja sisään
Kuvalaatikko 1
näytetään
"ristin" kuva ja jos
taulukon solun arvo on
on yhtä kuin 1, niin se sisältää
"risti" ja 0 on kirjoitettu siihen, ja
tyhjä solu tulee näkyviin.

VAIHE 5. LISÄÄ KOODI PICTUREBOX-OBJETEILLE

1
2
3
4
5
6
7
8
9



Lisää koodi kentän jäljellä oleville soluille
samalla tavalla kuin ensimmäisessä, vain muuttumassa
PictureBox-objektin numero ja solun osoite
joukko.
ESIMERKKI toiselle solulle:

Toimenpiteet painikkeen painalluksella
lisätä
operaattori
sykli
kuka tarkistaa
kaikki solut ensimmäisestä
tyhjien solujen läsnäolo. Ja jos
solu on tyhjä
sitten siihen
"nolla" on kirjoitettu, nimittäin sisään
taulukon solu kirjoitetaan -1.
Tulevaisuuden työskentelyn helpottamiseksi
muuttujia
minä
j
mikä
käytetään toistamaan silmukoita
ilmoittaa koko lomakkeelle.

VAIHE 6. LISÄÄ KÄVELYPAINIKKEEN OHJELMAKOODI

Näytetään nollia
pelaamista
ala
tarpeellista
lisää ohjelmakoodi runkoon
solujen tyhjyyden tarkistussykli.
Sisäkkäisoperaattorilla
haarautuminen
tahtoa
tapahtua
taulukon solun osoitteen jäsennys for
nolla lähtö oikein
PictureBox.
Lisäämme myös taukolausekkeen
ennenaikaiseen lopettamiseen
silmukka tyhjänä
soluja.

VAIHE 6. LISÄÄ KÄVELYPAINIKKEEN OHJELMAKOODI

Ilmaisee pelin tilan
käyttöliittymäelementtiä käytetään
Tunniste 1. Koska pelaaja liikkuu aina
ensimmäinen
Että
klo
lataukset
sovellukset
tarpeellista
V
elementti
Tunniste 1
tarpeellista
heijastaa
lauseita "sinun
liikkua."
varten
Tämä
luoda
muuttuja
vastaus
mikä
Otetaan tämä lause. A
lomakemuuttujaa ladattaessa
täytyy määrittää elementille
Label1, luodaksesi tarvittavat
menettelyt
tarpeellista
kaksoisnapsauta ensin
muodossa

VAIHE 7. LISÄÄ KOODI UUDELLE PELIVALIKKOKOHDAT

Kun napsautat komentoa uusi
peli nollautuu
kaikki taulukon solut korvaamalla kaikki
"ristit" ja "noughts" päällä
tyhjiä soluja. Myös lähtö
kirjain "Sinun siirtosi"

VAIHE 8. NÄYTÄ PELIN TULOKSET

Tarkistaaksesi liikkeiden tulokset
tarpeellista
analysoida
rivien, sarakkeiden ja
diagonaalit. Jos kaikki kolme elementtiä
ovat yhtä suuria kuin 1, tämä on pelaajan voitto ja
jos kolme -1, tämä on tappio
pelaaja.
Voittotesti vaaditaan
käyttäytyminen
ennen
liikkua
tietokone,
A
todentaminen
tappion jälkeen.
Toimenpiteen viimeinen komento
näyttää tulokset
liikkua.

VAIHE 8. NÄYTÄ PELIN TULOKSET

Ohjelmakoodi käyttäjän voiton tarkistamiseksi:
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Voitit";
Ohjelmakoodi käyttäjän voiton tarkistamiseksi:
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Sinä hävisit";
etiketti1.teksti = vastaus;

VAIHE 9 PARANNA PELAATTAVUUTTA

Pelattavuuden parantamiseksi
sarjalähdön sijaan
ensimmäisessä tyhjässä
"nollien" solut toteutamme
ulostulo satunnaisgeneraattorin kautta
numeroita.
Tätä varten sinun on lisättävä
yksi boolen muuttuja
uslovie ja vaihda silmukan tyyppi For
aikana, koska emme tiedä
toistojen tarkka määrä
generaattori satunnaisia ​​numeroita Hei hei
se ei putoa tyhjään soluun.

VENÄJÄN OPETUS- JA TIETEMINISTERIÖ

liittovaltion talousarvion mukainen korkea-asteen ammatillinen koulutuslaitos

"Vologdan osavaltion yliopisto"

Automaatio- ja tietokonetekniikan laitos

Kurssiprojektin selitys

Ohjelmointi ja algoritmisoinnin perusteet

"Ristinolla"

Täytetty EM-21 ryhmän opiskelija

Butorova L.Yu.

hyväksytty Rzheutskaya S. Yu.

JOHDANTO

1. ONGELMAN ANALYYSI JA KEHITETTYN OHJELMAN VAATIMUSTEN MÄÄRITTÄMINEN

1 Ohjelman tarkoitus, sen käyttäjät, tärkeimmät toiminnot ja tavoitteet, joihin kehittämisen aikana pyritään

2 Yleiskatsaus tunnetuista ohjelmista, jotka suorittavat samanlaisia ​​toimintoja

3 Kehityksen teoreettiset perusteet

4 Kehitystyökalujen valinta

SUUNNITTELU OSA KEHITTÄMISTÄ

1 Käyttöliittymän suunnittelu

2.2 Tietorakenteiden kehittäminen (ulkoisessa ja RAM-muistissa)

2.3 Algoritmien kehittäminen ja analysointi

OHJELMAN TOTEUTUS C++:ssa

1 Ohjelmaarkkitehtuuri

2 Tavallisten visuaalisten ja ei-visuaalisten komponenttien valinta

TESTITULOKSET

PÄÄTELMÄ

Bibliografia

Sovellukset

JOHDANTO

Tic-tac-toe - looginen peli kahden vastustajan välillä neliökentällä, jossa on 3 x 3 solua tai suurempi ("loputtomaan kenttään" asti). Yksi pelaajista pelaa "risteillä", toinen - "ei". Tämä peli tuli suosituksi kauan ennen tietokoneiden tuloa, vain aiemmin sitä pelattiin yksinkertaisella paperilla ja kynällä. Perinteinen kiinalainen peli käyttää mustia ja valkoisia kiviä.

Tässä tutkielma perussäännöt ja pelikentän vakiokoko (3x3 solua) on säilytetty. Pelin mukavuuden vuoksi ensimmäisen liikkeen oikeus jätetään käyttäjälle, eli "risteytykset".

Tic-tac-toe on ohjelma, joka on suunniteltu viihdyttämään käyttäjää, joten sen käyttöliittymä on tässä kurssityössä tehty pelityyliin, jossa on yhdistetty positiivisia värejä, jotka pahentavat pelin emotionaalista osaa.

Pelissä on kolme tyyppiä: X vs 0 - käyttäjä vastaan ​​käyttäjä, "1 taso tietokoneen kanssa" - niille, jotka ovat vasta oppimassa maailmanpelin perusteita, ja taso "2 taso tietokoneen kanssa" - niille, jotka ovat täysin varmoja voitostaan. Tasoilla 1 ja 2 on mahdollista kolme tulosta: "voitto", "häviö" ja "tasapeli". Voitto on kiinteä, jos pysty-, vaaka- tai diagonaali on täysin täynnä ristejä tai noita.

Jos kentän vapaat solut ovat ohi, mutta kukaan ei ole voittanut, katsotaan, että peli päättyi "tasapeliin".

1. ONGELMAN ANALYYSI JA KEHITETTYN OHJELMAN VAATIMUSTEN MÄÄRITTÄMINEN

ohjelman välinen rajapinta

1.1 Ohjelman tarkoitus, sen käyttäjät, keskeiset toiminnot ja kehittämisen aikana asetetut tavoitteet

Tämän ohjelman tarkoituksena on ensinnäkin viihdyttää käyttäjiä, jotta henkilön odotusaika kirkastuu, koska mikä tahansa työ tarvitsee lepoa, ja tämä yksinkertainen peli auttaa sinua rentoutumaan ja kääntämään huomiosi jokapäiväisistä asioista. Myös "tic-tac-toe" kuuluu älyllisten ja loogisten pelien luokkaan, joka on suunniteltu kouluttamaan loogista ajattelua, mahdollistamaan keskittymisen ja muistin kehittämisen.

Käyttäjien kohderyhmänä ovat lapset ja nuoret sekä aikuiset. Tuotteen käytön pääkriteerit ovat kyky lukea ohjelmaan kirjoitettua tekstiä ja kyky valita tietokoneelle tarvittava tehtävä painikkeilla.

Tästä voimme päätellä, että päätehtävät ovat: viihteen tehtävä ja tehtävänä kehittää ihmisen loogista potentiaalia.

1.2 Yleiskatsaus tunnetuista ohjelmista, jotka suorittavat samanlaisia ​​toimintoja

Internetistä löydät suuren määrän teoksia, jotka toteuttavat tämän pelin. Tällä hetkellä tästä pelistä on monia analogeja, jotka ovat poikennut alkuperäisistä standardeista. Esimerkkejä tällaisista ohjelmista ovat Tic-Tac-Toe äärettömällä kentällä ja Tic-Tac-Toe 3D. Lisäksi monissa peleissä "ristit" ja "varpaat" korvataan muilla symboleilla, kuten esimerkiksi "kivillä".

Kurssiprojektini on PC-sovellus. Peli on suunniteltu sekä yhdelle käyttäjälle, jonka vastustaja on tekoäly (tai tietokone), että kahdelle käyttäjälle. Se esitetään klassisella 3x3-kentällä.

Mielenkiintoisin ja epätavallisin oli mielestäni peli "Tic Tac Toe 3D". Siksi valitsin sen vertailuksi.

Kolmiulotteinen tic-tac-toe on paljon mielenkiintoisempi kuin paperilla tai tavallisella kentällä. Täällä on enemmän mahdollisuuksia voittaa ja hävitä, ja tasapelit ovat harvinaisempia. Voit pelata yksin - tietokonetta vastaan ​​- tai yhdessä ystävän kanssa. Ja mitä epätavallisinta tässä on se, että voittaaksesi voit tehdä kolmen värisi (musta tai valkoinen) pallon yhdistelmän, ei vain yhdellä tasolla, vaan myös seinien tasoa pitkin ja jopa koko pallon diagonaalia pitkin. kenttään (kuva 1.1).

Riisi. 1.1

Saman teeman pelien laajasta valikoimasta voidaan erottaa jokaisessa työssä ainutlaatuinen suunnitelman toteutus. Jokainen projekti eroaa muista yksilöllisyydellään.

1.3 Kehityksen teoreettiset perusteet

Analyysi

Jokaiselle osapuolelle tunnetaan hyvin algoritmit, jotka takaavat tasapelin missä tahansa vastustajan pelissä, ja jos hän tekee virheen, voit voittaa. Peli on siis kunnossa "ei kenenkään kuolema"<#"877528.files/image002.gif">

Kuva 1.2. Pelitilanteiden puu

Kuvassa 1.2 on esitetty osittainen puu pelitilanteista tic-tac-toe -pelille. Pelitilanteiden puu tic-tac-toe-pelissä, jossa "tic-tac-toe" -pelin pelaaja menee ensin ja toimii yllä olevan algoritmin mukaisesti, ja "tac-toe"-pelaaja voi tehdä mitä haluaa (lisäksi yksi kärki on annettu rationaaliselle ja irrationaaliselle aktille, eli mille tahansa muulle), koostuu 50 solmusta.

1.4 Kehitystyökalujen valinta

Tehtävien toteuttamiseksi tarvitaan integroitu sovelluskehitysympäristö. Siksi projekti on kehitetty Microsoft Visual Studio 2008 -ohjelmointiympäristössä.

Microsoft Visual Studio - Microsoftin tuotelinja , mukaan lukien integroitu kehitysympäristö ohjelmistoja ja monia muita työkaluja. Näiden tuotteiden avulla voit kehittyä konsolina sovellukset sekä GUI-sovelluksia , mukaan lukien tuki Windows Forms -teknologialle sekä verkkosivustoja , Web palvelut kuten natiivissa , ja hallinnassa koodit kaikille Windowsin tukemille alustoille Windows Mobile , Windows CE , .NET Framework , Xbox , Windows Puhelin .NET Compact Framework ja Silverlight .

2. SUUNNITTELU OSA KEHITTÄMISTÄ

2.1 Käyttöliittymän suunnittelu

Pelisovellusta luotaessa on otettava huomioon yksi tuotteen menestyksen pääkomponenteista - tämä on käyttöliittymä. Ohjelman käyttöliittymän tulee olla ennen kaikkea käyttäjälle ymmärrettävä ja houkutteleva. Sinun on yritettävä poistaa kaikki hetket, jotka häiritsevät käyttäjää tai aiheuttavat hänelle epämukavuutta. Ohjelman koko käyttöliittymä voidaan jakaa kahteen osaan.

) Ohjelman päävalikko

Riisi. 2.1 - Ohjelman päävalikko

Päävalikko on suunniteltu siten, että käyttäjä pääsee mukaan pelitunnelmaan, joten käyttöliittymä on tehty värikkäillä, leikkisillä väreillä. Valikon kautta pääset pelikentälle, tutustu pelin sääntöihin tai poistu pelistä.

) pelikenttä

Kuva 2.2 - Pelikenttä

Pelikenttä sisältää pelin välittömän alueen, jonne pelaaja ja tietokone asettavat kuvakkeet. Ennen pelin aloittamista käyttäjän on valittava pelityyppi, kuten "X vs. 0", "1 taso tietokoneella" tai "2 taso tietokoneella", muuten ohjelma kehottaa sinua kertomaan, mitä tehdä. Painike, joka auttaa pelaajaa palaamaan päävalikkoon. Lopussa avautuvat lisäikkunat, jotka ilmoittavat osallistujalle kaksintaistelun tuloksista.

Riisi. 2.3 - lisäpelien tulosikkunat

2.2 Tietorakenteiden kehittäminen (ulkoisessa ja RAM-muistissa)

RAM-muistia käytetään yksiulotteiseen taulukkoon, joka koostuu 9 elementistä ja joka tallentaa pelikentän tilat, jossa jokainen taulukon solu vastaa pelikentän solua. Muistia kuluu myös staattisiin muuttujiin: tasonumero, käännösjärjestys.

Se vaatii 803 kt vapaata muistia toimiakseen.

.3 Algoritmien kehittäminen ja analysointi

Pelin ajattelualgoritmin toteuttamiseksi sinun on määritettävä staattinen taulukko gcnew array (9); johon pelikentän tilat tallennetaan, missä jokainen taulukon solu vastaa solua. "0" - vastaa tyhjää solua, jos pelaaja meni soluun, eli "X", arvo "1" tallennetaan ja jos tietokone teki liikkeen, eli "O", arvo on "2". Aluksi kaikki taulukon elementit ovat yhtä suuria kuin "0". Sinun on asetettava staattinen muuttuja lvl, joka tallentaa tasotiedot. Tässä pelissä on yhteensä 3 tasoa: lvl saa arvon "1", jos käyttäjä on valinnut pelityypin "X vs. O", arvon "2", jos "1 taso tietokoneen kanssa", ja arvon " 3", jos "2 tasolla tietokoneen kanssa". Muuttuva pelaaja - tallentaa siirtojärjestyksen ("true" - pelaajan siirto, "false" - tietokoneen siirto). Koska ensimmäisen liikkeen oikeus myönnetään käyttäjälle, pelin alussa pelaaja = tosi. Lippustaattinen muuttuja tallentaa tietoa siitä, onko pelikentällä tyhjiä soluja vai ei: jos lippu = tosi - eli false - tyhjiä soluja ei ole. Varmennusalgoritmin on sisällettävä taulukon x parametrien luettelo ja esitettävä oma ratkaisunsa, joka on optimaalinen jatkopeliin. Tämä ohjelma esittelee pelin 2 tasoa tietokoneen kanssa. Tasolla 1 tietokoneen tehtävä ei ole voittaa vastustajaa. Siksi annettu toiminto palauttaa sen solun satunnaisen arvon, johon tietokone menee. Tämän algoritmin koodi on esitetty [Liite 1]. Kuvassa 2.4 on lohkokaavio koodin toteutuksesta.

Voittavin liike pelin alussa on siirtyminen kentän keskelle. Toiminnossa dif_level() tarkistetaan alussa ehto: jos pelaaja ei mennyt keskuskentälle, niin tietokone menee sinne. Muussa tapauksessa, jos pelaaja meni keskelle, kutsutaan check(2)-toiminto tarkistaakseen tietokoneen yhdistelmän ja, jos on mahdollista voittaa, palauttaa solun numeron. Jos tietokone ei voi voittaa seuraavalla siirrolla, kutsutaan check(1)-toimintoa: pelaajan yhdistelmän tarkistaminen. Palautetaan solun numero, panostaen, jossa pelaaja voittaisi. Jos tällaista yhdistelmää ei ole, kutsutaan low_level()-funktiota.

Kuva 2.4. - Vuokaavio

Kuva 2.5. - Vuokaavio

3. OHJELMAN TOTEUTUS C++-kielellä

.1 Ohjelmaarkkitehtuuri

Tämä ohjelma toteuttaa 3 muotoa: päävalikko (kuva 2.1.), pelikenttä (kuva 2.2) ja ohjekenttä (pelin säännöt); 12 paneelia, joista 9 on pääpaneelia. Lisäksi pelin lopussa kuvaruutuun tulee tulos, joita on yhteensä 5 (kuva 2.3).

Pohjaksi voit ottaa paneelinapsautuskäsittelijät, joita on pelikentällä tasan 9. Jokainen käsittelijä kutsuu useita toimintoja. Alussa on ehto, jos käyttäjä valitsee pelityypin "X vastaan ​​0", vain solut täytetään arvoilla 1 tai 2 (risti tai nolla). Seuraavaksi tulevat funktiot: siirron ilmaisu (CrossZero()), joka muuttaa ristin nollaan ja päinvastoin, miehitettyjen solujen estäminen tarkistamalla Array(), voittajan löytäminen(). Voittaja()-funktiossa otetaan huomioon kaikki mahdolliset voittovaihtoehdot, joten jos joku pelaajista asettaa 3 figuuriaan (risti tai nolla) peräkkäin pystysuunnassa, vaakasuunnassa tai vinottain, hän voittaa. Muuten, jos kenttä on täytetty, mutta kukaan pelaajista ei ole rivissä, kutsutaan toimintoa (_ystävä()) - tarkista tasapeli, joka tarkistaa, onko kentällä vapaita soluja vai ei. Jos fr = tosi, kentässä ei ole vapaita soluja. Jos arvo on muuttunut, kentässä on vapaa solu.

Toinen ehto toimii, jos valitaan toinen tai kolmas pelityyppi. Sitten kutsutaan funktiota, jossa suoritetaan tietokoneen siirto(int n). Se vastaanottaa sen solun numeron, jota pelaaja napsautti. Seuraavaksi tulevat toiminnot: edistymisen ilmaisu (CrossZero()), varattujen solujen estäminen tarkistamallaArray(). Tämän jälkeen kutsutaan voittaja()-funktiota, joka tarkistaa, onko pelaaja voittanut tämän liikkeen vai ei. Jos ei, vapaiden solujen läsnäolo tarkistetaan. Jos vapaita soluja on, tietokone liikkuu. Lisäksi riippuen siitä, minkä tason pelaaja "1" tai "2" valitsi, kutsutaan seuraavia toimintoja: low_level(), dif_level(). Low_level()-funktio valitsee satunnaisesti, mihin nolla sijoitetaan, ja dif_level()-funktio tarjoaa erityisen algoritmin, jonka avulla tietokone voi voittaa. Seuraavaksi tulevat toiminnot: edistymisen ilmaisu (CrossZero()), varattujen solujen estäminen tarkistamallaArray(). Tämän jälkeen kutsutaan voittaja()-funktiota, joka tarkistaa, onko tietokone voittanut tämän siirron vai ei. Jos ei, vapaiden solujen läsnäolo tarkistetaan. Jos vapaita soluja on, pelaaja liikkuu.

.2 Tavallisten visuaalisten ja ei-visuaalisten komponenttien valinta

Tämän työn toteuttamista varten valittiin seuraavat komponentit:

1) Lomake1, jossa annetut parametrit Text=Tic Tac Toe, ControlBox=False

2) f2, BackColor asetettu, Text=Game

) comboBox1 annetuilla kohteilla:

X vs. 0

1. taso tietokoneen kanssa

2. taso tietokoneella

4) paneeli, jossa on annetut BackColor-parametrit sekä Visible- ja Enabled-parametrien erilaiset arvot. Joillekin paneeleille kirjoitettiin tapahtumia, kuten Click.

5) -painike, jossa on määritetyt fontti-, etuväri-, takaväri- ja tekstiparametrit, kaikille painikkeille, kuten Click, kirjoitettiin.

6) etiketti, annetuilla parametreilla BackColor , Font, Fore Color, Text.

) pictureBox, jossa on kuvan parametrit, SizeMode= StretchImage.

) textBox, annetuilla parametreilla BackColor, Font, Fore Color, Text=” ”.

4. TESTITULOKSET

Testataan ohjelmaa käymällä läpi 3 pelityyppiä.

Kokeillaan päävalikon painikkeiden toimintoja. Painikkeet toimivat oikein. Yritetään aloittaa peli valitsematta pelityyppiä. Ohjelma näyttää virheilmoituksen ja pyytää sinua valitsemaan pelityypin. (Kuva 4.1)

Kuva 4.1.

Valitaan 1 pelityyppi - "X vastaan ​​0", ts. käyttäjä vs käyttäjä. Pelin tässä vaiheessa käyttäjä voi myös leikkiä itsensä kanssa. (Kuva 4.2)

Kuva 4.2.

Pelin "1 taso tietokoneen kanssa" aikana tietokone ei aseta itselleen tavoitetta voittaa osallistuja. Hän laittaa vain nollia vapaita paikkoja kentät. Tässä vaiheessa käyttäjä voi helposti voittaa tietokoneen. Vaikka tällä tasolla, muutkin skenaariot ovat mahdollisia.

Kuva 4.3.

Pelityyppi "Taso 2 tietokoneella". Tässä vaiheessa peli analysoi kaikki liikkeet ja yrittää valita optimaalisimman liikkeen. Kaikki kolme tapahtumien kehityksen muunnelmaa ovat myös mahdollisia täällä, koska Tietokone siirtyy ensimmäisen kerran mihin tahansa vapaaseen soluun. Suurimman osan ajasta peli päättyy tasapeliin.

Kuva 4.4.

Ohjelma toimii onnistuneesti kaikissa testiversioissa ilman virheitä.

PÄÄTELMÄ

Voi sanoa, että työn alussa asetettu tehtävä on suoritettu. Kehityksen aikana suunniteltiin ja kehitettiin kuuluisan Tic-Tac-Toe-pelin remix-projekti. Peli täyttää määritetyt vaatimukset ja suorittaa tehtävänsä. Toteutettu työssä Erilaisia ​​tyyppejä pelejä ja vaikeustasoja.

Työn aikana hallittiin uusia ohjelmointimenetelmiä integroidussa kehitysympäristössä. Vanha tieto C ++ -kielen kanssa työskentelystä on kiinteä. Kurssityötä varten analysoitiin erilaisia ​​menetelmiä ja algoritmeja tämän pelin toteuttamiseksi.

Huolimatta tämän ohjelman näennäisestä yksinkertaisuudesta, se on täynnä useita vaikeuksia, jotka toteutetaan käyttämällä kaikkia Visual C ++ -perustekniikoita.

Tämän ohjelman ominaisuudet ovat:

Selkeästi rakennettu algoritmi;

Intuitiivinen käyttöliittymä;

Helppokäyttöisyys;

Täysin selkeä käyttöohje;

Ei ylimääräisiä lisävarusteita.

KIRJASTUS

1. http://www.pravilaigr.ru/xo.php

2. http://2igroka.com/stuff/sportivnye/krestiki_noliki_3d/15-1-0-14

3. https://www.draw.io/

Http://pol-video.ru/QPW9QHEO2GU/uroki_s_krestiki-noliki_ch1.html

LIITE 1

private: int low_level()(// menettely matalalle vastustajalle;::Random^ rand = gcnew System::Random();(= rand->Next(0,8);

) while (x[r]!= 0);r;

LIITE 2

yksityinen: bool check(int n)(k = -1;// tarkistaa kaikki yhdistelmät ja palauttaa oikean liikkeen(x == n) (((x == n)&&(x == 0)) k =2; ( (x == n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =6;((x == n)&&(x == 0 )) k =3;((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =7;((x = = n)&&(x == 0)) k = 4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0)) k =6;((x = = n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =5;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =5;((x = = n)&&(x == 0)) k = 4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =3;((x = = n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =7;

)(x == n) (((x == n)&&(x == 0)) k =6;

)(k!=-1) palauttaa tosi, muuten palauttaa epätosi;

LIITE 3

yksityinen: int dif_level()(//vaikea vastustaja

//palauttaa check(2);(x == 0) return (4);(check(2)) return k; else (tarkista(1)) palauttaa k; else low_level();

SOVELLUS 4

yksityinen: void CrossZero()(// muuttaa ristin nollaan(edistymisen ilmaisin)(player) (->Visible = true;->Visible = false;

) else (-> Näkyvä = tosi;-> Näkyvä = epätosi;

): void checkingArray()(//-funktio tarkistaa, onko solussa jotain, jos on, et voi enää napsauttaa tätä solua. >Enabled = false;)(x == 2) (paneeli1-> BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (paneeli2->BackgroundImage = panel11->BackgroundImage;paneeli2- >Käytössä = false;)(x == 2) (paneeli2-> BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (paneeli3->BackgroundImage = panel11->BackgroundImage;paneeli3- >Käytössä = false;)(x == 2) (paneeli3-> BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (paneeli4->BackgroundImage = panel11->BackgroundImage;paneeli4- >Käytössä = false;)(x == 2) (paneeli4-> BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (paneeli5->BackgroundImage = panel11->BackgroundImage;paneeli5- >Käytössä = false;)(x == 2) (paneeli5-> BackgroundImage = panel10->BackgroundImage;paneeli5->Käytössä = false;)(x == 1) (paneeli6->B ackgroundImage = panel11->BackgroundImage;paneeli6->Käytössä = false;)(x == 2) (paneeli6->BackgroundImage = panel10->BackgroundImage;paneeli6->Käytössä = false;)(x == 1) (paneeli7-> BackgroundImage = panel11->BackgroundImage;paneeli7->Käytössä = false;)(x == 2) (paneeli7->Taustakuva = panel10->BackgroundImage;paneeli7->Käytössä = false;)(x == 1) (paneeli8-> BackgroundImage = panel11->BackgroundImage;panel8->Enabled = false;)(x == 2) (paneeli8->BackgroundImage = panel10->BackgroundImage;paneeli8->Käytössä = false;)(x == 1) (paneeli9-> BackgroundImage = panel11->BackgroundImage;panel9->Enabled = false;)(x == 2) (paneeli9->BackgroundImage = panel10->BackgroundImage;paneeli9->Käytössä = false;)

): bool winner()(// tarkista voittaja ja estä kaikki jäljellä olevat solut.

//Bool-lippu = false;(((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x = = 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2 )) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)))( (lvl==1) ( picturePo->Visible = true;)(picturePr->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false; true;

)(((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || (( x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x = = = x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)))((lvl==1) ) (kuvaPx->Näkyvä = tosi;)(kuvaPobeda->Näkyvä = tosi;)->Käytössä = epätosi;->Käytössä = epätosi;->Käytössä = epätosi;->Käytössä = epätosi;->Käytössä = epätosi;- > Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false; true;

): void _friend()(fr = tosi;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->näkyvä = totta ;)

): void move(int n)(// tietokoneen siirtofunktio= false;[n] = 1;= !player;();();(voittaja()) () ((int i = 0; i< 9; i++) if (x[i] == 0) flag = true;(flag){(lvl == 2) = 2; = 2;= !player;();();();

): System::Void button1_Click(System::Object^ lähettäjä, System::EventArgs^ e) (// uusi peli>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Teksti;(typePeli == "")(::Show("Valitse ensin pelityyppi!");

) else ((typeGame == "X vs 0") lvl = 1;(typeGame == "tietokonetaso 1") lvl = 2;(typeGame == "tietokonetaso 2") lvl = 3;(); = tosi ;(int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->Backgroundmage;->Background panel12->-mage; BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = tosi;->Käytössä = tosi;->Käytössä = tosi;->Käytössä = tosi;->Käytössä = tosi;->Käytössä = tosi;

): System::Void panel1_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((soitin)( = 1;

)= !soitin;();();();

): System::Void panel2_MouseClick(System::Object^ lähettäjä, Järjestelmä::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel3_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel4_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel5_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel6_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel7_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel8_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel9_MouseClick(System::Object^ lähettäjä, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((soitin)( = 1;

)= !soitin;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void button2_Click(System::Object^ lähettäjä, System::EventArgs^ e) (();

): System::Void picturePx_Click(System::Object^ lähettäjä, System::EventArgs^ e) (>Näkyvä = false;

): System::Void picturePo_Click(System::Object^ lähettäjä, System::EventArgs^ e) (>Näkyvä = false;

): System::Void picturePobeda_Click(System::Object^ lähettäjä, System::EventArgs^ e) (>Näkyvä = false;

): System::Void picturePr_Click(System::Object^ lähettäjä, System::EventArgs^ e) (>Näkyvä = false;

): System::Void pictureN_Click(System::Object^ lähettäjä, System::EventArgs^ e) (>Näkyvä = false;

Huomio! Tässä on kokeiluversio oppitunnista, jonka materiaalit eivät välttämättä ole täydellisiä.

Kirjaudu sisään opiskelijana

Kirjaudu sisään opiskelijana käyttääksesi koulun sisältöä

1C-konfiguraatioiden luominen: "Tic-tac-toe" osan 1/3 kirjoittaminen

Opimme pelaamalla, ja siksi ensimmäinen projektimme on luoda
lapsuudesta tuttu peli - "Tic-tac-toe".

Mitä tekemistä peleillä on 1C:n, kirjanpidon ja kaupan kanssa, kysyt? Ei melkein yhtään. Mutta meidän on aloitettava asteittain, ja ajan myötä päästään varastojen automatisointiin. Aloitetaan nyt pienestä.

Ennen kuin aloitamme Tic-Tac-Toe-pelin ohjelmoinnin, pohditaan.

Tiedämme jo, että lomakkeella on elementtejä, joista yksi on painike. Painikkeet pystyvät suorittamaan komentoja, ja samalla niillä on ominaisuuksia, joiden avulla voit hallita niiden näyttöä lomakkeessa (esimerkiksi otsikko).

Voit esimerkiksi luoda painikkeen avulla kentän, jossa on yhdeksän hotspotia (ne solut, joita napsautamme ja korjaamme toiminnon näyttäen samalla merkinnät muodossa "O" ja "X"). Nappaa meille enemmän kuin sopiva tähän.

Mitä me tarvitsemme? On selvää, että meidän tulee muistaa siirtomme ja tietokoneen liike. Meidän on myös muutettava painikkeiden otsikot: kun napsautamme, painikkeen otsikko on aina "O", kun tietokone liikkuu - "X".

Ja ensin meidän on luotava uusi tietokanta, jossa luomme pelimme. Tehdään se.

Vaihe 1: Luo tyhjä pohja

Luodaan tyhjä Tic-Tac-Toe-tietokanta.

Yksityiskohtaiset ohjeet

Juostaan 1C-pikakuvake avataksesi luettelon tietokoneessa olevista tietokannoista. Luet oppitunnin kokeiluversiota, täydelliset oppitunnit löytyvät. Meidän on luotava uusi pohja joten napsauta painiketta Lisätä":

Lisää-ikkuna avautuu tietokanta, josta haluat valita ensimmäisen kohteen " Tietokannan luominen ja napsauta "Seuraava" -painiketta:

Valitse seuraavassa ikkunassa toinen kohde " Luodaan tietokantaa ilman määritystä uuden kokoonpanon kehittämiseksi... ja napsauta "Seuraava" -painiketta uudelleen:

Seuraavassa ikkunassa meitä pyydetään syöttämään uuden tukikohdan nimi, jonka alla se näkyy tukiasemien luettelossa. Mennään sisään" Ristinolla ja napsauta "Seuraava" -painiketta:

Seuraavassa ikkunassa sinun on määritettävä polku tyhjään kansioon, johon tietokanta tallennetaan. Tässä tapauksessa loin kansion " Ristinolla" levyn D kansiossa "Bases 1C":

Jätä seuraavassa ikkunassa kaikki oletusasetukset ja napsauta " Valmis":

Lyhyen tauon jälkeen tietokanta luodaan ja lisätään luetteloon. Tietokannassa on kaksi päätoimintatapaa: 1C: Yritys Ja Konfiguraattori:

Konfigurointitilassa konfiguroimme ja ohjelmoimme pohjan, 1C:Enterprise-tilassa katsomme mitä siitä tuli.

Vaihe 2: avaa konfiguraattori

Painamme nappia" Konfiguraattori" siirtyäksesi konfigurointitilaan:

Vaihe 3: avaa määrityspuu

Suorita valikon komento " Kokoonpano"->"Avaa määritys":

Edessämme on avautunut konfiguraatiopuu, joka sisältää eri osia kokoonpanosta. Koska emme ole vielä luoneet mitään, nämä osiot ovat toistaiseksi tyhjiä:

Vaihe 4: Lisää käsittely

Pelimme logiikan sijoittamiseksi käytämme "Käsittely"-osiota. Painetaan oikealla painikkeella kohdassa " Käsittely ja valitse "Lisää"-komento:

Ennen meitä avattiin ikkuna uuden käsittelyn luomiseksi. Kirjoita nimi " Ristinolla". Synonyymi korvautuu itsestään. Tämä riittää tallentamaan käsittelymme (vielä tyhjä) tietokantaan. Paina "Sulje"-painiketta:

Vaihe 5: Ensimmäinen ohjelman virheenkorjaus

Voit tarkistaa mitä tapahtui käyttäjätilasta ( 1C: Yritys). Pääset siihen suoraan konfiguraattorista suorittamalla valikon komento " Virheenkorjaus"->"Aloita virheenkorjaus":

Koska olemme tehneet muutoksia tietokantaan, meiltä kysytään, hyväksymmekö tämän muutoksen. Tätä kysymystä kysytään meiltä jatkuvasti kehitysprosessissa. Vastaamme suostumuksella (painike " Joo"):

Tietokanta käynnistettiin 1C:Enterprise-tilassa. Luet oppitunnin kokeiluversiota, täydelliset oppitunnit löytyvät. Mutta kuten näemme, hänen kanssaan on edelleen vaikea työskennellä - ei yksinkertaisesti ole mitään, mistä valita. Se on outoa, koska olemme jo luoneet prosessoinnin ja teoriassa sen pitäisi näkyä keltaisessa paneelissa.




Ylös