Igra križci in krožci

Igra križci in krožci

Avtor: Matic Pogladič

Besedilo naloge

Programiranje enostavnih igric (izdelava kompletne aplikacije za preprosto potezno igro - med dvema igralcema - + če je en (ali oba) od igralcev lahko računalnik)

Križci in krožci - obvezno je lahko igralec računalnik (ne nujno zelo pameten ;-)

Ideja rešitve

V visual studiu bom izbral Windows form application. V kodi Form.cs bom sporgramiral, da se bo na začetku odprlo okno, kjer bo uporabnik izbral ali igra sam ali proti računalniku. To se bo shranilo v spremenljivko "dvaIgralca" tipa bool. Če se bo igralo proti računalniku, potem se bo naključno izbralo kdo začne. Nato se bo inicializirala tabela ničel, ki je namenjena potezam igralcev in računalnika. Torej se polni z 1 ali 2. Lahko bi bila tudi bool tabela. Na paleto se nariše 9 polj, ki so potrebna za igro. Če igralec igra proti račinalniku, le ta začne vedno isto(tabela[0][0] = 2). Ob vsaki potezi se ustrezno izriše tudi celotna tabela. Na vsaki potezi uporabnika, se izriše ustrezen lik na ustreznem mestu in se preveri, če je že kdo zmagal. Če je, se pojavi okno, ki to pove. Preveri tudi, če je igre že konec in ni zmagovalca.

Razlaga kode v C#

Razlaga: Z sporočilnim oknom se izbira ali se igra proti računalniku ali pa dva igralca. To se shrani v "bool dvaIgralca."

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace krizciInKrozci
{
    public partial class Form1 : Form
    {
        //ali igrata dva igralca ali proti računalniku
        private bool dvaIgralca;

        public Form1()
        {
            InitializeComponent();

            //okno, kjer uporabnik izbere ali igra proti računalniku
            var result = MessageBox.Show("Želite igrati proti računalniku?", "Začetek igre", MessageBoxButtons.YesNo);

            switch (result)
            {
                case DialogResult.Yes:   //če pritisne da
                    dvaIgralca = false;
                    break;
                case DialogResult.No:    //Če pritisne ne
                    dvaIgralca = true;
                    break;
                default:                 // Za vsak slučaj
                    MessageBox.Show("Nekaj pritisni!");
                    break;
            }



        }

Razlaga: Inicializiranje nekaterih potrebnih spremenljivk. Med njimi tudi naključno true/false, ki določa kdo začne. Inicializira se tudi tabela(matrika) ničel, ki je namenjena shranjevanju potez.

       private bool konec = false;

        //naključnost, kdo začne
        private bool racunalnik = new Random().Next() % 2 == 0 ? true : false;

        private int poteza = 0;

        //matrika, kjer se shranjujejo poteze. 0 je nepokrito polje, 1 je igralec, 2 je računalnik
        private int[][] tabela = new int[][]
            {
                new int[] {0,0,0},
                new int[] {0,0,0},
                new int[] {0,0,0},

            };

Razlaga: Na ustvarjeno paleto se izriše 9 polj(razdelilne črte), ki se ob spreminjanju velikosti okna prilagajajo. Če je prvi na vrsti računalnik, vedno začne v istem polju. Vsakič, se izriše celotna tabela v obliki križcev in krožcev(DrawEllipse in DrawLine) z zankami po matriki.

  private void paleta_Paint(object sender, PaintEventArgs e)
        {
            //grafika
            Graphics g = this.paleta.CreateGraphics();
            Random gen = new Random();


            //risanje ločevalnih črt
            for (int i = 1; i < 3; i++)
            {
                g.DrawLine(new Pen(Brushes.Black), new Point(i * paleta.Width / 3, 0), new Point(i * paleta.Width / 3, paleta.Height));
            }

            for (int i = 1; i < 3; i++)
            {
                g.DrawLine(new Pen(Brushes.Black), new Point(0, i * paleta.Height / 3), new Point(paleta.Width, i * paleta.Height / 3));
            }

            //če igra računalnik in je prvi na potezi, vedno izbere isto potezo
            if (racunalnik && poteza == 0 && !dvaIgralca)
            {
                tabela[0][0] = 2;
                racunalnik = false;
                poteza++;
            }

            //risanje križcev in krožcev iz tabele
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (tabela[i][j] == 1)
                    {
                        g.DrawEllipse(new Pen(Brushes.Black), i * (paleta.Width / 3) + i, j * (paleta.Height / 3) + j, paleta.Width / 3 - 1, paleta.Height / 3 - 1);
                    }

                    if (tabela[i][j] == 2)
                    {
                        g.DrawLine(new Pen(Brushes.Black), new Point(i * paleta.Width / 3, j * paleta.Height / 3), new Point((i + 1) * paleta.Width / 3, (j + 1) * paleta.Height / 3));

                        g.DrawLine(new Pen(Brushes.Black), new Point((i + 1) * paleta.Width / 3, (j) * paleta.Height / 3), new Point((i) * paleta.Width / 3, (j + 1) * paleta.Height / 3));
                    }
                }
            }

        }

        private void paleta_Resize(object sender, EventArgs e)
        {
            paleta.Invalidate();
        }

Razlaga: Ko uporabnik klikne na panel, program preveri, koliko igralcev igra in na podlagi tega izriše bodisi avtomatsko računalnikovo potezo in jo shrani v tabelo bodisi čaka na drugega igralca. Če igrata dva igralca, se ob vsakem kliku izmenjujoče polni tabela z 1 ali 2 in se le ta izrisuje. Ob vsakem kliku se tudi preveri, če je kdo zmagal oziroma, če so vsa polja polna.V teh primerih se pojavi ustrezno okno.

     //ko uporabnik klikne na panel
        private void paleta_MouseClick(object sender, MouseEventArgs e)
        {

            Random gen = new Random();

            //če se igra proti računalniku
            if (!dvaIgralca)
            {
                //poteza uporabnika
                if (!racunalnik)
                {
                    //če klikne na prazno polje, zapolne tabelo na ustreznem mestu z 1
                    if (tabela[(int)(e.Location.X / (paleta.Width / 3))][(int)(e.Location.Y / (paleta.Height / 3))] == 0)
                    {
                        tabela[(int)(e.Location.X / (paleta.Width / 3))][(int)(e.Location.Y / (paleta.Height / 3))] = 1;

                        racunalnik = true;
                    }


                    paleta.Invalidate();


                }

                //preverjanje ali so vsa polja zapolnjena
                int vsota = 0;
                for (int i = 0; i < tabela.Length; i++)
                {
                    foreach (var item in tabela[i])
                    {
                        if (item == 0)
                        {
                            vsota++;
                        }
                    }
                }

                //če so vsa polja zapolnjena, je neodločeno in se pojavi okno
                if (vsota == 0)
                {
                    //okno
                    var result = MessageBox.Show("Nihče ni zmagal!\nŽeliš igrati ponovno?", "Konec igre", MessageBoxButtons.YesNo);

                    switch (result)
                    {
                        case DialogResult.Yes:   // Če pritisne Yes, se aplikacija ponovno zažene
                            Application.Restart();
                            break;
                        case DialogResult.No:    // izhod
                            Application.Exit();
                            break;
                        default:                 // Za vsak slučaj
                            MessageBox.Show("Nekaj pritisni!");
                            break;
                    }
                    konec = true;

                }

                //računalnikova poteza
                if (racunalnik && vsota > 0)
                {


                    //naključna poteza računalnika
                    while (true)
                    {
                        int prva = gen.Next(3);
                        int druga = gen.Next(3);

                        if (tabela[prva][druga] == 0)
                        {
                            tabela[prva][druga] = 2;
                            break;
                        }
                    }



                    racunalnik = false;


                }

            }
            //če igrata dva igralca
            else
            {
                if (tabela[(int)(e.Location.X / (paleta.Width / 3))][(int)(e.Location.Y / (paleta.Height / 3))] == 0 )
                {
                    //na ustrezno mesto v tabeli se doda ustrezno število, če je tam 0
                    if (poteza%2 == 0)
                    {
                        tabela[(int)(e.Location.X / (paleta.Width / 3))][(int)(e.Location.Y / (paleta.Height / 3))] = 1;
                    }
                    else
                    {
                        tabela[(int)(e.Location.X / (paleta.Width / 3))][(int)(e.Location.Y / (paleta.Height / 3))] = 2;
                    }

                    //poteza se poveča
                    poteza++;
                }





                paleta.Invalidate();


            }


            //preverjanje zmagovalca po stolpcih
            for (int i = 0; i < 3; i++)
            {
                if (tabela[i][0] == tabela[i][1] && tabela[i][0] == tabela[i][2] && tabela[i][0] != 0 && konec == false)
                {

                    //tekst za sporočilno okno
                    string text = "";

                    if (tabela[i][0] == 1)
                    {
                        text += "Zmagal si!\nŽeliš igrati ponovno?";
                    }
                    else
                    {
                        text += "Računalnik je zmagal!\nŽeliš igrati ponovno?";
                    }

                    //sporočilno okno
                    var result = MessageBox.Show(text, "Konec igre", MessageBoxButtons.YesNo);

                    switch (result)
                    {
                        case DialogResult.Yes:   // Pritisk Yes ponovno zažene
                            Application.Restart();
                            break;
                        case DialogResult.No:    // Pritisk No zapre aplikacijo
                            Application.Exit();
                            break;
                        default:                 // Za vsak slučaj
                            MessageBox.Show("Nekaj pritisni!");
                            break;
                    }
                    konec = true;

                }
            }

            //preverjanje zmagovalca po vrsticah
            for (int i = 0; i < 3; i++)
            {
                if (tabela[0][i] == tabela[1][i] && tabela[0][i] == tabela[2][i] && tabela[0][i] != 0 && konec == false)
                {

                    //tekst za sporočilno okno
                    string text = "";

                    if (tabela[i][0] == 1)
                    {
                        text += "Zmagal si!\nŽeliš igrati ponovno?";
                    }
                    else
                    {
                        text += "Računalnik je zmagal!\nŽeliš igrati ponovno?";
                    }

                    //sporočilno okno
                    var result = MessageBox.Show(text, "Konec igre", MessageBoxButtons.YesNo);

                    switch (result)
                    {
                        case DialogResult.Yes:   // Pritisk Yes ponovno zažene
                            Application.Restart();
                            break;
                        case DialogResult.No:    // Pritisk No zapre aplikacijo
                            Application.Exit();
                            break;
                        default:                 // Za vsak slučaj
                            MessageBox.Show("Nekaj pritisni!");
                            break;
                    }
                    konec = true;
                }
            }

            //če je zmagovalec na prvi diagonali
            if (tabela[0][0] == tabela[1][1] && tabela[0][0] == tabela[2][2] && tabela[0][0] != 0 && konec == false)
            {
                //tekst za sporočilno okno
                string text = "";

                if (tabela[0][0] == 1)
                {
                    text += "Zmagal si!\nŽeliš igrati ponovno?";
                }
                else
                {
                    text += "Računalnik je zmagal!\nŽeliš igrati ponovno?";
                }
                //sporočilno okno
                var result = MessageBox.Show(text, "Konec igre", MessageBoxButtons.YesNo);

                switch (result)
                {
                    case DialogResult.Yes:   // Pritisk Yes ponovno zažene
                        Application.Restart();
                        break;
                    case DialogResult.No:    // Pritisk No zapre aplikacijo
                        Application.Exit();
                        break;
                    default:                 // Za vsak slučaj
                        MessageBox.Show("Nekaj pritisni!");
                        break;
                }
                konec = true;
            }

            //če je zmagovalec na diagonali
            if (tabela[0][2] == tabela[1][1] && tabela[0][2] == tabela[2][0] && tabela[0][2] != 0 && konec == false)
            {
                //tekst za sporočilno okno
                string text = "";

                if (tabela[0][2] == 1)
                {
                    text += "Zmagal si!\nŽeliš igrati ponovno?";
                }
                else
                {
                    text += "Računalnik je zmagal!\nŽeliš igrati ponovno?";
                }

                //sporočilno okno
                var result = MessageBox.Show(text, "Konec igre", MessageBoxButtons.YesNo);

                switch (result)
                {
                    case DialogResult.Yes:   // Pritisk Yes ponovno zažene
                        Application.Restart();
                        break;
                    case DialogResult.No:    // Pritisk No zapre aplikacijo
                        Application.Exit();
                        break;
                    default:                 // Za vsak slučaj
                        MessageBox.Show("Nekaj pritisni!");
                        break;
                }

                konec = true;
            }

            //če je zadnja poteza igre med dvema uporabnikoma, se pojavi sporočilno okno
            if (poteza == 9 && dvaIgralca)
            {
                var result = MessageBox.Show("Izenačeno!\nNova igra?", "Konec igre", MessageBoxButtons.YesNo);

                switch (result)
                {
                    case DialogResult.Yes:   // Pritisk Yes ponovno zažene
                        Application.Restart();
                        break;
                    case DialogResult.No:    // Pritisk No zapre aplikacijo
                        Application.Exit();
                        break;
                    default:                 // Za vsak slučaj
                        MessageBox.Show("Nekaj pritisni!");
                        break;
                }
            }



        }

Razlaga: Zavihki za izhod in ponovni zagon v windows oknu aplikacije.

        //zavihek za izhod
        private void izhod_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        //zavihek za ponovni zagon aplikacije
        private void restart_Click(object sender, EventArgs e)
        {
            Application.Restart();
        }
    }
}

Testni primeri

0%
0%