Bir tic-tac-toe oyunu yaratmak. aşama: oyuncunun kazanıp kazanmadığını kontrol edin

Dikkat! İşte materyalleri tamamlanmamış olabilecek dersin deneme sürümü.

Öğrenci olarak giriş yap

Okul içeriğine erişmek için öğrenci olarak oturum açın

1C konfigürasyonları oluşturma: "Tic-tac-toe" bölüm 1/3 yazma

Oynarken öğreneceğiz ve bu nedenle ilk projemiz oluşturmak olacak.
çocukluk oyunundan tanıdık - "Tic-tac-toe".

Oyunların 1C, muhasebe ve ticaret ile ne ilgisi var, soruyorsunuz? Neredeyse hiç. Ama yavaş yavaş başlamamız gerekiyor ve zamanla depoların otomasyonuna ulaşacağız. Şimdilik küçük başlayalım.

Tic-Tac-Toe oyununu programlamaya başlamadan önce bir düşünelim.

Bir formun Öğeleri olduğunu zaten biliyoruz, bunlardan biri Düğme. Düğmeler komutları yürütme yeteneğine sahiptir ve aynı zamanda formdaki görüntülerini (örneğin başlık) denetlemenize olanak tanıyan özelliklere sahiptir.

Örneğin, dokuz etkin nokta içeren bir alan oluşturmak için bir düğme kullanabilirsiniz (bu hücreler, yazıları "O" ve "X" biçiminde görüntülerken tıkladığımız ve eylemi düzelttiğimiz hücreler). Bizi buna fazlasıyla uygun buton.

Neye ihtiyacımız olacak? Açıkçası, hareketimizi hatırlamamız ve bilgisayarın hareketini hatırlamamız gerekecek. Düğme başlıklarını da değiştirmemiz gerekiyor: tıkladığımızda düğme başlığı her zaman "O", bilgisayar hareket ettiğinde - "X".

Ve önce oyunumuzu oluşturacağımız yeni bir veritabanı oluşturmamız gerekiyor. Haydi Yapalım şunu.

Adım 1: Boş bir temel oluşturun

Boş bir Tic-Tac-Toe veritabanı oluşturalım.

Detaylı talimatlar

Hadi koşalım Bilgisayarda bulunan bilgi tabanlarının bir listesini açmak için 1C kısayolu. Dersin deneme sürümünü okuyorsunuz, tam dersler yer almaktadır. Yeni bir veritabanı oluşturmamız gerekiyor, bu yüzden " Eklemek":

İlk öğeyi seçmeniz gereken bir bilgi tabanı eklemek için bir pencere açılacaktır " Bir bilgi tabanının oluşturulması ve "İleri" düğmesini tıklayın:

Bir sonraki pencerede ikinci öğeyi seçin " Yeni bir konfigürasyon geliştirmek için konfigürasyonsuz bir bilgi tabanı oluşturmak... ve tekrar "İleri" düğmesine tıklayın:

Bir sonraki pencerede, üsler listesinde görüntüleneceği yeni üssün adını girmemiz istenir. girelim" tik-tak-toe ve "İleri" düğmesini tıklayın:

Bir sonraki pencerede, veritabanımızın saklanacağı boş bir klasörün yolunu belirtmelisiniz. Bu durumda bir klasör oluşturdum " tik-tak-toe" D diskindeki "Bases 1C" klasöründe:

Bir sonraki pencerede, tüm varsayılan ayarları bırakın ve " Hazır":

Kısa bir duraklamadan sonra veritabanı oluşturulur ve listeye eklenir. Veritabanı ile iki ana çalışma modu vardır: 1C: Kurumsal ve yapılandırıcı:

Konfigüratör modunda, tabanı yapılandırıyor ve programlıyoruz, 1C:Enterprise modunda bunun ne olduğuna bakıyoruz.

Adım 2: yapılandırıcıyı açın

Düğmeye basalım" yapılandırıcı" yapılandırıcı moduna girmek için:

Adım #3: yapılandırma ağacını açın

Menü komutunu yürütün " Yapılandırma"->"Açık yapılandırma":

Önümüze konfigürasyonun çeşitli bölümlerini içeren bir konfigürasyon ağacı açıldı. Henüz bir şey oluşturmadığımız için bu bölümler şu ana kadar boş:

4. Adım: İşleme Ekle

Oyunumuzun mantığını yerleştirmek için "İşleme" bölümünü kullanacağız. hadi basalım sağ tık bölümünde" İşleme ve "Ekle" komutunu seçin:

Bizden önce yeni bir işlem oluşturmak için bir pencere açtı. adını girin" Tic Tac Toe". Eşanlamlı kendi başına değiştirilecektir. Bu, işlemimizi (hala boş) veritabanına kaydetmek için yeterlidir. "Kapat" düğmesine basın:

Adım #5: İlk Önce Programda Hata Ayıklama

Kullanıcı modundan ne olduğunu kontrol edebilirsiniz ( 1C: Kurumsal). Doğrudan yapılandırıcıdan almak için menü komutunu çalıştırın " hata ayıklama"->"Hata Ayıklamayı Başlat":

Veritabanında bir değişiklik yaptığımız için bu değişikliği kabul edip etmeyeceğimiz soruluyor. Bu soru geliştirme sürecinde bize sürekli sorulacak. Rıza ile cevap veriyoruz (düğme " Evet"):

Veritabanı 1C:Enterprise modunda başlatıldı. Dersin deneme sürümünü okuyorsunuz, tam dersler yer almaktadır. Ancak görebildiğimiz gibi, onunla çalışmak hala zor - aralarından seçim yapabileceğiniz hiçbir şey yok. Garip, çünkü işlemeyi zaten yarattık ve teorik olarak sarı panelde görünmesi gerekiyor.

tic-tac-toe'da alt edilemeyen bir bot nasıl yazılır veya minimax kuralına giriş

Yüzlerce tic-tac-toe oyunundan sonra şunu merak etmiş olabilirsiniz: En uygun algoritma nedir? Ama buradaysanız, muhtemelen bu oyunun bir uygulamasını da yazmaya çalıştınız. Daha da ileri gideceğiz ve tic-tac-toe'da yenmesi imkansız olacak bir bot yazacağız. “Neden?” Sorunuzu önceden tahmin ettikten sonra cevap vereceğiz: algoritma sayesinde.

Profesyonel bir satranç oyuncusu gibi, bu algoritma, rakibin hareketlerini birkaç hamle öncesinde - ister zafer, ister yenilgi veya beraberlik olsun, oyunun sonuna ulaşana kadar - hesaplar. Bu son durumdayken, AI kendisine bir galibiyet için pozitif bir puan (bizim durumumuzda +10), bir kayıp için negatif bir puan (-10) ve beraberlik için nötr bir puan (0) verecektir.

Aynı zamanda algoritma, oyuncunun hamleleri için benzer hesaplamalar yapar. AI hareket ederse en yüksek puana sahip hamleyi, oyuncu hareket ederse en düşük puana sahip hamleyi seçecektir. Bu stratejiyi kullanarak minimax yenilgiyi önler.

Bu oyunu oynamayı deneyin.

Minimax algoritması en basit şekilde özyinelemeli bir fonksiyon olarak tanımlanır:

  1. bitiş durumu bulunursa bir değer döndürür (+10, 0, -10),
  2. sahadaki tüm boş hücrelerden geçer,
  3. her biri için minimax işlevini çağırır (özyineleme),
  4. alınan değerleri değerlendirir
  5. ve en iyisini döndürür.

Özyinelemeye aşina değilseniz, Harvard CS50 kursundan bu dersi izlemelisiniz:

Minimax'ın nasıl çalıştığını anlamak için uygulamasını yazalım ve davranışını modelleyelim. Bunu sonraki iki bölümde ele alacağız.

Minimax uygulaması

Oyun sona erdiğinde durumu değerlendireceğiz (aşağıdaki resme bakın). Minimax tüm olası oyun durumlarından geçtiği için (ve bunlardan yüz binlercesi vardır), oyunun sonunu düşünmek mantıklıdır - bu şekilde daha az özyinelemeli işlev çağrısını (toplamda 9) takip etmemiz gerekir.

AI'nın haçlarla oynamasına izin verin, adam - sıfırlarla.

Alanla çalışmayı basitleştirmek için, onu hücrelerin içeriğine eşit değerlere sahip 9 elemanlı bir dizi olarak ilan edelim. Yukarıdaki resimdeki gibi çarpı ve sıfırlarla dolduralım ve origBoard diyelim.

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

Daha sonra aiPlayer ve huPlayer değişkenlerini bildirir ve bunlara sırasıyla "X" ve "O" değerlerini atarız.

Ayrıca, kazanan kombinasyonları arayan ve arama başarılı olursa true değerini döndüren bir işleve ve mevcut hücrelerin dizinlerini depolayan bir işleve ihtiyacımız var.

/* ilk kart durumu O | | X --------- X | | X --------- | O | O */ var origBoard = [“O”,1 ”X”,”X”,4 ”X”, 6 ”O”,”O”]; // insan var huPlayer = “O”; // AI var aiPlayer = "X"; // tahtadaki boş hücrelerin dizinlerinin bir listesini döndürür function emptyIndices(board)( dönüş board.filter(s => s != "O" && s != "X"); ) // kazanan kombinasyonlar, hesap endeksleri fonksiyonu kazanma(pano, oyuncu)( if((pano == oyuncu && masa == oyuncu && masa == oyuncu) || (pano == oyuncu && masa == oyuncu && masa == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu) || (tahta == oyuncu && tahta == oyuncu && tahta == oyuncu)) ( true döndür; ) başka ( false döndür; ))

Şimdi iki argümanla bir minimax fonksiyonu tanımlayalım: newBoard (yeni tahta) ve oyuncu (oyuncu). Daha sonra sahadaki serbest hücrelerin indekslerini buluyor ve bunları availSpots değişkenine aktarıyoruz.

// ana minimax işlev işlevi minimax(newBoard, player)( //mevcut hücreler var availSpots = emptyIndices(newBoard);

Ek olarak, son durumları takip etmemiz ve uygun değerleri döndürmemiz gerekiyor. Sıfır kazanırsa, "çapraz" - +10 ise -10 , döndürmeniz gerekir. BoşSpots dizisinin boyutu sıfırsa, boş hücre yoktur, oyun berabere biter ve sıfır döndürülmelidir.

// terminal durumunu kontrol et (kazan/kaybet/beraberlik) //ve buna göre bir değer döndür if (kazanan(newBoard, huPlayer))( dönüş (skor:-10); ) else if (kazanan(newBoard, aiPlayer)) ( dönüş (skor:10); ) else if (availSpots.length === 0)( dönüş (skor:0); )

Bundan sonra, boş hücrelerin her birinden puan toplamanız gerekir. Bunu yapmak için, bir dizi hareket oluşturalım ve tüm boş hücreler arasında döngü oluşturalım, her hareketin indekslerini ve puanlarını hareket nesnesine koyalım.

Daha sonra origBoard'da sayı olarak saklanan boş hücrenin indeksini move nesnesinin index özelliğine ayarladık. Ardından, mevcut oyuncu için yeni alan newBoard'un boş bir hücresine gidiyoruz ve başka bir oyuncudan minimax işlevini ve sonuçta ortaya çıkan alan newBoard'u çağırıyoruz. Bundan sonra minimax işlevi tarafından döndürülen nesnenin score özelliğini move nesnesinin score özelliğine koymamız gerekir.

Minimax bir son durum bulamazsa, bir uç duruma ulaşana kadar tekrar tekrar oyun içinde derinleşmeye devam eder. Bundan sonra, özyinelemenin bu "seviyesinin" noktalarını bir seviye yukarıya geçer.

Son olarak, işlev newBoard'u sıfırlar ve move nesnesini move dizisine yerleştirir.

// tüm nesneleri depolamak için dizi var move = ; // (var i = 0; i) için kullanılabilir hücreler arasında geçiş yapın< 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'ın daha sonra hareket dizisinden en iyi hareketi seçmesi gerekir. Yapay zeka hareketiyse en yüksek puana, insan hareketiyse en küçük hamleye ihtiyacı var. Bu nedenle, player'ın değeri aiPlayer ise, algoritma bestScore değişkenini çok küçük bir sayıyla başlatır ve hareket dizisi boyunca döngü yapar: eğer hareket hareketi bestScore'dan daha fazla puan alırsa, algoritma o hareketi hatırlar. Aynı noktalara sahip hareketler durumunda, algoritma ilkini hatırlar.

Player'ın huPlayer'a eşit olması durumunda, her şey aynıdır - ancak şimdi bestScore büyük bir sayı ile başlatılır ve minimax, en az sayıda puanla hareket hareketini arar.

Son olarak minimax, bestMove içinde depolanan nesneyi döndürür.

// bu bir yapay zeka hareketiyse, hareketler arasında dolaşın ve en yüksek puana sahip hareketi seçin var bestMove; if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = hamle[i].score; bestMove = i; ) ) )else( // aksi takdirde hamleler arasında dolaşın ve en düşük puana sahip hamleyi seçin var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

Bir sonraki bölümde, nasıl çalıştığını anlamak için programımızın simülasyonunu yapacağız.

Minimax iş başında

Aşağıdaki diyagramı kullanarak algoritmanın adım adım modelini analiz edeceğiz.

Not: Diyagramda, büyük sayılar fonksiyon çağrısının sıra numarasını, seviyeler ise algoritmanın kaç hamle ileri gittiğini gösterir.

  1. Algoritma, origBoard ve aiPlayer ile beslenir. Bulunan üç boş hücrenin bir listesini yapar, durumun sonlu olup olmadığını kontrol eder ve tüm boş hücreler arasında döngü yapar. Algoritma daha sonra aiPlayer'ı ilk boş hücreye yerleştirerek newBoard'u değiştirir. Bundan sonra kendisini newBoard ve huPlayer'dan arar ve ikinci çağrının bir değer döndürmesini bekler.
  2. İlk işlev çağrısı hala çalışırken, ikincisi çalışır, iki boş hücreden oluşan bir liste oluşturur, durumun sonlu olup olmadığını kontrol eder ve tüm boş hücreler arasında döngü oluşturur. İkinci çağrı, huPlayer'ı ilk boş hücreye yerleştirerek newBoard'u değiştirir. Bundan sonra kendisini newBoard ve aiPlayer'dan çağırır ve üçüncü çağrının bir değer döndürmesini bekler.

  3. İkinci çağrı iki boş hücre bulduğundan minimax, huPlayer'ı ikinci boş hücreye yerleştirerek newBoard'u değiştirir. Daha sonra kendisini newBoard ve aiPlayer'dan çağırır.

  4. Algoritma, boş hücrelerin bir listesini derler ve durumun sonluluğunu kontrol ettikten sonra oyuncunun zaferini düzeltir. Bu nedenle, sayı alanı (-10) değerine eşit olan bir nesne döndürür.

    İkinci fonksiyon çağrısında, algoritma üçüncü ve dördüncü fonksiyon çağrıları tarafından alt seviyeden döndürülen değerleri alır. huPlayer hareketi bu iki sonucu ürettiğinden, algoritma bunlardan en küçüğünü seçer. Aynı oldukları için algoritma ilkini seçer ve ilk fonksiyon çağrısına iletir.

    Bu noktada, ilk işlev çağrısı, aiPlayer'ın ilk boş hücreye hareketinin bir tahminini aldı. Ardından, aiPlayer'ı ikinci boş hücreye yerleştirerek newBoard'u değiştirir. Bundan sonra kendisini newBoard ve huPlayer'dan çağırır.

  5. Beşinci işlev çağrısında, algoritma boş hücrelerin bir listesini derler ve durumun sonluluğunu kontrol ettikten sonra AI zaferini sabitler. Böylece sayı alanı +10 olan bir nesne döndürür.

    Bundan sonra, ilk çağrı, aiPlayer'ı üçüncü boş hücreye yerleştirerek newBoard'u değiştirir. Daha sonra kendisini newBoard ve huPlayer'dan çağırır.

  6. Altıncı çağrı, iki boş hücrenin bir listesini derler, durumun sonlu olup olmadığını kontrol eder ve tüm boş hücreler arasında döngü yapar. Daha sonra huPlayer'ı ilk boş hücreye yerleştirerek newBoard'u değiştirir. Ardından kendisini newBoard ve aiPlayer'dan arar ve yedinci çağrının bir değer döndürmesini bekler.
  7. Yeni çağrı bir boş hücreyi listeler, durumun sonlu olup olmadığını kontrol eder ve boş hücreye aiPlayer yerleştirerek newBoard'u değiştirir. Bundan sonra kendisini newBoard ve huPlayer'dan çağırır ve bu çağrının bir değer döndürmesini bekler.
  8. Sekizinci çağrı, boş bir boş hücre listesi derler ve durumun sonluluğunu kontrol ettikten sonra aiPlayer'ın zaferini düzeltir. Bu nedenle, yedinci çağrıya, bir seviye yukarı (+10) eşit sayım alanına sahip bir nesne döndürür.

    Yedinci çağrı, alt seviyelerden yalnızca bir pozitif değer aldı. Bu değer aiPlayer sırasında alındığından, algoritma alınan değerlerin en büyüğünü döndürür. Böylece altıncı aramaya bir seviye yukarı pozitif bir değer (+10) döndürür.

    Altıncı çağrı iki boş hücre bulduğu için minimax, huPlayer'ı ikinci boş hücreye yerleştirerek newBoard'u değiştirir. Daha sonra kendisini newBoard ve aiPlayer'dan çağırır.

  9. Bundan sonra, algoritma boş hücrelerin bir listesini derler ve durumun sonluluğunu kontrol ettikten sonra aiPlayer'ın zaferini düzeltir. Bu nedenle, bir seviye yukarıya (+10) eşit bir sayı alanı olan bir nesne döndürür.

    Bu noktada altıncı çağrı, yedinci çağrının verdiği puan (+10) ile dokuzuncu çağrının verdiği puan (-10) arasında seçim yapmalıdır. huPlayer'ın hareketi bu iki sonucu verdiğinden, algoritma bunlardan en küçüğünü seçer ve onu puan ve indeks alanlarıyla bir nesne olarak seviye yukarı döndürür.

    Son olarak, ilk çağrının üç şubesi de değerlendirilir (-10, +10, -10). aiPlayer'ın hareketi bu üç sonucu verdiğinden, algoritma en yüksek puanı (+10) ve indeksini (4) içeren nesneyi seçer.

Yukarıda tartışılan senaryoda minimax, alanın merkez karesine taşınmanın en iyi seçim olduğuna karar verir.

Son!

Şimdiye kadar minimax algoritmasının nasıl çalıştığını anlamalısınız. Kendiniz bir uygulama yazmayı deneyin veya GitHub veya CodePen'deki bir örneğe göz atın ve optimize edin.

Oyunlarda AI konusuyla ilgileniyorsanız, bu konudaki materyallerimizi okumanızı tavsiye ederiz.

ADIM 1. FORM PARAMETRELERİNİN AYARLANMASI1. Formu özelleştirmek için boyutunu ayarlayın
510 yatay nokta ve 480 dikey nokta
dikey. maksimum ve minimum
aynı değerlere eşit boyutu belirtin.
2. Şekli "Tic Tac Toe" kelimesiyle adlandırın.
3. Formun arka planı için klasördeki dosyayı kullanın.
Arkaplan.png adı altındaki resimler ve yerleştirin
formun ortasında.
4. Başlık çubuğundaki simge için
klasörden use dosyasını kullan
menu4.ico adlı resimler.
5. Form arka plan renginin ayarlanması gerekiyor
Nane Kreması.

ADIM 2. FORMA BİR BUTON VE BİR SINIF EKLEYİN

1. Yerleştirilen öğeler için değiştirin
yazı tipi boyutu 12 ve arka plan seti
şeffaf.

1. Öğeler içeren bir menü çubuğu oluşturun.
resimde belirtildiği gibi.

ADIM 3. MENÜ ÇUBUĞUNU FORMA EKLEME

1. Dosya menü öğesinde bir komut oluşturun
Çıkış.
2. için
takımlar
çıkış
Reçetelemek
program kodu aynı
önceki uygulama

ADIM 3. MENÜ ÇUBUĞUNU FORMA EKLEME

1. Oyun menü öğesinde bir ekip oluşturun
Yeni oyun.
2. Yeni Oyun ekibi için şunu yazın:
program kodu gelecekte
birkaç adım.

ADIM 3. MENÜ ÇUBUĞUNU FORMA EKLEME

1. Yardım menü öğesinde bir komut oluşturun
Program hakkında.
2. Hakkında komutu için yeni bir tane oluşturun
program kodunu oluştur ve yaz
öncekine benzer
uygulama.

1. Bir PictureBox'ı forma sürükleyerek
boyutunu 100x100 olarak değiştirin.
2. Saydam bir arka plan ayarlayın.
3. PictureBox'ı şekilde gösterildiği gibi düzenleyin.
oyun alanının ilk hücresinin üzerindeki şekil.

ADIM 4. FORMA RESİM KUTUSU NESNELERİ EKLEYİN

1
2
3
4
5
6
7
8
9
1. Yerleştirdiğimiz hücrelerin geri kalanının üstünde
PictureBox nesneleri, ilkinin kopyaları
nesne, üzerinde belirtilen numaralandırmaya göre
Görüntüler.

1. Kod yazmadan önce
bir klasörde gerekli
\Görsel stüdyo
2010\Projeler\Tic Tac Toe \ Tic Tac Toe
sıfırlar\bin\Debug\ yeniden yönlendirilmesi gerekiyor
x.png, 0.png, none.png dosyaları Görüntüler klasöründen.
2. İlkinde farenin sol tuşuna çift tıklayın.
Resim kutusu.

ADIM 5. RESİM KUTUSU NESNELERİ İÇİN KOD EKLEYİN

1. İçindeki tüm öğelere erişilebilen iki boyutlu bir dizi oluşturun.
tamsayılardan oluşan 3x3 eleman şeklinde oluşturulur. Hemen
bildirirken sıfırlarla dolduruyoruz. boş hücreler için
0, "çarpmalar" için - 1 ve "sıfırlar" için - -1 kullanacağız.

ADIM 5. RESİM KUTUSU NESNELERİ İÇİN KOD EKLEYİN

İlk tıklandığında prosedürde
PictureBox, operatör ekleme
tercih
hangisi
niyet
durum kontrolü yap
dizi hücreleri. eğer değer
dizi hücresi 0 olacak, bu
Bu, içinde "sıfır" olmadığı anlamına gelir.
"çapraz", sonra bu hücrede
dizi 1 yazılır ve
Resim Kutusu1
görüntülenen
"haç" görüntüsü ve eğer
dizi hücre değeri olacak
1'e eşittir, o zaman içerir
"çapraz" ve içine 0 yazılır ve
boş bir hücre görüntülenir.

ADIM 5. RESİM KUTUSU NESNELERİ İÇİN KOD EKLEYİN

1
2
3
4
5
6
7
8
9



Alanın kalan hücreleri için kodu ekleyin
ilkinde olduğu gibi, sadece değişen
PictureBox nesne numarası ve hücre adresi
sıralamak.
ÖRNEK ikinci hücre için:

Düğme tıklama prosedürü için
Ekle
Şebeke
Çevrim
kim kontrol eder
ilk hücreden tüm hücrelere
boş hücrelerin varlığı. Ve eğer
hücre boş
sonra içine
"sıfır" yazılır, yani
dizi hücresi -1 yazılır.
Gelecekteki çalışmalarda kolaylık sağlamak için
değişkenler
Bence
J
hangisi
döngüleri yinelemek için kullanılır
tüm form için beyan.

ADIM 6. YÜRÜME DÜĞMESİ İÇİN PROGRAM KODUNU EKLEYİN

üzerinde sıfırları görüntülemek için
oyun oynamak
alan
gerekli
gövdeye program kodu ekleyin
boşluk için hücreleri kontrol etme döngüsü.
İç içe operatör ile
dallanma
niyet
yer almak
dizi hücre adresi için ayrıştırma
doğru çıkış sıfır
Resim kutusu.
Ayrıca bir break ifadesi ekliyoruz
erken son için
boşken döngü
hücreler.

ADIM 6. YÜRÜME DÜĞMESİ İÇİN PROGRAM KODUNU EKLEYİN

Oyun durumunu belirtmek için
arayüz elemanı kullanılır
Etiket1. Oyuncu her zaman hareket ettiğinden
ilk
sonra
de
İndirilenler
uygulamalar
gerekli
v
eleman
etiket1
gerekli
yansıtmak
ifadeler "senin
taşınmak."
İçin
Bugün nasılsın
oluşturmak
değişken
Cevap
hangisi
Bu ifadeyi ele alalım. A
form değişkenini yüklerken
elemana atanmalıdır
Label1, gerekli olanı oluşturmak için
prosedürler
gerekli
önce çift tıklayın
bilgi vermek

ADIM 7. YENİ OYUN MENÜ ÖĞESİ İÇİN KOD EKLEYİN

Yeni komuta tıkladığınızda
oyun sıfırlanacak
dizideki tüm hücreler, tümünün yerine
üzerinde "haçlar" ve "hiçbir şey"
boş hücreler. Ayrıca çıktı
"Hareketiniz" yazısı

ADIM 8. OYUN SONUÇLARINI GÖRÜNTÜLE

Hareketlerin sonuçlarını kontrol etmek için
gerekli
analiz etmek
satırların, sütunların içeriği ve
köşegenler. Her üç unsur ise
1'e eşitse, bu oyuncu için bir zaferdir ve
eğer üç -1 ise o zaman bu bir yenilgidir
oyuncu.
Zafer kontrolü gerekli
yönetmek
ön
taşınmak
bilgisayar,
a
doğrulama
sonrası yenilgi.
Prosedürün son komutu
sonuçları gösterecek
taşınmak.

ADIM 8. OYUN SONUÇLARINI GÖRÜNTÜLE

Kullanıcının kazandığını kontrol etmek için program kodu:
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Kazandın";
Kullanıcının kazandığını kontrol etmek için program kodu:
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Kaybettiniz";
etiket1.metin = yanıt;

ADIM 9 "OYNATILABİLİRLİĞİ" İYİLEŞTİRİN

Oynanabilirliği geliştirmek için
seri çıkış yerine
ilk boşta
"sıfır" hücreleri uygularız
rastgele üreteç aracılığıyla çıktı
sayılar.
Bunun için eklemeniz gerekir
bir boole değişkeni
uslovie ve döngü türünü For'dan değiştirin
sırasında, çünkü bilmiyoruz
tam tekrar sayısı
rastgele numara üreticisi
boş bir hücreye düşmeyecektir.

RUSYA EĞİTİM VE BİLİM BAKANLIĞI

yüksek mesleki eğitim federal devlet bütçe eğitim kurumu

"Vologda Devlet Üniversitesi"

Otomasyon ve Bilgisayar Mühendisliği Bölümü

Disiplinle ilgili kurs projesine açıklayıcı not

Programlama ve algoritmalaştırmanın temelleri

"Tic Tac Toe"

Yerine getirilmiştir EM-21 grubu öğrencisi

Butorova L.Yu.

kabul edilmiş Rzheutskaya S. Yu.

GİRİŞ

1. PROBLEMİN ANALİZİ VE GELİŞTİRİLEN PROGRAM İÇİN GEREKLİLİKLERİN BELİRLENMESİ

1 Programın amacı, kullanıcıları, geliştirme sırasında izlenen ana işlevler ve hedefler

2 Benzer işlevleri yerine getiren iyi bilinen programlara genel bakış

3 Gelişimin teorik temelleri

4 Geliştirme araçlarının seçimi

GELİŞTİRMENİN TASARIM BÖLÜMÜ

1 Kullanıcı arayüzünün tasarlanması

2.2 Veri yapılarının geliştirilmesi (harici ve RAM'de)

2.3 Algoritmaların geliştirilmesi ve analizi

C++'DA PROGRAM UYGULAMASI

1 Program mimarisi

2 Standart görsel ve görsel olmayan bileşenlerin seçimi

TEST SONUÇLARI

ÇÖZÜM

bibliyografya

Uygulamalar

GİRİŞ

Tic-tac-toe - 3'e 3 hücre veya daha büyük ("sonsuz alana" kadar) kare bir alanda iki rakip arasında mantıklı bir oyun. Oyunculardan biri "çarpma" ile, ikincisi - "hayır" ile oynuyor. Bu oyun bilgisayarların ortaya çıkmasından çok önce popüler hale geldi, ancak daha önce basit bir kağıt parçası ve bir kalemle oynandı. Geleneksel Çin oyunu siyah ve beyaz taşlar kullanır.

Bu ders çalışmasında oyun alanının temel kuralları ve standart boyutu (3x3 hücre) korunur. Oyunun rahatlığı için ilk hamlenin sağı kullanıcıya bırakılmıştır, yani "çarpma".

Tic-tac-toe, kullanıcıyı eğlendirmek için tasarlanmış bir programdır, bu nedenle, bu ders çalışmasında arayüzü, oyunun duygusal kısmını şiddetlendiren pozitif renklerin bir kombinasyonu ile oyun tarzında yapılmıştır.

Oyunda üç tür vardır: X'e karşı 0 - kullanıcıya karşı kullanıcı, "1 seviye bilgisayarla" - dünya oyununun temellerini yeni öğrenenler için ve seviye "bilgisayarla 2 seviye" - zaferlerinden kesinlikle eminler. 1. ve 2. seviyelerde üç sonuç mümkündür: "kazan", "kaybet" ve "beraberlik". Dikey, yatay veya diyagonal tamamen çarpılar veya boşluklarla doluysa kazanç sabittir.

Alanın serbest hücreleri bittiyse ancak kimse kazanamadıysa, oyunun berabere bittiği kabul edilir.

1. PROBLEMİN ANALİZİ VE GELİŞTİRİLEN PROGRAM İÇİN GEREKLİLİKLERİN BELİRLENMESİ

program çapraz arayüzü

1.1 Programın amacı, kullanıcıları, geliştirme sırasında izlenen ana işlevler ve hedefler

Bu programın amacı, her şeyden önce, bir kişinin bekleme süresini aydınlatmak için kullanıcıları eğlendirmektir, çünkü herhangi bir işin dinlenmeye ihtiyacı vardır ve bu basit oyun, rahatlamanıza ve günlük işlerden uzaklaşmanıza yardımcı olacaktır. Ayrıca, "tic-tac-toe", mantıksal düşünmeyi eğitmek için tasarlanmış, konsantre olmanızı ve hafıza geliştirmenizi sağlayan entelektüel ve mantıksal oyunlar sınıfına aittir.

Kullanıcıların hedef kitlesi, yetişkinlerin yanı sıra çocuklar ve gençlerdir. Ürünü kullanmanın ana kriteri, programda yazılan metni okuyabilmesi ve butonları kullanarak bilgisayar için gerekli görevi seçebilmesidir.

Bundan, ana görevlerin şunlar olduğu sonucuna varabiliriz: eğlence görevi ve bir kişinin mantıksal potansiyelini geliştirme görevi.

1.2 Benzer işlevleri yerine getiren bilinen programlara genel bakış

İnternette bu oyunu uygulayan çok sayıda eser bulabilirsiniz. Şu anda, bu oyunun orijinal standartlardan ayrılan birçok analogu var. Bu tür programların örnekleri, Sonsuz Alanda Tic-Tac-Toe ve Tic-Tac-Toe 3D'dir. Ayrıca, birçok oyunda "haçlar" ve "ayak parmakları", örneğin "taşlar" gibi başka sembollerle değiştirilir.

Ders projem bir PC uygulamasıdır. Oyun, rakibi yapay zeka (veya bilgisayar) olan bir kullanıcı ve iki kullanıcı için tasarlanmıştır. Klasik 3x3 sahada sunulmaktadır.

Bence en ilginç ve sıradışı olanı "Tic Tac Toe 3D" oyunuydu. Bu yüzden karşılaştırma için seçtim.

Üç boyutlu tic-tac-toe, kağıt üzerinde veya normal bir alanda olduğundan çok daha ilginçtir. Burada kazanmak ve kaybetmek için daha fazla fırsat var ve beraberlik daha nadir. Tek başınıza - bilgisayara karşı - veya bir arkadaşınızla birlikte oynayabilirsiniz. Ve burada en sıra dışı olan şey, kazanmak için kendi renginizden (siyah veya beyaz) üç topun bir kombinasyonunu yalnızca herhangi bir seviyede değil, aynı zamanda duvarların düzlemi boyunca ve hatta tümün köşegeni boyunca yapabilmenizdir. alan (Şekil 1.1).

Pirinç. 1.1

Benzer bir temanın çok çeşitli oyunları arasında, her çalışmada planın benzersiz bir uygulamasını ayırt edebilirsiniz. Her proje kendi bireyselliği ile diğerlerinden farklıdır.

1.3 Gelişimin teorik temelleri

analiz

Algoritmalar, tarafların her biri için iyi bilinir ve rakibin herhangi bir oyununda beraberliği garanti eder ve eğer bir hata yaparsa, kazanmanıza izin verir. Yani oyun durumda "kimsenin ölümü"<#"877528.files/image002.gif">

Şekil 1.2. Oyun durumları ağacı

tic-tac-toe oyunu için oyun durumlarının kısmi bir ağacı Şekil 1.2'de gösterilmektedir. "tic-tac-toe" için oyuncunun ilk gittiği ve yukarıdaki algoritmaya göre hareket ettiği ve "tac-toe" için oyuncunun istediği her şeyi yapabileceği tic-tac-toe oyunu için oyun durumları ağacı (ayrıca, rasyonel ve irrasyonel bir eylem için bir köşe verilir, yani herhangi biri), 50 düğümden oluşur.

1.4 Geliştirme araçlarının seçimi

Görevlerimizi uygulamak için entegre bir uygulama geliştirme ortamına ihtiyaç vardır. Bu nedenle proje Microsoft Visual Studio 2008 programlama ortamında geliştirilmiştir.

Microsoft Visual Studio - Microsoft ürün grubu entegre bir geliştirme ortamı dahil yazılım ve bir dizi başka araç. Bu ürünler bir konsol olarak geliştirmenize izin verir uygulamalar GUI uygulamalarının yanı sıra Windows Forms teknolojisi desteği dahil web sitelerinin yanı sıra , Ağ hizmetleri yerli olarak , ve kontrollü Windows tarafından desteklenen tüm platformlar için kodlar Windows Mobil , Windows CE .NET Çerçevesi , Xbox , Windows Phone .NET Kompakt Çerçeve ve Silverlight .

2. GELİŞTİRMENİN TASARIM BÖLÜMÜ

2.1 Kullanıcı arayüzünün tasarlanması

Bir oyun uygulaması oluştururken, ürünün başarısının ana bileşenlerinden birini hesaba katmak gerekir - bu arayüz. Programın kullanıcı arayüzü her şeyden önce kullanıcı için anlaşılır ve çekici olmalıdır. Kullanıcının dikkatini dağıtacak veya rahatsız olmasına neden olacak tüm anları ortadan kaldırmaya çalışmanız gerekir. Programın tüm arayüzü iki bileşene ayrılabilir.

) Program ana menüsü

Pirinç. 2.1 - Programın ana menüsü

Ana menü, kullanıcının oyun atmosferine katılmasına izin verecek şekilde tasarlanmıştır, bu nedenle arayüz renkli, eğlenceli renklerde yapılmıştır. Menü aracılığıyla oyun alanına gidebilir, oyunun kurallarını görebilir veya oyundan çıkabilirsiniz.

) oyun alanı

Şekil 2.2 - Oyun alanı

Oyun alanı, oyuncunun ve bilgisayarın simgelerini koyduğu oyun için hemen alanı içerir. Oyuna başlamadan önce, kullanıcı "X vs 0", "1 seviye bilgisayarlı" veya "2 seviye bilgisayarlı" gibi bir oyun türü seçmelidir, aksi takdirde program size ne yapmanız gerektiğini söyleyen bir mesaj isteyecektir. Oyuncunun ana menüye dönmesine yardımcı olacak bir düğme. Sonunda, katılımcıyı düello sonuçları hakkında bilgilendirecek ek pencereler açılacaktır.

Pirinç. 2.3 - ek oyun sonucu pencereleri

2.2 Veri yapılarının geliştirilmesi (harici ve RAM'de)

RAM, dizinin her bir hücresinin oyun alanındaki bir hücreye karşılık geldiği oyun alanının durumlarını saklayan 9 öğeden oluşan tek boyutlu bir dizi için kullanılır. Bellek ayrıca statik değişkenler için de harcanır: seviye numarası, sıra sırası.

Çalıştırmak için 803 KB boş bellek gerekir.

.3 Algoritmaların geliştirilmesi ve analizi

Oyun düşünme algoritmasını uygulamak için statik diziyi gcnew dizisini belirtmelisiniz (9); oyun alanının durumlarının saklanacağı, dizinin her bir hücresinin bir hücreye karşılık geldiği. "0" - boş bir hücreye karşılık gelir, oyuncu hücreye gittiyse yani "X" ise "1" değeri kaydedilir ve bilgisayar hareketi yaptıysa yani "O" ise değer "2". Başlangıçta dizinin tüm elemanları "0"a eşittir. Seviye verilerini depolayan statik değişken lvl'yi ayarlamalısınız. Bu oyunda toplam 3 seviye vardır: lvl, kullanıcı "X vs. O" oyun türünü seçtiyse "1" değerini, "bilgisayarla 1 seviye" ise "2" değerini ve "değerini alır. 3" ise "bilgisayarla 2 seviye". Değişken oyuncu - hareketin sırasını saklar ("doğru" - oyuncunun hareketi, "yanlış" - bilgisayarın hareketi). İlk hamle hakkı kullanıcıya verildiğinden oyunun başında oyuncu = true olur. Bayrak statik değişkeni, oyun alanında boş hücreler olup olmadığı hakkında bilgi depolar: eğer flag = true - yani, false - boş hücre yoktur. Doğrulama algoritması, x dizisinin parametrelerinin numaralandırılmasını içermeli ve sonraki oyun için en uygun olacak kendi çözümünü ortaya koymalıdır. Bu program oyunun 2 seviyesini bilgisayar ile birlikte sunar. 1. seviyede, bilgisayarın görevi rakibi yenmek değildir. Dolayısıyla bu fonksiyon bilgisayarın gideceği hücrenin rastgele bir değerini döndürür. Bu algoritmanın kodu [Ek 1]'de sunulmuştur. Şekil 2.4, kod uygulamasının bir blok şemasını göstermektedir.

Oyunun başında en çok kazandıran hamle, alanın ortasına yapılan hamledir. dif_level() işlevinde, başlangıçta koşul kontrol edilir: oyuncu orta sahaya gitmediyse, bilgisayar oraya gider. Aksi takdirde, oyuncu merkeze gittiyse, bilgisayarın kombinasyonunu kontrol etmek için check(2) işlevi çağrılır ve eğer kazanmak mümkünse hücre numarasını döndürür. Bilgisayar bir sonraki hamlede kazanamazsa, check(1) işlevi çağrılır: oyuncunun kombinasyonunu kontrol etmek. Oyuncunun kazanacağı bahis, hücrenin numarası döndürülür. Böyle bir kombinasyon yoksa, low_level() işlevi çağrılır.

Şekil 2.4. - Akış şeması

Şekil 2.5. - Akış şeması

3. PROGRAMIN C++ İLE UYGULANMASI

.1 Program mimarisi

Bu program 3 form uygular: ana menü (Fig.2.1.), oyun alanı (Fig.2.2) ve yardım alanı (oyunun kuralları); 9'u ana olmak üzere 12 panel. Ayrıca oyunun sonunda sonuçla birlikte bir pictureBox belirir, toplamda 5 tane vardır (Şekil 2.3).

Temel olarak, oyun alanında tam olarak 9 tane olan panel tıklama işleyicilerini alabilirsiniz. Her işleyici birkaç işlevi çağırır. Başlangıçta bir koşul vardır, kullanıcı "X'e karşı 0" oyun türünü seçerse, sadece hücreler 1 veya 2 (çapraz veya sıfır) değerleriyle doldurulur. Daha sonra işlevler gelir: haçı sıfıra ve tam tersine değiştiren hareketin göstergesi (CrossZero()), Array() öğesini kontrol ederek işgal edilen hücreleri bloke eder, kazananı() bulur. Winner() işlevinde, olası tüm kazanma seçenekleri göz önünde bulundurulur, bu nedenle, oyunculardan biri figürlerinden 3'ünü (çapraz veya sıfır) dikey, yatay veya çapraz olarak sıralarsa, kazanır. Aksi takdirde, alan doluysa, ancak oyunculardan hiçbiri arka arkaya dizilmediyse, (_friend()) işlevi çağrılır - sahada boş hücreler olup olmadığını kontrol eden bir beraberlik olup olmadığını kontrol edin. fr = true ise, alanda boş hücre yoktur. Değer değiştiyse, alanda boş bir hücre var.

İkinci koşul, ikinci veya üçüncü oyun türü seçildiğinde çalışır. Ardından, bilgisayarın hareketinin (int n) gerçekleştirildiği fonksiyon çağrılır. Oyuncunun tıkladığı hücrenin numarasını alır. Ardından işlevler gelir: ilerleme göstergesi (CrossZero()), Array() öğesini kontrol ederek dolu hücrelerin engellenmesi. Ardından, oyuncunun bu hamleyi kazanıp kazanmadığını kontrol eden kazanan() işlevi çağrılır. Değilse, serbest hücrelerin varlığı kontrol edilir. Boş hücreler varsa, bilgisayar hareket eder. Ayrıca, oyuncunun "1" veya "2" hangi seviyeyi seçtiğine bağlı olarak, sırasıyla şu fonksiyonlar çağrılır: low_level(), dif_level(). low_level() işlevi sıfırın nereye koyulacağını rastgele seçer ve dif_level() işlevi bilgisayarın kazanması için özel bir algoritma sağlar. Ardından işlevler gelir: ilerleme göstergesi (CrossZero()), Array() öğesini kontrol ederek dolu hücrelerin engellenmesi. Daha sonra, bilgisayarın bu hareketi kazanıp kazanmadığını kontrol eden kazanan() işlevi çağrılır. Değilse, serbest hücrelerin varlığı kontrol edilir. Boş hücreler varsa, oyuncu hareket eder.

.2 Standart görsel ve görsel olmayan bileşenlerin seçimi

Bu çalışmanın uygulanması için aşağıdaki bileşenler seçildi:

1) Form1, verilen parametrelerle Text=Tic-Tac-Toe, ControlBox=False

2) f2, BackColor seti ile, Metin=Oyun

) verilen Öğeler parametreleriyle comboBox1:

X'e karşı 0

1. seviye bilgisayar

2. seviye bilgisayar

4) Panel, verilen BackColor parametreleri ve Visible ve Enabled parametrelerinin farklı değerleri ile. Bazı paneller için Click gibi olaylar yazıldı.

5) butonu ile belirtilen Font, Fore Color, BackColor, Text parametreleri ile tüm butonlar için Click gibi olaylar yazılmıştır.

6) BackColor , Font, Fore Color, Text parametreleri ile etiketleyin.

) imageBox, Image parametreleri ayarlanmış, SizeMode= StretchImage.

) textBox, verilen parametrelerle BackColor, Font, Fore Color, Text=” ”.

4. TEST SONUÇLARI

3 çeşit oyun üzerinden geçerek programı test edelim.

Ana menü düğmelerinin eylemlerini deneyelim. Düğmeler düzgün çalışıyor. Oyun türü seçmeden oyuna başlamayı deneyelim. Program bir hata mesajı görüntüler ve sizden oyun türünü seçmenizi ister (Şek.4.1)

Şekil 4.1.

1 oyun türü seçelim - "X'e karşı 0", yani. kullanıcı vs kullanıcı Oyunun bu aşamasında kullanıcı kendisi ile de oynayabilir. (Şek.4.2)

Şekil 4.2.

“Bilgisayarla 1 seviye” oyunu sırasında bilgisayar, katılımcıyı kazanma hedefini belirlemez. Alanın boş yerlerine sadece sıfırlar koyar. Bu aşamada kullanıcı bilgisayarı rahatlıkla yenebilir. Bu seviyede olmasına rağmen, başka senaryolar da mümkündür.

Şekil 4.3.

Oyunun türü "Bilgisayarlı 2. Seviye". Bu aşamada oyun tüm hamleleri analiz eder ve en uygun hamleyi seçmeye çalışır. Olayların gelişiminin üç çeşidi de burada mümkündür, çünkü Bilgisayar herhangi bir boş hücreye ilk hamlesini yapar. Çoğu zaman oyun berabere biter.

Şekil4.4.

Program, tüm test varyantlarında hatasız olarak başarıyla çalışır.

ÇÖZÜM

İşin başında belirlenen görevin tamamlandığını söyleyebiliriz. Geliştirme sürecinde ünlü Tic-Tac-Toe oyununun bir remiks projesi planlandı ve geliştirildi. Oyun belirtilen gereksinimleri karşılar ve işlevlerini yerine getirir. Çalışmada çeşitli oyun türleri ve zorluk seviyeleri uygulanmaktadır.

Çalışma sırasında, entegre geliştirme ortamında yeni programlama yöntemlerine hakim olundu. C++ diliyle çalışma konusundaki eski bilgiler düzeltildi. Ders çalışmasına hazırlık olarak, bu oyunun uygulanması için çeşitli yöntemler ve algoritmalar analiz edildi.

Bu programın görünen basitliğine rağmen, Visual C ++ 'ın tüm temel teknikleri kullanılarak uygulanan bir takım zorluklarla doludur.

Bu programın özellikleri şunlardır:

Açıkça oluşturulmuş algoritma;

Sezgisel arayüz;

Kullanım kolaylığı;

Tamamen net kullanım kılavuzu;

Ekstra ekstra yok.

KAYNAKÇA

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

EK 1

private: int low_level()(// düşük bir rakip için prosedür;::Random^ Rand = gcnew System::Random();(= Rand->Next(0,8));

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

EK 2

private: bool check(int n)(k = -1;// tüm kombinasyonları kontrol eder ve doğru hareketi döndürür(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 = 0) = n)&&(x == 0))) k =4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0))) k =6;((x = 0) = 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 = 0) = n)&&(x == 0))) k =4;

)(x == n) (((x == n)&&(x == 0) k =0;((x == n)&&(x == 0))) k =3;((x = 0) = 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) true döndür, yoksa false döndür;

EK 3

özel: int dif_level()(//zor düşman

//dönüş kontrol(2);(x == 0) dönüş (4);(kontrol(2)) dönüş k; başka (kontrol (1)) k döndür; yoksa low_level();

EK 4

private: void CrossZero()(// çarpıyı sıfıra değiştirir(ilerleme göstergesi)(oyuncu) (->Görünür = doğru;->Görünür = yanlış;

) else (->Görünür = doğru;->Görünür = yanlış;

): void kontrolArray()(// hücrede bir şey olup olmadığını kontrol etme işlevi, varsa artık bu hücreye tıklayamazsınız. >Enabled = false;)(x == 2) (panel1-> BackgroundImage = panel10->BackgroundImage;panel1->Etkin = yanlış;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage;panel2- >Etkin = yanlış;)(x == 2) (panel2-> BackgroundImage = panel10->BackgroundImage;panel2->Etkin = yanlış;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage;panel3- >Etkin = yanlış;)(x == 2) (panel3-> BackgroundImage = panel10->BackgroundImage;panel3->Etkin = yanlış;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage;panel4- >Etkin = yanlış;)(x == 2) (panel4-> BackgroundImage = panel10->BackgroundImage;panel4->Etkin = yanlış;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage;panel5- >Etkin = yanlış;)(x == 2) (panel5-> BackgroundImage = panel10->BackgroundImage;panel5->Etkin = yanlış;)(x == 1) (panel6->B ackgroundImage = panel11->BackgroundImage;panel6->Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Etkin = false;)(x == 1) (panel7-> BackgroundImage = panel11->BackgroundImage;panel7->Etkin = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Etkin = false;)(x == 1) (panel8-> BackgroundImage = panel11->BackgroundImage;panel8->Etkin = yanlış;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Etkin = yanlış;)(x == 1) (panel9-> BackgroundImage = panel11->BackgroundImage;panel9->Etkin = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Etkin = false;)

): bool kazanan()(// kazananı kontrol edin ve kalan tüm hücreleri engelleyin.

//bool flag = 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;)->Etkin = false;->Etkin = false;->Etkin = false;->Etkin = false;-> Etkin = false;->Etkin = false;->Etkin = false;->Etkin = false;->Etkin = false;doğru;

)(((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) ) ( picturePx->Visible = true;)(picturePobeda->Visible = true;)->Etkin = false;->Etkin = false;->Etkin = false;->Etkin = false;->Etkin = false;- > Etkin = false;->Etkin = false;->Etkin = false;->Etkin = yanlış;doğru;

): void _friend()(fr = true;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->görünür=doğru;)

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

): System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) (// new game>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Text;(typeGame == "")(::Show("Önce oyun türünü seçin!");

) else ((typeGame == "X'e karşı 0") lvl = 1;(typeGame == "Bilgisayar düzeyi 1") lvl = 2;(typeGame == "Bilgisayar düzeyi 2") lvl = 3;(); = true ;(int ben = 0; ben< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12-> BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;->Etkin = true;

): System::Void panel1_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((player)( = 1;

)= !oyuncu;();();();

): System::Void panel2_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel3_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel4_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel5_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel6_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel7_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel8_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((player)( = 1;

)= !oyuncu;();();();

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

): System::Void panel9_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((player)( = 1;

)= !oyuncu;();();();

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

): System::Void button2_Click(System::Object^ gönderen, System::EventArgs^ e) (();

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

): System::Void picturePo_Click(System::Object^ gönderen, System::EventArgs^ e) (>Visible = false;

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

): System::Void picturePr_Click(System::Object^ gönderen, System::EventArgs^ e) (>Visible = false;

): System::Void pictureN_Click(System::Object^ gönderen, System::EventArgs^ e) (>Visible = false;

Selamlar sevgili arkadaşlar! Bu derste size javascript ile nasıl bir tarayıcı oyunu - tic-tac-toe yapabileceğinizi göstereceğim! Hepiniz bu oyunun ne olduğunu ve nasıl oynandığını biliyorsunuz ama tekrar hatırlatmama izin verin:

Tic-tac-toe, 3'e 3 kare (muhtemelen daha büyük) bir alanda iki oyuncu arasında oynanan bir mantık oyunudur. Biri "haçlar" ile, ikincisi - "tak-toes" ile oynuyor.

not Tüm benzer javascript eğitimlerinde olduğu gibi, makalenin sonunda kaynak dosyayı indirebilir, ayrıca çalışmanın sonucunu demo örneğinde görebilirsiniz!

Oluşturulan oyunun açıklaması

Gelelim oyunun özelliklerine:

  • oyun, sayfa yüklendikten hemen sonra başlar;
  • ilk hareket hakkı rastgele seçilir (ya yürümeye başlarsınız ya da bilgisayar);
  • koyacağınız işaret rastgele seçilir (çapraz veya sıfır);
  • oyuncu kazanırsa, kazanan semboller (bir çarpı veya sıfır şeridi) yeşil renkle vurgulanır;
  • oyuncu bilgisayara kaybederse, çubuk kırmızıyla vurgulanır;
  • alanın üzerinde sonucun (zafer veya mağlubiyet) görüntülendiği bir bilgi satırı vardır.

mantık

Oyun alanı 3'e 3 hücre için karmaşık (evrensel) algoritmalar bulamadım, diğer tarafa gittim - kaba kuvvet! (bu konuda daha sonra). Tüm mantığın dayandığı üç ana ardışık aşama belirledim:

Aşama 1: kontrol - oyuncu kazandı mı?

Bu aşamada, aynı oyuncu sembolleriyle (çarpma veya sıfır) dolu 3 hücrenin (aynı satırda) olup olmadığını kontrol ediyoruz. Şunlar. Bu hamle ne olursa olsun (ilk hamle bile olsa), her zaman önce oyuncunun kazanıp kazanmadığını kontrol ederiz. Zafer böyle görünüyor:

Aşama 2: kontrol edin - bilgisayar bir sonraki hamlede kazanabilir mi?

Bu aşamada bir bilgisayarla dolu 2 hücre ve bir boş hücrenin olacağı bir çizgi arıyoruz - yani oyuncunun dikkatsizliğinden dolayı kazanmaya çalışıyoruz. Yenilgi şöyle görünür (yani bilgisayar zaferi):

Aşama 3: Kazanmamıza izin verme!

Burada ikinci aşamadaki ile aynı satırı arıyoruz, sadece 2 hücre oyuncunun oyun işaretleri ile doldurulmalı yani bu aşamada boş bir hücreye işaret koyarak bilgisayarın kaybetmesine izin vermiyoruz. Aşamaların her biri bağımsız bir işlevdir - bunu aşağıdaki js kodunda görebilirsiniz.

uygulama

Oyun alanının düzeni çok basittir - ana blok bir bilgi satırı (sınıf - sonuç) ve hücreler olan 9 blok (sınıf - blok) hücrelerin HTML işaretlemesini içerir:

Senin sıran!

Oyun alanında istenen hücreyi doğru bir şekilde tanımlamak için hücre yardımcı sınıfına ihtiyaç vardır. Oyun alanı için CSS stilleri:

Krestiki_noliki( genişlik: 306 piksel; kenar boşluğu: 0 otomatik; ) .krestiki_noliki .block( genişlik: 100 piksel; yükseklik: 100 piksel; kenarlık: 1 piksel katı #ccc; imleç: işaretçi; kayan nokta: sol; metin hizalama: merkez; yazı tipi boyutu: 100 piksel; satır yüksekliği: 94 piksel; )

Şimdi JS kodunun tamamına bakalım, ardından ana noktalardan bahsedeceğim:

$(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"]; //Oyuncunun zafer fonksiyonunu belirle 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; } }); });

İlk olarak, değişkenleri bildiririz: znak_user - bu değişkende kullanıcının oynayacağı işareti saklarız (varsayılan olarak orada bir sıfır saklanır - bu İngilizce kabin "O" dur). znak_comp - bu değişkende bilgisayarın oynayacağı işareti saklarız (varsayılan olarak, orada bir çarpı saklanır - bu İngilizce kabin "x" dir).

Mantık şudur: Rastgele sayı 3'ten büyükse, bilgisayar sıfırlarla oynar ve ilk hareketi o (bilgisayar) yapar.

Bu mantığı kendi zevkinize göre değiştirebilirsiniz, örneğin kimin en az birinci olacağı ve hangi karakterlerin olacağı konusunda daha fazla seçenek yapmak için bazı rasgele sayılar oluşturabilirsiniz. exit_flag - bu bayrak (değişken) işlevden çıkmaktan sorumludur, yani örneğin bilgisayar zaten hamlesini yaptığında ve işlevden çıkmanız ve hareketi oyuncuya aktarmanız gerekir. win_user_array - bu dizi, hücreleri doldurmak için tüm kazanan seçenekleri saklar. Açıklığa kavuşturmak için, şu resme bir göz atalım:

Dizinin her bir elemanı, kazanan bir kombinasyon olan üç basamaklı bir dizedir, yani, örneğin 1, 2 ve 3 sayılarının altındaki hücreleri doldurursanız, zafer (veya yenilgi) gelecektir. Gördüğünüz gibi toplamda 8 kazanan seçenek var, bizim görevimiz tüm bu seçenekleri sıralamak. Aşağıdakiler 3 işlevdir:

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

Bu işlevlerin amacı (üç adımda) Mantık bölümünde (yukarıda) açıklanmıştır. Bu işlevler, alanın herhangi bir hücresine tıklanarak çağrılır. İşlevlerin her birine (znak) parametresi iletilir - bu, oyuncunun veya bilgisayarın işaretidir (çapraz veya sıfır), örneğin, oyuncunun zaferini belirleyen işlevde (check_3_user), işaretini geçiyoruz Oyuncu aynı satırda 3 özdeş işareti bulmak için.

Üç işlevden sonra (bilgisayar henüz hareket etmemişse), bilgisayar boş hücrelerden birini doldurur. Burada, örneğin, merkezi hücre boşsa (hücre numarası 5), o zaman önce içine bahis yapın, eğer doluysa, sonra serbest köşelerden birine bahis yapın (bunlar 1, 3, 7 ve 9) numaralı hücreler ve benzeri - genel olarak, burada size kalmış.

Prensip olarak, böyle bir oyun yaratmak için gereken tek şey budur.

Artık oyunu demo olarak izleyebilir ve kaynak dosyayı (sadece 1 dosya) indirebilirsiniz.

06/08/2018 - Mektubun yazarına gösterdiğiniz ilgi için teşekkürler: Patvakan Baghdasaryan, bilgisayar birkaç olası zafer seçeneğine sahipken ve tüm kazanan hamleleri boyandığında (3 yerine 4'ten 6 hücreye) bir hata düzeltildi ).

Benim için bu kadar, umarım bu eğitim sizin için faydalı olmuştur, iyi şanslar dilerim, hoşçakalın!

Konunun devamı:
internet

Yeni bir taşıyıcı dağılımı hemen kurulmadığından, bir yarı iletken diyot, akım veya voltajdaki yeterince hızlı değişikliklere göre inerttir. Nasıl...