C# Chińczyk

0

Piszę pierwszą aplikację okienkową w języku C#(Visual Studio), będzie nią chińczyk. Póki co jestem zielony i mam dwa pytania,

  1. Jak wygenerować mapę do chińczyka? Za pomocą jednego PictureBox'a czy każde pole do gry powinno mieć swojego?
  2. Baza danych powinna przechowywać współrzędne wszystkich pól gry(X,Y) oraz CzyZajętę, jeśli tak - przez którego gracza? Jeśli nie, to co?

Za każdą odpowiedź i radę z góry dziękuję.

1

Dobra skasowałem posta bo pisałem dla warcab xD. Nie pisze w WPF nie pisalem nigdy w tym nic wiekszego niz kilka inputow to podpowiem jak mi sie wydaje.

  1. Jak dla mnie kazde pole powinno mieć swój picture box i przygotujesz sobie
  • pole puste
  • pole z pionkiem 1 gracza
  • pole z pionkiem 2 gracza
  • pole z pionkiem 3 gracza
  • pole z pionkiem 4 gracza
    i będziesz podmieniać te pola odpowiednio
  1. Te x i y zmylily mnie jako, ze to sa warcaby bo w chinczyku wystarczy ci przeciez 1 wymiar i kazde pole ma swoj numerek po prostu. Dla mnie db jest przerostem troche formy nad treścią le niech będzie. Ja osobiscie w polu trzymałbym informację jaki gracz na nim jest bo dzięki temu wiesz jak taka plasze wygnerowac korzystajc z bitmap z pola 1.
0

Powoli idzie, mam kolejne pytanko, jak to rozwiązać?
Bitmap pionekA = new Bitmap(@"pionekA.png");
pole10.Image = pionekA;
Chciałbym, aby nazwy przed kropką, czyli tutaj "pole10" były przechowane pod zmienną, którą możemy modyfikować.

Chodzi mi o takie coś:
string nazwa = "pole10";
nazwa.Image = pionekA;

1

Użyj tablic.

Mniej więcej tak (zależy jakie masz konkretnie typy):

Pionki[] pionki = new Pionki[10];
pionki[0] = new Pionek();
pionki[0].Image = new Bitmap();
// i tak dalej
0

Dzięki za pomoc, pionki się ruszają, jest bicie, zostało dodać bazę danych i check wygranej.

1

@Turoczek: a po co Ci baza?

0

Chciałbym przenieść z Windows Form App, tak, aby była to gra online. Baza danych do rankingu graczy i aby było można odtworzyć przebieg gry. Co mi jest potrzebne? ASP.NET Core?

0

Ma sens. Bo jakbys robil lokalnie to spokojnie wystarczy serializacja/deserializacja. To chyba najlatwiejszy sposob na zrobienie save'a (przynajmniej w Javie).

1

Chciałbym, aby można było grać w niego online, sposób łączenia dowolny, w sensie - czy to exe, który jakoś połączy się z online czy będzie to strona internetowa. Rodzi to następne pytania, mam napisanego chińczyka w Windows Form App(póki co bez żadnej bazy danych), co dalej? Kombinować tutaj w jakieś łączenia czy przenieść to np do ASP NET Core, czy co? Tutaj już musicie pomóc, bo nie mam kompletnie zielonego pojęcia jak to zrobić. Nakierujcie mnie proszę. Może jakieś darmowe poradniki? Płatny kurs też mogę kupić, może macie coś co może pomóc?

Pomoże ktoś? :D

1

Można to różnie zrobić, generalnie porytwasz się trochę z motyką na słońce. Ponieważ można tego chinczyka i jako ASP .NET Core zarelizowac jak i na jakiś socketach jako twoja apka w windos formach. Aczkolwiek w obu przypadkach będziesz zmagać się z synchronizacją i innymi problemami dotyczącymi rozgrywki w multiplayerze

0

Jak chcesz robić multiplayer gre w winformsach, zawsze możesz postawić serwer z biblioteka signalR jako self hosted, ułatwi Ci to sprawę.

0

Cześć i czołem wszystkim! Skoro piszę to znaczy, że mam problem.
Oto mój kod: https://pastebin.com/y6tWzM8v
Sprawa wygląda następująco: było dwóch graczy - A i C, gdy mieli po jednym pionku i chodzili po mapie to się zbijali, a jak wypadła "6" na kostce to wychodzili ponownie z bazy. Problem pojawił się przy tym, gdy mieli więcej niż po jednym pionku.
Np gracz A wyrzuca 6 i ma do wyboru dwa pionki, którymi może wyjść - pionek A oraz A1. Próbuje robić to funkcją np:

       private void wyjscieA1_Click(object sender, EventArgs e)
        {
            if (KtoryGracz == false && CzyWyrzucona6() && zmienne[24].newImage == pionekA)
            {
                zmienne[24].newImage = puste;
                zmienne[pionA1].newImage = pionekA; //wychodzi pierwszy pionek
                KtoryGracz = true; //kolej przeciwnika
            }
        }

Jak mam zrobić bicie/wybieranie/chodzenie dla więcej niż jednego pionka? Mógłby ktoś podsunąć jakiś pomysł? Z góry dziękuję!

3

Ale brudny kod aż mi się moje początki przypominają :D. Co do zasad gry to powinieneś dać graczowi wybór jak wyrzucił 6 czy wystawia pionek czy przesuwa się o 6 pół i rzuca ponownie. Niestety masz to napisane bez klas i dobrego podejścia. Moja rada jest taka, żebyś o tej warstwie internetowej myślał kiedy indziej. Co do gry potrzebujesz umożliwiać wybór, którym pionkiem się przesunąć. Ale jak dal mnie to poczytaj o klasach i napisz ten kod na klasach bo już tutaj kod się robi nie czytelny i zaczyna babranie się w tonie ifów. Zauważ, że kod

 if (KtoryGracz == false) // ruch gracza czerwonego

jest zdublowany jak będziesz domyślnie implementował grę dal 4 osób to będziesz 4x te ify kopiował? Fajnie, że masz funkcje ale to nadal robi się z tego kupa, nie traktuj tego jako obrazę bo sam na forum każdy z nas przez ten czas przychodził ale porywasz się trochę z motyką na słońce.

ok ale wracając do tematu, po rzucie kostką powinieneś dać wybór przesuń (wybrany pionek) lub wystaw z bazy nowy pionek.

0

Wiem jak działają klasy i mniej więcej jak się ich używa, a mógłbyś podsunąć jakiś pomysł? W sensie co miałbym mieć za klasy?
Class Pionek, która przechowuje: do którego gracza należy, położenie, pictureboxa z kolorem.
Class Pole, która przechowuje: domyślnego pictureboxa, bool CzyKtośTuStoi?

1

Dobra to zacznijmy od wejść jakie mogą wpłynąć na stan twojej planszy. Zrobiłeś prosty przycisk rzut kostką i wszystko automatycznie obsługujesz. Dlatego tu masz problem, że nie możesz obsłużyć większej ilości pionków. Generalnie dla mnie flow gry powinno wyglądać tak
Gracz rzuca kością -> jeśli nie posiada wystawionych pionków to wystawia pionek ( jak wyrzuci 6 ;) ) -> jeśli posiada pionki to przez kliknięcie na niego wybiera, że to on przemieszcza się, tak samo może wyrzucając 6 kliknąć na bazę by wystawić pionek, możesz tu też obsłużyć ponowny rzut kostką jeśli miał 6 i nie wystawił pionka tylko się przesunął. Czyli innymi słowy musisz ogarnąć więcej inputów, które mają mieć wpływ na grę :).

Ok co do klas to trzeba wszystko dobrze przeanalizować. Na pierwszy rzut oka wytworzył bym przynajmniej 4 klasy:
Plansza odpowiadająca za wyświetlanie takie view model, Gra która obsługuje zasady gry :), Pionek posiadający to co powiedziałeś + ja bym dodał jego położenie obecne na planszy. Gracz, który będzie maił listę pionków jakieś może imię, ale genralnie jest potrzebny by w grze moc oddać sterownie poszczególnym graczom

0

Póki co robię na ifach(druga wersja będzie elegancko na klasach - nie od razu Rzym zbudowano hehe), mam takie dwie funkcje:
https://pastebin.com/cpNXuGMb
https://pastebin.com/SKf4Au1E
Różnią się one nazwą i wartościami w linijkach nr 3,5,6, 55,57,58. W pierwszej funkcji jest wartość 1, w drugiej wartość 2 itd.. jak to połączyć w jedną funkcję? :D

2

Poczytaj o programowaniu obiektowym i ogólnie bo na razie to lecisz okropnie strukturalnie i to w najgorszym tego możliwym wykonaniu. Tworzysz drzewo ifów sam się prosisz o g**no kod. Do obsługi dwóch pionków potrzebujesz PONAD 10 IFÓW stary w chinczyku jest w sumie 16 pionków ty serio chcesz mieć jakieś 80 ifów na samą obsługę pionków i w takim drzewie pracować. Niby znasz klasy i funkcje ale ich wgl nie używasz duplikujesz kod nie widzisz, że powtarzasz 4 razy kod robiący to samo? Anyway jesli nie widzisz, że sam sobie robisz krzywdę napisz obsługę 4 pionków nawet dla tych dwóch graczy.

Wracaj do książek przeczytaj coś o dobrym kodzie, wzorcach a nie piszesz aplikacje która opiera się na samych ifach. Może słyszałeś kiedyś o jak w TV mówią o grach, że twórcy implementowali zachowanie obiektów i one same oddziaływały między sobą u ciebie nie ma impementacji zachowania jest po prostu ifologai. Wiesz czym się to różni od twojego kodu? Tym, że dodanie trzeciego pionka dla każdego gracza będzie u ciebie mordegą bo będzeisz musiał go wpiąć do tej ifologi. Wyobraź sobie, że musisz ta ilość ifów stworzyć dla 16 pionków nie dla 4 i co twój kod będzie miał 500 lini? Czegoś co można było napisać w 20? Jako programista masz starać się opisywać zachowania a nie tworzyć maszynę stanów logicznych. W twoim kodzie jest 26 ifów a problem rozwiązuje pewno koło 4 jak nie mniej.

Lektura obowiązkowa:

  • programowanie obiektowe
  • klasy i obiekty
  • polimorfizm
  • przeciążanie funkcji
  • SOLID i DRY <- to obowiązkowo to są podstawoe zasady dobrego programowania, które łamiesz strasznie w tym kodzie

@Edit:
Przykład prosty -> implementujesz przesuwanie pionka. I teraz masz zachowanie, które może użyć każdy pionek i nie interesuje mnie czy w grze jest 15 pionków czy dwa na każdym mogę wywołać tą jedną funkcję napisaną. W twoim kodzie pisałbyś osobno funkcję/kod dla każdego pionka by go przesunąć.

0
 class Pionek
    {
        public int pozycja;
        public Image Image;

        public Pionek(int pozycja, Image image)
        {
            this.pozycja = pozycja;
            Image = image;
        }

    }
 class Pole
    {
        public Image Image = Image.FromFile(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\pole.png");

        public Pole()
        {
            Image = Image;
        }
    }
 class Gracz
    {
        public string nick;
        List<Pionek> listaPionkow = new List<Pionek>();

        public Gracz(string nick, List<Pionek> listaPionkow)
        {
            this.nick = nick;
            this.listaPionkow = listaPionkow;
        }
    }
namespace ChinczykObiektowo
{
    public partial class Form1 : Form
    {
        Bitmap puste = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\pole.png");
        Bitmap pionekA = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczA.png");
        Bitmap pionekC = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczC.png");

        Pole[] zPole = new Pole[6];
        Pionek[] zPionek = new Pionek[4];
        Gracz[] zGracz = new Gracz[2];


        public Form1()
        {
            InitializeComponent();
            StworzGre();
            WczytajMape();
        }

        public void StworzGre()
        {
            for (int i = 1; i < 6; i++) // stworzenie mapy
            {
                zPole[i] = new Pole();
            }
            
        }

        public void WczytajMape()
        {
            pictureBox1.Image = zPole[1].Image;
            pictureBox2.Image = zPole[2].Image;
            pictureBox3.Image = zPole[3].Image;
            pictureBox4.Image = zPole[4].Image;
            pictureBox5.Image = zPole[5].Image;
        }

        public void Graj()
        {
            
        }


    }
}

Coś takiego?

0

Tak, ale dodaj sobie do klasy pionek pole kotre przechowuje pozycej startowa pionka tak bys mogl go latwo wrocic na to miejsce. Teraz np sproboj napisac funkcje w klasie pionek odpowiedzialna za przemieszczanie. Dodaj sobie jeszcze jakas klase nadrzedna nad gra ktora bedzie obslugiwac zasady: wybieranie pionka, przesuwanie sie, zbijanie etc.

0

Czas wrócić do chińczyka, siedzę nad tym od wczoraj i nie wiem co dalej... jak to dalej dziabać.

namespace ChinczykObiektowo
{
   public partial class Form1 : Form
   {
       Bitmap puste = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\pole.png");
       Bitmap pionekA = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczA.png");
       Bitmap pionekC = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczC.png");

       Pole[] zPole = new Pole[27];
       Pionek[] PionkiCzerwonego = new Pionek[2];
       Pionek[] PionkiNiebieskiego = new Pionek[2];

       public Form1()
       {
           InitializeComponent();
           StworzGre();
           WczytajMape();
       }

       public void StworzGre()
       {
           Gracz Czerwony = new Gracz("Adam", PionkiCzerwonego);
           Gracz Niebieski = new Gracz("Daniel", PionkiNiebieskiego);
          
           for (int i = 1; i < 27; i++) // stworzenie mapy do chodzenia
           {
               zPole[i] = new Pole(puste);
           }
           PionkiCzerwonego[0] = new Pionek(23, pionekA);
           PionkiCzerwonego[1] = new Pionek(24, pionekA);

           PionkiNiebieskiego[0] = new Pionek(25, pionekC);
           PionkiNiebieskiego[1] = new Pionek(26, pionekC);

           zPole[23].Image = pionekA;
           zPole[24].Image = pionekA;

           zPole[25].Image = pionekC;
           zPole[26].Image = pionekC;

       }

       public void WczytajMape()
       {
           pictureBox1.Image = zPole[1].Image;
           pictureBox2.Image = zPole[2].Image;
           pictureBox3.Image = zPole[3].Image;
           pictureBox4.Image = zPole[4].Image;
           pictureBox5.Image = zPole[5].Image;
           pictureBox6.Image = zPole[6].Image;
           pictureBox7.Image = zPole[7].Image;
           pictureBox8.Image = zPole[8].Image;
           pictureBox9.Image = zPole[9].Image;
           pictureBox10.Image = zPole[10].Image;
           pictureBox11.Image = zPole[11].Image;
           pictureBox12.Image = zPole[12].Image;
           pictureBox13.Image = zPole[13].Image;
           pictureBox14.Image = zPole[14].Image;
           pictureBox15.Image = zPole[15].Image;
           pictureBox16.Image = zPole[16].Image;
           pictureBox17.Image = zPole[17].Image;
           pictureBox18.Image = zPole[18].Image;
           pictureBox19.Image = zPole[19].Image;
           pictureBox20.Image = zPole[20].Image;
           pictureBox21.Image = zPole[21].Image;
           pictureBox22.Image = zPole[22].Image;

           wyjscieA.Image = zPole[23].Image;
           wyjscieA1.Image = zPole[24].Image;

           wyjscieC.Image = zPole[25].Image;
           wyjscieC1.Image = zPole[26].Image;
       }


   }
}
namespace ChinczykObiektowo
{
    class Gracz
    {
        public string nick;
        public Pionek[] Pionki;

        public Gracz(string nick, Pionek[] pionki)
        {
            this.nick = nick;
            Pionki = pionki;
        }
    }
}
namespace ChinczykObiektowo
{
    class Pionek : Rules
    {
        public int pozycja;
        public Image Image;

        public Pionek(int pozycja, Image image)
        {
            this.pozycja = pozycja;
            Image = image;
        }

        public void RuszSie()
        {

        }

    }
}
namespace ChinczykObiektowo
{
    class Pole
    {
        public Image Image;

        public Pole(Image image)
        {
            Image = image;
        }
    }
}
namespace ChinczykObiektowo
{
    class Rules
    {
        public bool Czy6()
        {
            if (Rzuc() == 6) return true;
            else return false;
        }

        public int Rzuc()
        {
            Random rnd = new Random();
            int wylosowana = rnd.Next(1,6);
            return wylosowana;
        }

        public bool CzyMozliweWyjscie()
        {
            if (Czy6())
            {
                return true;
            }
            else return false;
        }
    }
}
0

Mam takie pytanko, chciałbym stworzyć funkcję, która będzie odpowiedzialna za podmienianie klikniętego pictureboxa. Mam 22 pictureboxy, każdy miał swoją funkcję, a jak zrobić jedną uniwersalną? Jak odnieść się do danego pictureboxa?

2

Nie wiem co chcesz zrobić no ale masz pobierasz wszystkie picutreboxy z formy i przypisujesz im event

         var pictureBoxes = Controls.OfType<PictureBox>().ToList();
            foreach (var pictureBox in pictureBoxes)
            {
                pictureBox.Click += PictureBox_Click;
            }
0

Z góry dzięki za swój czas. Dobra, od początku. Mam jak widzisz klasy: pole, pionek, gracz, zasady gry, Form1.

class Pole
    {
        public Image Image;

        public Pole(Image image)
        {
            Image = image;
        }
    }
class Pionek : Rules
    {
        public int pozycja;
        public Image Image;

        public Pionek(int pozycja, Image image)
        {
            this.pozycja = pozycja;
            Image = image;
        }

        public void RuszSie()
        {
            pozycja += Rzuc();
        }
    }
class Gracz
    {
        public string nick;
        public Pionek[] Pionki;

        public Gracz(string nick, Pionek[] pionki)
        {
            this.nick = nick;
            Pionki = pionki;
        }
    }
    class Rules
    {
        public bool Czy6()
        {
            if (Rzuc() == 6) return true;
            else return false;
        }

        public int Rzuc()
        {
            Random rnd = new Random();
            int wylosowana = rnd.Next(1,6);
            return wylosowana;
        }

        public bool CzyMozliweWyjscie()
        {
            if (Czy6()) // dodać warunek czy na pozycjach startowych znajdują się pionki
            {
                return true;
            }
            else return false;
        }
    }
public partial class Form1 : Form
    {
        Bitmap puste = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\pole.png");
        Bitmap pionekA = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczA.png");
        Bitmap pionekC = new Bitmap(@"C:\Users\studi\source\repos\Chinczyk\Chinczyk\Resources\graczC.png");
        
        Pole[] zPole = new Pole[27];
        Pionek[] PionkiCzerwonego = new Pionek[2];
        Pionek[] PionkiNiebieskiego = new Pionek[2];

        public Form1()
        {
            InitializeComponent();
            StworzGre();
            Mapa();
        }

        public void StworzGre()
        {
            Gracz Czerwony = new Gracz("Adam", PionkiCzerwonego);
            Gracz Niebieski = new Gracz("Daniel", PionkiNiebieskiego);
           
            for (int i = 1; i < 27; i++) //
            {
                zPole[i] = new Pole(puste);
            }
            PionkiCzerwonego[0] = new Pionek(23, pionekA);
            PionkiCzerwonego[1] = new Pionek(24, pionekA);

            PionkiNiebieskiego[0] = new Pionek(25, pionekC);
            PionkiNiebieskiego[1] = new Pionek(26, pionekC);

            zPole[23].Image = pionekA;
            zPole[24].Image = pionekA;

            zPole[25].Image = pionekC;
            zPole[26].Image = pionekC;

            NickRed.Text = "Pionki gracza: "+ Czerwony.nick;
            NickBlue.Text = "Pionki gracza: "+ Niebieski.nick;
        }

        public void Mapa()
        {
            var pictureBoxes = Controls.OfType<PictureBox>().ToList();
            foreach (var pictureBox in pictureBoxes)
            {
                pictureBox.Image = puste;
            }     
        }
    }

Moja koncepcja była taka - klikam w dowolnego pictureboxa, funkcja sprawdza mi:
Czy znajduje się tu pionek?(Sprawdza czy dany picturebox.Image != puste) Jeśli tak - którego gracza stoi? Czerwonego - wywoła się funkcja rusz, która do obecnej pozycji doda wyrzuconą cyfrę 1-6.
Jest jakaś inna lepsza koncepcja czy moja jest dobra? Jeśli moja dobra to dążę do tego, że nie wiem jak w funkcji CzyZnajdujeSieTuPionek przekazać jakieś ID które zidentyfikuje mi danego pictureboxa.

0

Ja na twoim miejscu zrobił bym sobie nową kontrolkę np Pionek i tam wstawił wszystko co mi potrzeba jakieś image guid (dla konkretnego pionka) od tego bym wyszedł.

0

Dobra, powolutku idzie do przodu, natknąłem się na kolejny błąd System.NullReferenceException: „Odwołanie do obiektu nie zostało ustawione na wystąpienie obiektu.”

        public void SprawdzClick(object sender, MouseEventArgs e)
        {
            Pionek Clicked = sender as Pionek;
            if (Clicked.Image == pionekA)
            {
                if(Clicked.CzyMozliweWyjscie(Clicked.pozycja, Clicked.start)) // wyjscie
                {
                    Clicked.RuszSie();
                }
            }
        }
0

Gdzieś odwołujesz się do nulla, w którym miejscu wywala Ci ten błąd?

0

Następne pytanko, mam:
if (PionkiCzerwonego[0].pozycja == index)
{...}
if (PionkiNiebieskiego[0].pozycja == index)
{...}

Różnią się one nazwą(tylko Czerwonego/Niebieskiego), a reszta jest funkcji taka sama, jak zadeklarować zmienną która będzie to odpowiednio wywoływać?

0

Skoro to funkcja to przyjmij parametr i w nim podawaj to lub to

0

Klasa: https://pastebin.com/RXQj57SD
"Main": https://pastebin.com/Nc6yFXZZ
Rzuci ktoś okiem na ten kod? Jakieś rady? Chyba na kilka dni pisania w C# jest w miarę ok? Zostało mi dodać checkwygranej i aby nie mogły na siebie wchodzić.

0

Pytałeś wcześniej o pobieranie pictureboxow a przypisujesz ręcznie wartości czas najwyższy poznać petlę. Nazwy po ang. Nie trzymaj ścieżek w kodzie najlepiej dodaj je do resources. Nie używaj nazw typu 'x' bo uja mówi. Najlepiej skasuj całość i napisz jeszcze raz

1 użytkowników online, w tym zalogowanych: 0, gości: 1