Skapa ett tic-tac-toe-spel. Teoretiska grunder för utveckling

Hälsningar, kära vänner! I den här lektionen kommer jag att visa hur du kan göra ett webbläsarspel - tic-tac-toe, i javascript! Ni vet alla vad det här spelet är och hur man spelar det, men låt mig påminna er igen:

Tic-tac-toe är ett logiskt spel mellan två spelare på ett kvadratiskt fält med 3 gånger 3 celler (eventuellt större). Den ena leker med "kors" och den andra med "tårna".

P.S. som i alla liknande javascript-lektioner kan du i slutet av artikeln ladda ner källfilen, och även se resultatet av arbetet i ett demo-exempel!

Beskrivning av spelet som skapas

Låt oss titta på funktionerna i spelet:

  • spelet startar omedelbart efter att sidan har laddats;
  • rätten att gå först väljs slumpmässigt (antingen börjar du gå eller datorn);
  • tecknet du kommer att satsa väljs slumpmässigt (ett kryss eller en nolla);
  • om spelaren vinner är de vinnande symbolerna (en remsa med kryss eller nollor) markerade i grönt;
  • om spelaren förlorar mot datorn, markeras stapeln i rött;
  • Ovanför fältet finns en rad med information där resultatet visas (seger eller nederlag).

Logik

Jag kom inte på komplexa (universella) algoritmer för en spelplan på 3 gånger 3 kvadrat, jag gick åt andra hållet - brute force! (mer om detta lite senare). Jag har identifierat tre huvudsakliga sekventiella steg på vilka all logik vilar:

Steg 1: kontrollera om spelaren har vunnit?

I detta skede kontrollerar vi om det finns 3 celler (på samma rad) fyllda med samma spelarsymboler (kors eller nollor). De där. oavsett vad draget är (även det första), kontrollerar vi alltid först om spelaren har vunnit. Så här ser segern ut:

Steg 2: check - kan datorn vinna med nästa drag?

I det här skedet letar vi efter en rad där det skulle finnas 2 celler fyllda av datorn och en tom cell - det vill säga vi försöker vinna på grund av spelarens ouppmärksamhet. Så här ser nederlaget ut (dvs en datorseger):

Steg 3: vi låter dig inte vinna!

Här letar vi efter samma rad som i det andra steget, endast 2 celler måste fyllas med spelarens speltecken, det vill säga i detta skede tillåter vi inte datorn att förlora genom att placera en skylt i en tom cell. Vart och ett av stegen representerar en oberoende funktion - du kan se detta i js-koden nedan.

Genomförande

Utformningen av spelplanen är mycket enkel - huvudblocket innehåller en rad information (klass - resultat) och 9 block, som är celler (klass - block) HTML-layout av cellerna:

Din tur!

Den extra klasscellen är nödvändig för att exakt identifiera den önskade cellen på spelplanen. CSS-stilar för spelplanen:

Krestiki_noliki( width: 306px; margin: 0 auto; ) .krestiki_noliki .block( width: 100px; height: 100px; border: 1px solid #ccc; cursor: pointer; float: left; text-align: center; font-size: 100px; linjehöjd: 94px;)

Låt oss nu titta på hela JS-koden, varefter jag kommer att prata om huvudpunkterna:

$(document).ready(function())( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1)); if (rand_num > 3)( var znak_comp = "O"; var znak_user = "X"; $(".cell"+rand_num).text(znak_comp); ) var exit_flag = false; var win_user_array = ["123", "456","789","147","258","369","159","357"]; //Bestämma spelarens segerfunktion 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; } }); });

Först deklarerar vi variablerna: znak_user - i denna variabel lagrar vi tecknet som användaren kommer att spela med (som standard lagras en nolla där - detta är den engelska rutan "O"). znak_comp - i denna variabel lagrar vi tecknet som datorn kommer att spela med (som standard lagras ett kryss där - detta är den engelska rutan "X").

Logiken är denna: om slumptalet är större än 3, så spelar datorn med nollor, och den (datorn) gör det första draget.

Du kan ändra denna logik som passar dig, till exempel kan du skapa flera slumpmässiga nummer för att göra fler alternativ för vem som kommer att vara först och vilka tecken. exit_flag - denna flagga (variabel) är ansvarig för att lämna funktionen, det vill säga till exempel när datorn redan har gjort sitt drag och du måste lämna funktionen och skicka draget till spelaren. win_user_array - denna array lagrar alla vinnande alternativ för att fylla cellerna. För att göra det tydligt, låt oss ta en titt på den här bilden:

Varje element i arrayen är en sträng med tre nummer, vilket är en vinnande kombination, det vill säga om du till exempel fyller i cellerna under siffrorna 1, 2 och 3, så kommer seger (eller nederlag) att inträffa. Som du kan se finns det 8 vinnande alternativ totalt, vår uppgift är att gå igenom alla dessa alternativ. Därefter kommer 3 funktioner:

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

Syftet med dessa funktioner beskrivs (i tre steg) i avsnittet Logik (ovan). Dessa funktioner anropas genom att klicka på någon av cellerna i fältet. En parameter (znak) skickas till var och en av funktionerna - detta är spelarens eller datorns tecken (ett kryss eller en nolla), till exempel till funktionen som bestämmer spelarens seger (check_3_user), vi passerar spelarens tecken i ordning för att hitta 3 identiska tecken på samma linje.

Efter tre funktioner (om datorn ännu inte har gjort ett drag) fyller datorn en av de lediga cellerna. Här kan du komplicera spelet, till exempel genom att göra det så att om den centrala cellen är ledig (cell nummer 5), satsa först i den; om den är upptagen, satsa sedan i ett av de fria hörnen (dessa är celler nr 1, 3, 7 och 9) och så vidare - i allmänhet, här är det upp till ditt gottfinnande.

Det är i princip allt som krävs för att skapa ett sådant spel.

Nu kan du titta på spelet med hjälp av ett demoexempel och ladda ner källfilen (1 fil totalt).

06/08/2018 - tack för din uppmärksamhet mot författaren till brevet: Patvakan Baghdasaryan, en bugg har åtgärdats när datorn hade flera möjliga alternativ segrar och alla hans vinnande drag målades över (från 4 till 6 celler istället för 3).

Det var allt för mig, jag hoppas att den här lektionen var användbar för dig, jag önskar dig lycka till, hejdå!

Hur man skriver en bot som inte kan slås vid tic-tac-toe, eller Introduktion till minimaxregeln

Det är mycket möjligt att du efter hundratals spel med tic-tac-toe har undrat: vad är den optimala algoritmen? Men om du är här så har du förmodligen också försökt skriva en implementering av detta spel. Vi kommer att gå längre och skriva en bot som kommer att vara omöjlig att slå vid tic-tac-toe. Förutse din fråga "varför?", kommer vi att svara: tack vare algoritmen.

Liksom en professionell schackspelare beräknar den här algoritmen motståndarens handlingar flera drag framåt - tills den når slutet av spelet, vare sig det är en seger, nederlag eller oavgjort. Väl i detta slutliga tillstånd kommer AI:n att ge sig själv ett positivt antal poäng (i vårt fall +10) för en vinst, negativ (-10) för en förlust och neutral (0) för oavgjort.

Samtidigt utför algoritmen liknande beräkningar för spelarens rörelser. Den kommer att välja draget med högst poäng om AI:n rör sig och draget med lägst om spelaren rör sig. Genom att använda denna strategi undviker minimax nederlag.

Försök spela det här spelet.

Minimaxalgoritmen beskrivs enklast som en rekursiv funktion som:

  1. returnerar ett värde om det slutliga tillståndet hittas (+10, 0, -10),
  2. går igenom alla tomma celler på fältet,
  3. anropar minimax-funktionen för var och en av dem (rekursion),
  4. utvärderar de erhållna värdena
  5. och ger tillbaka den bästa.

Om du inte är bekant med rekursion bör du titta på den här föreläsningen från Harvard CS50-kursen:

För att förstå hur minimax fungerar, låt oss skriva dess implementering och modellera dess beteende. Vi kommer att ta itu med detta i de kommande två avsnitten.

Minimax implementering

Vi ska titta på en situation där spelet går mot sitt slut (se bilden nedan). Eftersom minimax går igenom alla möjliga speltillstånd (och det finns hundratusentals av dem), är det vettigt att överväga slutspelet - på detta sätt kommer vi att behöva spåra ett mindre antal rekursiva funktionsanrop (9 totalt).

Låt AI:n leka med kors, personen - med nollor.

För att göra det lättare att arbeta med fältet, låt oss deklarera det som en array av 9 element med värden lika med innehållet i cellerna. Låt oss fylla den med kors och tår, som på bilden ovan, och kalla den origBoard.

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

Därefter deklarerar vi variablerna aiPlayer och huPlayer och tilldelar dem värdena "X" respektive "O".

Dessutom kommer vi att behöva en funktion som söker efter vinnande kombinationer och returnerar ett sant värde om sökningen lyckas, och en funktion som lagrar indexen för de tillgängliga cellerna.

/* initialtillstånd brädor O | | X ---------- X | | X ---------- | O | O */ var origBoard = [“O”,1,”X”,,”X”,4,”X”, 6,”O”,”O”]; // person var huPlayer = “O”; // AI var aiPlayer = “X”; // returnerar en lista med index över tomma celler på brädfunktionen emptyIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // vinnande kombinationer med hänsyn tagen index funktion vinnande(bräda, spelare)( if((bräda == spelare && styrelse == spelare && styrelse == spelare) || (bräde == spelare && styrelse == spelare && styrelse == spelare) || (bräda = = spelare && styrelse == spelare && styrelse == spelare) || (bräde == spelare && styrelse == spelare && styrelse == spelare) || (bräde == spelare && styrelse == spelare && styrelse == spelare) | | (bräde == spelare && styrelse == spelare && styrelse == spelare) || (bräde == spelare && styrelse == spelare && styrelse == spelare) || (bräde == spelare && styrelse == spelare && styrelse = = spelare)) ( return true; ) else ( return false; ) )

Så låt oss definiera en minimaxfunktion med två argument: newBoard och player. Sedan hittar vi indexen för fria celler på fältet och skickar dem till variabeln availSpots.

// huvudsaklig minimax funktion funktion minimax(newBoard, player)( // tillgängliga celler var availSpots = emptyIndices(newBoard);

Dessutom måste vi hålla reda på sluttillstånden och returnera lämpliga värden. Om "nolla" vinner måste du returnera -10, om "krysset" - +10. Om storleken på availSpots-arrayen är noll, så finns det inga lediga celler, spelet kommer att sluta oavgjort och noll måste returneras.

// kontrollerar terminaltillståndet (vinst/förlust/oavgjort) //och returnerar ett värde i enlighet därmed if (winning(newBoard, huPlayer))( return (poäng:-10); ) else if (vinnande(newBoard, aiPlayer)) ( return (poäng:10); ) else if (availSpots.length === 0)( return (poäng:0); )

Efter detta måste du samla poäng från var och en av de tomma cellerna. För att göra detta kommer vi att skapa en rad drag och gå igenom alla tomma celler i en slinga, och placera indexen och poängen för varje drag i rörelseobjektet.

Sedan sätter vi indexet för den tomma cellen, som lagrades som ett tal i origBoard, lika med indexegenskapen för flytta objektet. Sedan går vi som nuvarande spelare till en tom cell i det nya fältet newBoard och anropar minimax-funktionen från den andra spelaren och det resulterande fältet newBoard. Efter detta måste du lägga poängegenskapen för objektet som returneras av minimax-funktionen i poängegenskapen för det flyttade objektet.

Om minimax inte hittar ett terminaltillstånd, fortsätter det att rekursivt röra sig djupare in i spelet tills det når ett terminaltillstånd. Efter det överför den poängen för denna "nivå" av rekursion till en nivå högre.

Slutligen återställer funktionen ändringarna till newBoard och placerar flytta objektet i moves arrayen.

// array för att lagra alla objekt var moves = ; // gå igenom tillgängliga celler för (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); }

Minimax måste sedan välja det bästa draget från dragarrayen. Han behöver draget med den högsta poängen om AI:n rör sig, och med den lägsta om det är ett mänskligt drag. Således, om värdet på spelaren är aiPlayer initierar algoritmen variabeln bestScore till ett mycket litet antal och går genom dragarrayen: om en dragpoäng är värd mer poäng än bestScore, kommer algoritmen ihåg det draget. Vid drag med lika poäng kommer algoritmen ihåg den första.

I fallet när spelaren är lika med huPlayer , är allt liknande - först nu initieras bestScore till ett stort antal, och minimax letar efter flytten med minst poäng.

Som ett resultat returnerar minimax objektet lagrat i bestMove .

// om detta är ett AI-drag, gå igenom dragen och välj draget med flest poäng var bestMove; if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = moves[i].score; bestMove = i; ) ) else( // annars gå igenom dragen och välj draget med minst poäng var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

I nästa avsnitt kommer vi att simulera vårt program för att förstå hur det fungerar.

Minimax i aktion

Med hjälp av diagrammet nedan kommer vi att analysera algoritmens steg-för-steg-modell.

Notera: I diagrammet anger stora siffror funktionsanropets serienummer och nivåer anger hur många drag algoritmen har gått framåt.

  1. OrigBoard och aiPlayer matas till algoritmen. Den gör en lista över de tre tomma cellerna som hittats, kontrollerar tillståndets ändlighet och går igenom alla tomma celler. Algoritmen ändrar sedan newBoard , och placerar aiPlayer i den första tomma rutan. Efter det anropar den sig själv från newBoard och huPlayer och väntar på att det andra samtalet ska returnera ett värde.
  2. Medan det första funktionsanropet fortfarande körs körs det andra, skapa en lista med två tomma celler, kontrollera för ändligt tillstånd och gå igenom alla tomma celler. Det andra anropet ändrar sedan newBoard genom att placera huPlayer i den första tomma rutan. Efter det ringer den upp sig själv från newBoard och aiPlayer och väntar på att det tredje samtalet ska returnera ett värde.

  3. Eftersom det andra anropet hittade två tomma celler, ändrar minimax newBoard genom att placera huPlayer i den andra tomma cellen. Den anropar sig sedan från newBoard och aiPlayer.

  4. Algoritmen sammanställer en lista med tomma celler och registrerar spelarens seger efter att ha kontrollerat tillståndets ändlighet. Så det returnerar ett objekt med ett poängfält på (-10).

    I det andra funktionsanropet tar algoritmen emot de värden som returneras från den lägre nivån av de tredje och fjärde funktionsanropen. Eftersom huPlayers drag gav dessa två resultat, väljer algoritmen den mindre. Eftersom de är samma väljer algoritmen den första och skickar den till det första funktionsanropet.

    Vid denna tidpunkt fick det första funktionsanropet en uppskattning av aiPlayers förflyttning till den första tomma cellen. Den modifierar sedan newBoard genom att placera aiPlayer i den andra tomma rutan. Efter det anropar den sig själv från newBoard och huPlayer.

  5. I det femte funktionsanropet sammanställer algoritmen en lista med tomma celler och registrerar AI:ens seger efter att ha kontrollerat tillståndets ändlighet. Så det returnerar ett objekt med ett poängfält på +10.

    Efter detta ändrar det första anropet newBoard genom att placera aiPlayer i den tredje tomma cellen. Den anropar sig sedan från newBoard och huPlayer.

  6. Det sjätte anropet gör en lista med två tomma celler, kontrollerar tillståndets ändlighet och går igenom alla tomma celler. Den modifierar sedan newBoard genom att placera huPlayer i den första tomma rutan. Sedan ringer den upp sig själv från newBoard och aiPlayer och väntar på att det sjunde samtalet ska returnera ett värde.
  7. Det nya anropet skapar en lista med en tom cell, kontrollerar ändligt tillstånd och ändrar newBoard för att placera aiPlayer i den tomma cellen. Efter det anropar den sig själv från newBoard och huPlayer och väntar på att detta samtal ska returnera ett värde.
  8. Den åttonde utmaningen är tom lista tomma celler och registrerar segern för aiPlayer efter att ha kontrollerat lemtillståndet. Därför returnerar den ett objekt med ett räknefält lika med (+10) till nivån ovanför, det sjunde anropet.

    Det sjunde samtalet fick bara ett positivt värde från de lägre nivåerna. Eftersom detta värde erhölls under aiPlayers tur, returnerar algoritmen det största erhållna värdet. Så det returnerar ett positivt värde (+10) till nivån upp, det sjätte anropet.

    Eftersom det sjätte anropet hittade två tomma celler, modifierar minimax newBoard genom att placera huPlayer i den andra tomma cellen. Den anropar sig sedan från newBoard och aiPlayer.

  9. Efter detta sammanställer algoritmen en lista med tomma celler och registrerar segern för aiPlayer efter att ha kontrollerat tillståndets ändlighet. Därför returnerar den ett objekt med ett poängfält lika med (+10) till nivån ovanför.

    Vid denna tidpunkt måste den sjätte utmaningen välja mellan poängen (+10) som den sjunde utmaningen gav och poängen (-10) som den nionde utmaningen gav. Eftersom huPlayers drag gav dessa två resultat, väljer algoritmen den mindre och returnerar den till nästa nivå som ett objekt med poäng- och indexfält.

    Slutligen utvärderas alla tre grenarna av det första samtalet (-10, +10, -10). Eftersom aiPlayers drag gav dessa tre resultat, väljer algoritmen det objekt som innehåller det högsta antalet poäng (+10) och dess index (4).

I ovanstående scenario avgör minimax det optimalt val det kommer att ske en flytt till det centrala torget i fältet.

Slutet!

Vid det här laget borde du ha förstått hur minimaxalgoritmen fungerar. Testa att skriva en implementering själv, eller titta på ett exempel på GitHub eller CodePen och optimera det.

Om du är intresserad av ämnet AI i spel rekommenderar vi att du läser vårt material om detta ämne.

STEG 1. KONFIGURERA FORMULARPARAMETRAR1. För att anpassa ett formulär, ställ in dess storlek
510 punkter horisontellt och 480 punkter horisontellt
vertikal. Max och minimum
ange storleken lika med samma värden.
2. Ge formen namnet "Tic Tac Toe".
3. För formulärbakgrunden, använd en fil från mappen
Bilder under namnet background.png, och placera den
i mitten av formuläret.
4. För en ikon i titelraden
använd använd fil från mapp
Bilder under namnet menu4.ico.
5. Bakgrundsfärgen för formuläret måste ställas in
MintCream.

STEG 2. LÄGG TILL EN KNAPP OCH ETIKET I FORMULÄRET

1. För placerade element, ändra
teckenstorlek till 12 och bakgrundsuppsättning
transparent.

1. Skapa en menyrad med objekt i
som visas på bilden.

STEG 3. LÄGG TILL EN MENYRAD I FORMULÄRET

1. Skapa ett kommando i menyalternativet Arkiv
Utgång.
2. För
lag
Utgång
låt oss ordinera
programkoden är densamma som i
tidigare ansökan.

STEG 3. LÄGG TILL EN MENYRAD I FORMULÄRET

1. Skapa ett lag i menyalternativet Spel
Ett nytt spel.
2. För kommandot Nytt spel kommer vi att skriva
programkod i framtiden via
några steg.

STEG 3. LÄGG TILL EN MENYRAD I FORMULÄRET

1. Skapa ett kommando i menyalternativet Hjälp
Om programmet.
2. Skapa ett nytt för kommandot Om programmet
formulär och skriv programkoden
liknande som i föregående
Ansökan.

1. Genom att dra ett PictureBox-objekt till formuläret
ändra dess storlek till 100x100.
2. Ställ in en transparent bakgrund.
3. Placera PictureBox som visas i
bilden ovanför den första cellen i spelfältet.

STEG 4. LÄGG TILL BILDBOXOBJEKT I FORMULÄRET

1
2
3
4
5
6
7
8
9
1. Ovanför de återstående cellerna placerar vi
PictureBox-objekt, kopior av det första
objekt, enligt numreringen som anges på
Bilder.

1. Innan du skriver kod
behövs i mappen
\Visuell Studio
2010\Projects\Tic Tac Toe\X's
nollor\bin\Debug\ måste rullas om
filer x.png, 0.png, none.png från mappen Bilder.
2. Dubbelklicka med vänster mus på den första
PictureBox.

STEG 5. LÄGG TILL KOD FÖR PICTUREBOX-OBJEKT

1. Skapa en tvådimensionell array tillgänglig för alla element i
skapas i form av 3x3 element bestående av heltal. Direkt
vi fyller den med nollor när vi deklarerar den. För tomma celler vi
Vi kommer att använda 0, för "korsar" - 1, och för "nollor" - -1.

STEG 5. LÄGG TILL KOD FÖR PICTUREBOX-OBJEKT

I proceduren när du klickar på den första
PictureBox, lägg till en operatör
val
som
kommer
kolla statusen
arrayceller. Om värdet
matrisceller kommer att vara lika med 0, vilket
det betyder att det varken finns "noll" eller
"korsa", sedan i den här cellen
array skrivs 1 och in
PictureBox1
visas
bild av ett "kors" och om
värdet på arraycellen blir
är lika med 1 då den innehåller
"kryss" och 0 är skrivet i det, och
En tom cell visas.

STEG 5. LÄGG TILL KOD FÖR PICTUREBOX-OBJEKT

1
2
3
4
5
6
7
8
9



Lägg till koden för de återstående cellerna i fältet
samma som i den första som bara ändras
PictureBox-objektnummer och celladress
array.
EXEMPEL för den andra cellen:

I proceduren när du klickar på en knapp
Lägg till
operatör
cykel
vem kollar
alla celler från första till
förekomst av tomma celler. Och om
cellen är tom,
sedan in i henne
"noll" skrivs, nämligen in
arraycellen skrivs -1.
För bekvämlighet i framtida arbete
variabler
jag,
j
som
används för att iterera loopar
Vi kommer att meddela för hela formuläret.

STEG 6. LÄGG TILL KOD FÖR GÅNGKNAPPEN

För att visa nollor på
spelande
fält
nödvändig
lägg till programkod i brödtexten
cykel för att kontrollera celler för tomhet.
Använder ett kapslat uttalande
förgrening
kommer
äga rum
analys av array cell adress för
utgång noll i rätt
PictureBox.
Vi lägger också till ett brytmeddelande
för för tidigt slut
slinga när du hittar tom
celler.

STEG 6. LÄGG TILL KOD FÖR GÅNGKNAPPEN

För att indikera spelstatus
gränssnittselement används
Etikett1. Eftersom spelaren alltid rör sig
först
Den där

Nedladdningar
applikationer
nödvändig
V
element
Etikett1
nödvändig
reflektera
fraser "Din
flytta."
För
detta
låt oss skapa
variabel
svar
som
Låt oss tilldela denna fras. A
när du laddar formuläret en variabel
måste tilldelas elementet
Label1, för att skapa det nödvändiga
förfaranden
nödvändig
dubbelklicka först
enligt form

STEG 7. LÄGG TILL PROGRAMKOD FÖR DET NYA SPELMENYPOSTEN

När du trycker på kommando ny
spelet återställs
alla celler i arrayen, ersätter alla
"korsar" och "tårna" på
tomma celler. Även slutsatsen
"Ditt drag" tecken

STEG 8. LÄMNA SPELRESULTATET

För att kontrollera resultatet av drag
nödvändig
analysera
innehållet i rader, kolumner och
diagonaler. Om alla tre element
är lika med 1, då är detta en seger för spelaren, och
om tre -1 är detta ett nederlag
spelare.
Segercheck krävs
uppträdande
innan
framsteg
dator,
A
kolla upp
nederlag efter.
Procedurens sista kommando
resultaten kommer att visas på skärmen
framsteg.

STEG 8. LÄMNA SPELRESULTATET

Programkod för att kontrollera användarens seger:
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Du vinner";
Programkod för att kontrollera användarens seger:
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Du förlorade";
label1.Text = svar;

STEG 9 FÖRBÄTTRA SPELBARHETEN

För att förbättra spelbarheten
istället för seriell utgång
till de första tomma
celler med "nollor", implementerar vi
utmatning via slumpgenerator
tal.
För att göra detta måste du lägga till
en logisk variabel
uslovie och ändra looptypen från For
på While, eftersom vi inte vet
exakt antal repetitioner
generator slumpmässiga siffror Hejdå
det kommer inte att hamna i en tom cell.

RYSSLANDS UTBILDNINGSMINISTERIET OCH VETENSKAP

federal statsbudget utbildningsinstitution för högre yrkesutbildning

"Vologda State University"

Institutionen för automation och datateknik

Förklaring till kursprojektet i disciplinen

Programmering och algoritmiska grunder

"Luffarschack"

Avslutad student i grupp EM-21

Butorova L.Yu.

Accepterad Rzheutskaya S. Yu.

INTRODUKTION

1. ANALYS AV PROBLEMET OCH BESTÄMNING AV KRAV FÖR PROGRAMMET SOM SKALL UTVECKLAS

1 Syfte med programmet, dess användare, huvudfunktioner och mål som eftersträvas under utvecklingen

2 Genomgång av välkända program som utför liknande funktioner

3 Teoretisk grund för utveckling

4 Välja utvecklingsverktyg

DESIGN DEL AV UTVECKLING

1 Utveckling av användargränssnitt

2.2 Utveckling av datastrukturer (i extern och RAM)

2.3 Utveckling och analys av algoritmer

IMPLEMENTERING AV PROGRAMMET PÅ C++ SPRÅK

1 Programarkitektur

2 Val av standard visuella och icke-visuella komponenter

TESTRESULTAT

SLUTSATS

Bibliografi

Ansökningar

INTRODUKTION

Tic-tac-toe är ett logiskt spel mellan två motståndare på ett kvadratiskt fält med 3 gånger 3 celler eller större (upp till ett "ändlöst fält"). En av spelarna spelar med "kryss", den andra - med "tårna". Detta spel blev populärt långt innan datorernas tillkomst, bara innan det spelades med ett vanligt papper och en penna. Det traditionella kinesiska spelet använder svarta och vita stenar.

I denna kursarbete Grundreglerna och standardstorleken på spelfältet (3x3 celler) bevaras. För spelets bekvämlighet lämnas rätten att göra det första draget till användaren, det vill säga "korsar".

Tic Tac Toe är ett program som är designat för att underhålla användaren, därför är dess gränssnitt, i detta kursarbete, gjort i en spelstil med en kombination av positiva färger som förhöjer den känslomässiga delen av spelprocessen.

Det finns tre typer i spelet: X mot 0 - användare mot användare, "1:a nivå med en dator" - för dem som precis ska lära sig grunderna i världsspelet, och nivå "2:a nivå med en dator" - för de som är helt säkra på sin seger. På nivå 1 och 2 finns det tre möjliga utfall: "vinn", "förlora" och "oavgjort". Vinsterna är fixerade om de vertikala, horisontella eller diagonala linjerna är helt fyllda med kryss eller nollor.

Om de fria cellerna i fältet är över, men ingen vinner, anses spelet sluta i oavgjort.

1. ANALYS AV PROBLEMET OCH BESTÄMNING AV KRAV FÖR PROGRAMMET SOM SKALL UTVECKLAS

program tvärgränssnitt

1.1 Syfte med programmet, dess användare, huvudfunktioner och mål som eftersträvas under utvecklingen

Syftet med det här programmet är, först och främst, att underhålla användare, för att lysa upp en persons väntetid, eftersom allt arbete kräver vila, och det här enkla spelet hjälper dig att slappna av och ta tankarna bort från vardagliga angelägenheter. "Tic Tac Toe" tillhör också klassen av intellektuella och logiska spel, som är designade för att träna logiskt tänkande, låter dig koncentrera uppmärksamheten och utveckla minnet.

Målgruppen för användare är barn och tonåringar, såväl som vuxna. Huvudkriterierna för att använda produkten är förmågan att läsa text skriven i programmet och möjligheten att välja den nödvändiga uppgiften för datorn med hjälp av knappar.

Av detta kan vi dra slutsatsen att huvuduppgifterna är: underhållningsuppgiften och uppgiften att utveckla en persons logiska potential.

1.2 Granskning av välkända program som utför liknande funktioner

På Internet kan du hitta ett stort antal verk som implementerar detta spel. För närvarande finns det många analoger av detta spel som har avvikit från de ursprungliga standarderna. Ett exempel på sådana program är "Tic-tac-toe på ett oändligt fält" och "Tic-tac-toe 3D". I många spel ersätts också "kors" och "tårna" med andra symboler, som till exempel "stenar".

Mitt kursprojekt är en PC-applikation. Spelet är avsett för både en användare, vars motståndare är artificiell intelligens (eller en dator), och för två användare. Den presenteras på ett klassiskt 3x3-fält.

Det mest intressanta och ovanliga, enligt min mening, var spelet "Tic Tac Toe 3D". Det är därför jag valde det för jämförelse.

3D tic-tac-toe är mycket mer intressant än på papper eller på en vanlig bräda. Det finns fler möjligheter att vinna och förlora, och oavgjort är mindre vanligt. Du kan spela ensam - mot datorn - eller tillsammans med en kompis. Och det mest ovanliga här är att för att vinna kan du göra en kombination av tre bollar i din färg (svart eller vit) inte bara på vilken nivå som helst, utan också längs väggens plan och till och med diagonalt över hela fältet ( Fig. 1.1).

Ris. 1.1

Bland det stora utbudet av spel om ett liknande ämne kan vi i varje verk lyfta fram en unik implementering av planen. Varje projekt skiljer sig från andra i sin individualitet.

1.3 Teoretisk grund för utveckling

Analys

För var och en av parterna finns det välkända algoritmer som garanterar oavgjort i alla motståndares spel, och om hans motståndare gör ett misstag tillåter de honom att vinna. Så spelet är i ett tillstånd "ingens död"<#"877528.files/image002.gif">

Fig.1.2. Träd av spelsituationer

Ett partiellt träd av spelsituationer visas i fig. 1.2 för spelets tic-tac-toe. Ett träd av spelsituationer för spelet tic-tac-toe, där spelaren för "korsningarna" går först och agerar enligt ovanstående algoritm, och spelaren för "tårna" kan göra vad han vill (och en vertex är ges för en rationell och för en irrationell handling, det vill säga vilken som helst annan), består av 50 noder.

1.4 Välja utvecklingsverktyg

För att nå våra mål behöver vi en integrerad applikationsutvecklingsmiljö. Därför genomfördes projektutvecklingen i programmeringsmiljön Microsoft Visual Studio 2008.

Microsoft Visual Studio är en rad Microsoft-produkter , inklusive en integrerad utvecklingsmiljö programvara och ett antal andra verktyg. Dessa produkter låter dig utvecklas som konsolbaserad applikationer och GUI-applikationer , inklusive stöd för Windows Forms-teknik , samt webbplatser , webbservice som i native och kontrolleras koder för alla plattformar som stöds av Windows ,Windows Mobile ,Windows CE , .NET Framework , Xbox , Windows-telefon .NET Compact Framework och Silverlight .

2. DESIGN DEL AV UTVECKLING

2.1 Utveckling av användargränssnitt

När du skapar en spelapplikation är det nödvändigt att ta hänsyn till en av huvudkomponenterna för produktens framgång - gränssnittet. Användargränssnittet i programmet måste först och främst vara begripligt och attraktivt för användaren. Du måste försöka ta bort alla ögonblick som kommer att distrahera användaren eller orsaka honom obehag. Hela programgränssnittet kan delas upp i två komponenter.

) Programmets huvudmeny

Ris. 2.1 - Huvudmeny för programmet

Huvudmenyn är utformad för att låta användaren delta i spelatmosfären, så gränssnittet är designat i färgglada, lekfulla färger. Genom menyn kan du gå till spelplanen, se spelets regler eller avsluta spelet.

) Spelplan

Fig 2.2 - Spelplan

Spelplanen innehåller det omedelbara området för spel, där spelaren och datorn placerar sina ikoner. Innan spelet startas måste användaren välja speltyp som "X vs 0", "1 nivå med dator" eller "2 nivå med dator", annars kommer programmet att ge ett meddelande om vad som ska göras. En knapp som hjälper spelaren att återgå till huvudmenyn. I slutet kommer ytterligare fönster att dyka upp för att informera deltagaren om resultatet av matchen.

Ris. 2.3 - ytterligare spelresultatfönster

2.2 Utveckling av datastrukturer (i extern och RAM)

RAM används för en endimensionell array som består av 9 element som lagrar spelfältets tillstånd, där varje cell i arrayen motsvarar en cell på spelplanen. Minnet spenderas också på statiska variabler: nivånummer, turordning.

Den kräver 803 KB ledigt minne för att fungera.

.3 Utveckling och analys av algoritmer

För att implementera spelets tankealgoritm måste du ställa in en statisk array gcnew array (9); där tillstånden för spelplanen kommer att lagras, där varje cell i arrayen motsvarar en cell. "0" - motsvarar en tom cell, om en spelare flyttade in i cellen, det vill säga "X", registreras värdet "1" och om datorn gjorde ett drag, det vill säga "O", är värdet "2". Inledningsvis är alla arrayelement lika med "0". Det är nödvändigt att ställa in den statiska variabeln lvl, som lagrar nivådata. Det finns 3 nivåer totalt i detta spel: lvl tar värdet "1" om användaren har valt speltypen "X vs O", värdet "2" om "1:a nivån med en dator" och värdet "3" " om "2:a nivå med en dator" " Spelarvariabeln lagrar turordningen ("sant" är spelarens tur, "falskt" är datorns tur). Eftersom rätten att göra det första draget ges till användaren, i början av spelet = sant. Den statiska flaggvariabeln lagrar information om huruvida det finns tomma celler på spelplanen eller inte: om flagga = sant - det vill säga falskt - finns det inga tomma celler. Verifieringsalgoritmen måste innehålla en iteration av parametrarna för arrayen x och lägga fram en egen lösning, som kommer att vara optimal för vidare spel. Detta program har 2 nivåer för att spela med en dator. På nivå 1 är datorns uppgift inte att slå motståndaren. Det är därför denna funktion returnerar det slumpmässiga värdet för cellen dit datorn ska hamna. Koden för denna algoritm presenteras i [Bilaga 1]. Figur 2.4 visar blockschemat för kodimplementeringen.

Det mest vinnande draget i början av spelet är att flytta till mitten av fältet. I funktionen dif_level() kontrolleras ett villkor i början: om spelaren inte gick till det centrala fältet så går datorn dit. Annars, om spelaren gick till centrum, anropas check(2)-funktionen för att kontrollera datorkombinationen och, om det finns en möjlighet att vinna, returnera cellnumret. Om datorn inte kan vinna vid nästa drag, kallas check(1)-funktionen: kontrollera spelarens kombination. Numret på cellen där spelaren skulle ha vunnit om han satsade returneras. Om det inte finns någon sådan kombination anropas low_level()-funktionen.

Fig.2.4. - Blockdiagram

Fig.2.5. - Blockdiagram

3. IMPLEMENTERING AV PROGRAMMET PÅ C++ SPRÅK

.1 Programarkitektur

Detta program implementerar 3 former: huvudmenyn (fig. 2.1), spelplanen (fig. 2.2) och hjälpfältet (spelregler); 12 paneler, varav 9 är huvudpaneler. I slutet av spelet visas också en bildruta med resultatet, det finns 5 totalt (Figur 2.3).

Du kan använda panelklickhanterare som bas, av vilka det finns exakt 9 på spelplanen. Varje hanterare anropar flera funktioner. I början finns det ett villkor, om användaren väljer speltypen "X mot 0", fylls cellerna helt enkelt med värdena 1 eller 2 (kryss eller noll). Därefter kommer funktionerna: förloppsindikering (CrossZero()), som ändrar krysset till noll och vice versa, blockerar ockuperade celler checkingArray(), hitta vinnaren vinnare(). Winner()-funktionen tar hänsyn till alla möjliga vinstalternativ, så om en av spelarna radar upp 3 av sina pjäser (ett kryss eller en nolla) vertikalt, horisontellt eller diagonalt kommer han att vinna. Annars, om fältet är fullt, men ingen av spelarna har ställt upp, anropas funktionen för oavgjort kontroll (_friend()), som kontrollerar om det finns lediga celler kvar på fältet eller inte. Om fr = sant, så finns det inga fria celler på fältet. Om värdet har ändrats betyder det att det finns en ledig cell på fältet.

Det andra villkoret fungerar om den andra eller tredje speltypen väljs. Då kallas funktionen som datorns drag gjordes i: move(int n). Den sänder numret på den cell som spelaren klickade på. Därefter kommer funktionerna: förloppsindikering (CrossZero()), blockering av upptagna celler checkingArray(). Sedan anropas funktionen winner(), som kontrollerar om spelaren vann med detta drag eller inte. Om inte, kontrolleras närvaron av fria celler. Om det finns lediga celler, så rör sig datorn. Därefter, beroende på vilken nivå spelare "1" eller "2" har valt, kallas följande funktioner: low_level(), dif_level(). Funktionen low_level() väljer var nollan ska placeras slumpmässigt, och funktionen dif_level() presenterar en speciell algoritm för att datorn ska vinna. Därefter kommer funktionerna: förloppsindikering (CrossZero()), blockering av upptagna celler checkingArray(). Sedan anropas funktionen winner(), som kontrollerar om datorn vann med detta drag eller inte. Om inte, kontrolleras närvaron av fria celler. Om det finns lediga celler, så flyttar spelaren.

.2 Välja visuella och icke-visuella standardkomponenter

För att genomföra detta arbete valdes följande komponenter:

1) Form1, med givna parametrar Text=Tic-Tac-Toe, ControlBox=False

2) f2, med de angivna parametrarna BackColor, Text=Game

) comboBox1 med de angivna objektparametrarna:

X mot 0

1:a nivån med dator

Nivå 2 med dator

4) panel, med specificerade BackColor-parametrar och olika värden för parametrarna Synlig och Aktiverad. För vissa paneler skrevs händelser som Click.

5) knappen, med de angivna parametrarna Font, Fore Color, BackColor, Text, för alla knappar som händelser som Click skrevs.

6) etikett, med de angivna parametrarna BackColor, Font, Fore Color, Text.

) pictureBox, med specificerade parametrar Image, SizeMode= StretchImage.

) textBox, med de angivna parametrarna BackColor, Font, Fore Color, Text=” ”.

4. TESTRESULTAT

Låt oss testa programmet genom att gå igenom 3 typer av spel.

Låt oss prova funktionerna för huvudmenyknapparna. Knapparna fungerar som de ska. Låt oss försöka starta spelet utan att välja en speltyp. Programmet visar ett felmeddelande och ber dig att välja typ av spel. (Fig. 4.1)

Fig.4.1.

Låt oss välja en typ av spel - "X mot 0", dvs. användare vs användare. I detta skede av spelet kan användaren också spela med sig själv. (Fig.4.2)

Fig.4.2.

Under spelet "Nivå 1 med datorn" sätter inte datorn sig som mål att vinna deltagaren. Han sätter bara nollor lediga platser fält. I detta skede kan användaren enkelt slå datorn. Även på denna nivå är andra alternativ för utveckling av evenemang också möjliga.

Fig.4.3.

Speltyp: "Nivå 2 med dator". I detta skede analyserar spelet alla drag och försöker välja det mest optimala draget. Även här är alla tre scenarierna möjliga, eftersom Datorn gör sitt första steg till en ledig cell. Oftast blir spelet oavgjort.

Fig.4.4.

Programmet körs framgångsrikt på alla testvarianter, utan fel.

SLUTSATS

Vi kan med tillförsikt säga att uppgiften som sattes i början av arbetet har slutförts. Under utvecklingen planerades och utvecklades ett projekt för en remix av det berömda spelet "Tic Tac Toe". Spelet uppfyller de specificerade kraven och uppfyller sina funktioner. Implementerad i arbetet Olika typer spel och svårighetsgrader.

Under arbetets gång bemästrades nya programmeringsmetoder i en integrerad utvecklingsmiljö. Gamla kunskaper om att arbeta med språket C++ har konsoliderats. Som förberedelse inför kursarbetet analyserades olika metoder och algoritmer för att implementera detta spel.

Trots den uppenbara enkelheten i detta program är det fyllt av ett antal svårigheter som implementeras med alla grundläggande tekniker i Visual C++.

Funktionerna i detta program är:

Tydligt konstruerad algoritm;

Intuitivt gränssnitt;

Lätt att använda;

Ganska tydlig bruksanvisning;

Inga onödiga tillägg.

BIBLIOGRAFI

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

BILAGA 1

privat: int low_level())(// procedur för en lätt motståndare;::Random^ rand = gcnew System::Random();(= rand->Nästa(0,8);

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

BILAGA 2

privat: bool check(int n)(k = -1;// kontrollerar alla kombinationer och returnerar rätt drag(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) return true;else return false;

BILAGA 3

privat: int dif_level())(//svår fiende

//retur check(2);(x == 0) return (4);(check(2)) return k; else (check(1)) return k; annars low_level();

ANSÖKAN 4

privat: void CrossZero())(// ändrar krysset till en noll (förloppsindikator)(spelare) (->Visible = true;->Visible = false;

) else (->Synligt = sant;->Synligt = falskt;

): void checkingArray())(// funktion för att kontrollera om det finns något i en cell, om det finns kan du inte klicka på den här cellen längre.(x == 1) (panel1->BackgroundImage = panel11->BackgroundImage ;panel1- >Enabled = false;)(x == 2) (panel1->BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage ;panel2- >Enabled = false;)(x == 2) (panel2->BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage ;panel3- >Enabled = false;)(x == 2) (panel3->BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage ;panel4- >Enabled = false;)(x == 2) (panel4->BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage ;panel5- >Enabled = false;)(x == 2) (panel5->BackgroundImage = panel10->BackgroundImage;panel5->Enabled = false;)(x == 1) (panel6->BackgroundImage = panel11->BackgroundImage ;panel6- >Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Enabled = false;)(x == 1) (panel7->BackgroundImage = panel11->BackgroundImage ;panel7- >Enabled = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Enabled = false;)(x == 1) (panel8->BackgroundImage = panel11->BackgroundImage ;panel8- >Enabled = false;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Enabled = false;)(x == 1) (panel9->BackgroundImage = panel11->BackgroundImage ;panel9- >Enabled = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Enabled = false;)

): bool winner())(// kontrollerar vinnaren och blockerar alla återstående celler.

//bool flagga = 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) ( bildPx->Visible = true;)(picturePobeda->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;true;

): void _friend())(fr = sant;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->Synligt = sant ;)

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

): System::Void button1_Click(System::Object^ avsändare, System::EventArgs^ e) (// nytt spel>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Text;(typeGame == "")(::Show("Välj din speltyp först!");

) else ((typeGame == "X mot 0") lvl = 1;(typeGame == "1:a nivån med en dator") lvl = 2;(typeGame == "2:a nivån med en dator") lvl = 3;( ); = sant;(int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage =>panelImage12->BackgroundImage =>panelImage12->BackgroundImage BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = sant;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true;

): System::Void panel1_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((spelare)( = 1;

)= !spelare;();();();

): System::Void panel2_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel3_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel4_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel5_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel6_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel7_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel8_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((spelare)( = 1;

)= !spelare;();();();

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

): System::Void panel9_MouseClick(System::Object^ avsändare, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((spelare)( = 1;

)= !spelare;();();();

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

): System::Void button2_Click(System::Object^ avsändare, System::EventArgs^ e) (();

): System::Void picturePx_Click(System::Object^ avsändare, System::EventArgs^ e) (>Visible = false;

): System::Void picturePo_Click(System::Object^ avsändare, System::EventArgs^ e) (>Visible = false;

): System::Void picturePobeda_Click(System::Object^ avsändare, System::EventArgs^ e) (>Visible = false;

): System::Void picturePr_Click(System::Object^ avsändare, System::EventArgs^ e) (>Visible = false;

): System::Void pictureN_Click(System::Object^ avsändare, System::EventArgs^ e) (>Visible = false;

Uppmärksamhet! Detta är en introduktionsversion av lektionen, vars material kan vara ofullständigt.

Logga in på sidan som student

Logga in som elev för att få tillgång till skolmaterial

Skapa 1C-konfigurationer: skriv "Tic Tac Toe" del 1/3

Vi kommer att lära oss genom lek, och därför blir vårt första projekt att skapa för alla
ett spel som är bekant från barndomen - "Tic Tac Toe".

Du kanske frågar, vad har spel att göra med 1C, redovisning och handel? Nästan ingen. Men vi måste börja gradvis och med tiden når vi automatiseringen av lager. För nu, låt oss börja smått.

Innan vi börjar programmera Tic-Tac-Toe-spelet, låt oss tänka på det.

Vi vet redan att formuläret har element, varav en är knappen. Knappar kan utföra kommandon och har samtidigt egenskaper som låter dig styra deras visning i formuläret (till exempel en titel).

Till exempel kan du använda en knapp för att skapa ett fält med nio aktiva områden (de celler som vi klickar på och registrerar åtgärden på, samtidigt som vi visar inskriptioner i form av "O" och "X"). Knappen är mer än lämplig för detta.

Vad behöver vi? Uppenbarligen måste vi komma ihåg vårt drag och komma ihåg datorns drag. Vi kommer också att behöva ändra knapptitlarna: när vi klickar är knappens titel alltid "O", när datorn rör sig är det "X".

Först måste vi skapa en ny databas där vi kommer att skapa vårt spel. Nu gör vi det.

Steg #1: Skapa en tom databas

Låt oss skapa en tom Tic-Tac-Toe-databas.

Detaljerade instruktioner

Låt oss starta 1C genväg för att öppna en lista över infobaser tillgängliga på datorn. Du läser en testversion av lektionen, fullständiga lektioner finns tillgängliga. Vi behöver skapande ny bas, så tryck på knappen " Lägg till":

Lägg till fönstret öppnas informationsbas, där du måste välja det första objektet " Skapande av en informationsbas" och klicka på knappen "Nästa":

I nästa fönster, välj det andra objektet " Skapa en informationsbas utan konfiguration för att utveckla en ny konfiguration..." och klicka på knappen "Nästa" igen:

I nästa fönster uppmanas vi att ange namnet på den nya databasen, under vilken den kommer att visas i listan över databaser. Låt oss gå in" Luffarschack" och klicka på knappen "Nästa":

I nästa fönster måste du ange sökvägen till den tomma mapp där vår databas kommer att lagras. I det här fallet skapade jag mappen " Luffarschack" i mappen "1C Databases" på enhet D:

I nästa fönster, lämna alla inställningar som standard och klicka på " Redo":

Efter en kort paus skapades databasen och lades till i listan. Det finns två huvudsätt att arbeta med databasen: 1C:Företag Och Konfigurator:

I konfiguratorläge konfigurerar och programmerar vi databasen, i 1C:Enterprise-läge ser vi vad som kommer av det.

Steg #2: Öppna konfiguratorn

Låt oss trycka på knappen " Konfigurator" för att gå in i konfiguratorläget:

Steg #3: öppna konfigurationsträdet

Utför menykommandot " Konfiguration"->"Öppna konfigurationen":

Ett konfigurationsträd öppnades framför oss, som innehåller olika konfigurationssektioner. Eftersom vi inte har skapat något ännu är dessa sektioner tomma:

Steg #4: lägg till bearbetning

För att placera logiken i vårt spel använder vi avsnittet "Bearbetning". Låt oss klicka Högerklicka på avsnittet " Behandlingar" och välj kommandot "Lägg till":

Ett fönster för att skapa en ny bearbetning har öppnats framför oss. Låt oss ange namnet " Luffarschack". Synonymen kommer att infogas av sig själv. Detta räcker för att spara vår bearbetning (fortfarande tom) i databasen. Klicka på knappen "Stäng":

Steg nr 5: första felsökning av programmet

Du kan kontrollera vad som hände från användarläget ( 1C:Företag). För att komma in direkt från konfiguratorn, kör menykommandot " Felsökning"->"Börja felsöka":

Eftersom vi har gjort en ändring i databasen tillfrågas vi om vi accepterar denna ändring. Vi kommer att få denna fråga ständigt under utvecklingsprocessen. Vi håller med (knapp " Ja"):

Databasen startade i "1C:Enterprise"-läge. Du läser en testversion av lektionen, fullständiga lektioner finns tillgängliga. Men som vi ser är det fortfarande svårt att jobba med det – det finns helt enkelt inget att välja på. Det är konstigt, eftersom vi redan har skapat bearbetningen och i teorin borde den visas på den gula panelen.




Topp