• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Mastermind - gra w Visual Basic

VPS Starter Arubacloud
0 głosów
422 wizyt
pytanie zadane 27 kwietnia 2017 w Visual Basic przez Honter Użytkownik (690 p.)

Witam,

Dostałem ostatnio na zadanie domowe, stworzenie prostej gry w Mastermind w Visual Basic. Myślałem, że zadanie będzie proste i bez problemu sobie z nim poradzę, ale nic bardziej mylnego, siedzę nad kodem od 2 dni i nie mam pomysłu jak ta gra powinna działać. Treść zadanie brzmi tak: "Mastermind. Wygeneruj losową liczbę 4 cyfrową. Gracz musi wpisywać 4 cyfrowe liczby dopóki nie odgadnie losowo wygenerowanej liczby. Po każdej nieudanej próbie, gra powinna wypisać ile numerów było prawidłowych, lecz nie podawać ich pozycji" Tu pojawia się pewna niejasność, gdyż wiem, że w grze Mastermind podaje się ilość liczb 'prawidłowych - na swoich miejscach' i 'prawidłowych - nie na swoich miejscach'. Dlatego zakładam, że ma to wyglądać właśnie w ten sposób. Kontynuując "Na koniec gra powinna pogratulować graczowi i powiedzieć ile prób im zajęło odgadnięcie tego numeru"

To była podstawowa część zadania, do tego są jeszcze 3 rozszerzenia.

1. Pozwolić graczowi wybrać łatwy tryb gry, w którym gra podawałaby dokładnie, która cyfra w 4 cyfrowej liczbie jest poprawna.

2. Pozwolić graczowi wybrać trudny tryb gry, który generowałby 5 cyfrową liczbę zamiast 4 cyfrowej.

3. Po zakończeniu gry zapytać o imię gracza i zapisać ich punkty w tabeli. Po uruchomieniu gry pokazywać tabelę z najlepszymi wynikami, żeby dodać do gry element rywalizacji.

Co do rozszerzeń to raczej nie widzę z nimi żadnego problemu i mam już pomysł jak je zrobić. Problem pojawił się w podstawowej części zadania. Napisałem kod z interfejsem (menu, input, output itd.) i zacząłem zastanawiać się nad mechaniką gry. Dużym ograniczeniem okazała się funkcja InStr(string, szukany_znak), gdyż wyszukuje ona pierwszą literę/liczbę w danym stringu i podaje jej pozycję. A jak wiemy losowo wygenerowana liczba może składać się np. z samych 2 (2222). W przypadku kiedy gracz wpisze "1234", algorytm sprawdzający, uzna, że 1 cyfra jest poprawna, ale nie na swoim miejscu, gdyż pierwsza 2 na jaką natrafi będzie na 1 pozycji, a nie na 2. Myślałem nad ograniczeniem algorytmu tylko do cyfr na pozycji równej lub większej niż ta sprawdzana, tzn. Jeżeli gracz wpisuje "1234", algorytm sprawdza cyfrę 2, to 'kod"/losowa liczba "2222" będzie sprawdzana tylko od drugiej 2 "X222". Tutaj też pojawił się problem gdyż działało by to jedynie w przypadku losowej liczby składającej się z tych samych cyfr.

Pod spodem zamieszczam kod, który już napisałem. Wiem, że jest on niepoprawny, ale już tak długo myślę nad tym rozwiązaniem, że trochę się już pogubiłem w tym co piszę. Dlatego liczę na czyjąś pomoc, może nie w rozwiązaniu, bo nie chcę dostać gotowej odpowiedzi na to zadanie, ale np. naprowadzeniu na pewien tok myślenia nad rozwiązaniem. Część odpowiedzialna za rozgrywkę to Sub PlayGame().

Module Module1
    Dim RandomNumber As String
    Dim RandomDigits(4) As String
    Dim numberinput As String
    Dim PlayerString As String
    Dim PlayerDigits(4) As String
    Dim RemainDigits(4) As String
    Dim Number(4) As Boolean


    Sub Main()
        Dim menuselect As Char

        Console.Clear()

        For i = 1 To 4
            Number(i) = False
        Next

        Heading()

        'Menu
        Console.WriteLine("MAIN MENU")
        Console.WriteLine("1.(N)ew Game")
        Console.WriteLine("2.(S)elect Mode")
        menuselect = Console.ReadLine()

        Do Until menuselect = "N" Or menuselect = "S"
            Console.WriteLine("It's not a correct input")
            menuselect = Console.ReadLine()
        Loop

        If menuselect = "N" Then
            PlayGame()
        Else
            ModeSelect()
        End If

        Console.ReadLine()
    End Sub

    Sub Heading()
        Console.WriteLine("************")
        Console.WriteLine(" MASTERMIND ")
        Console.WriteLine("************")
    End Sub

    Sub Generator()
        Dim rand As New Random

        For i = 1 To 4
            RandomDigits(i) = Str(rand.Next(0, 9))
            RandomNumber = RandomNumber & RandomDigits(i)
        Next

    End Sub

    Sub ModeSelect()
        Dim mode As Char

        Console.Clear()

        Heading()

        Console.WriteLine("Select the game mode:")
        Console.WriteLine("1.(E)asy mode - shows which position you have guessed correctly")
        Console.WriteLine("2.(H)ard mode - generates 5 digit number")
        Console.WriteLine()
        Console.WriteLine("(B)ack to main menu")
        mode = Console.ReadLine()

        Do Until mode = "E" Or mode = "H" Or mode = "B"
            Console.WriteLine("It's not a correct input")
            mode = Console.ReadLine()
        Loop

        If mode = "E" Then
            Play_EasyMode()
        ElseIf mode = "H" Then
            Play_HardMode()
        ElseIf mode = "B" Then
            Main()
        End If
    End Sub

    Sub PlayGame()
        Dim CorrectDigit(4) As Boolean
        Dim MissedDigit(4) As Boolean
        Dim CorrectCount As Integer
        Dim MissedCount As Integer
        Dim NoOfTries As Integer
        Dim DigitPos As Integer

        Generator()


        Do Until CorrectDigit(1) = True And CorrectDigit(2) = True And CorrectDigit(3) = True And CorrectDigit(4) = True
            NumberDigitCheck()

            For i = 1 To 4
                PlayerDigits(i) = Mid(PlayerString, i, 1)
            Next

            For z = 1 To 4
                CorrectDigit(z) = False
                MissedDigit(z) = False
            Next

            CorrectCount = 0
            MissedCount = 0

            For j = 1 To 4
                DigitPos = InStr(RandomNumber, PlayerDigits(j))
                If DigitPos <> 0 Then
                    If Mid(RandomNumber, j, 1) = PlayerDigits(j) Then
                        CorrectDigit(j) = True
                        CorrectCount += 1
                    Else
                        MissedDigit(j) = True
                        MissedCount += 1
                    End If
                End If
            Next

            Console.WriteLine("You've got " & CorrectCount & " digits correct and on their place")
            Console.WriteLine("You've got " & MissedCount & " digits correct but not on their place")

            NoOfTries += 1
        Loop



        Console.WriteLine("CONGRATULATIONS, YOU'VE GUESSED THE NUMBER")
        Console.WriteLine("It took you " & NoOfTries & " tries to guess it")

        Console.ReadLine()

        Main()

    End Sub

    Sub NumberDigitCheck()
        Console.WriteLine("Insert a number:")
        numberinput = Console.ReadLine()

        Do Until numberinput.Length = 4
            Console.WriteLine("It's not a 4 digit number")
            numberinput = Console.ReadLine()
        Loop

        PlayerString = Str(numberinput)
    End Sub

    Sub Play_EasyMode()

    End Sub

    Sub Play_HardMode()

    End Sub

End Module

Problem z tym kodem wygląda tak, że w Sub PlayGame() kod jest zdecydowanie niepoprawny i gra niepoprawnie sprawdza numery, które wpisuje gracz. Przykładem błędu może być: Gra losuje liczbę, wpisuję 1234, dostaję odpowiedź, że 1 cyfra jest poprawna na swoim miejscu i 1 jest poprawna nie na swoim miejscu, z czego wnioskuję, że 2 cyfry z zakresu 1-4 są częścią kodu. Następnie dla sprawdzenia wpisuję 0000 i otrzymuję odpowiedź "1 cyfra poprawna na swoim miejscu, 2 poprawne nie na swoim miejscu" co by oznaczało, że 3 zera są częścią kodu. 3 zera + 2 cyfry z zakresu 1-4 = 5 cyfr, więc wyświetlane komunikaty są błędne i kod nie sprawdza liczby tak jak powinien.   

Z góry dziękuję wszystkim za odpowiedzi.  

1 odpowiedź

0 głosów
odpowiedź 27 kwietnia 2017 przez niezalogowany
wybrane 28 kwietnia 2017 przez Honter
 
Najlepsza

Używaj przy poszukiwaniu błędów Console.Write() do sprawdzania wartości zmiennych w różnych miejscach w kodzie.

Nie powinieneś używać w tym przypadku funkcji Str() do przekształcania liczb:

Dim TestString As String 
' Returns " 459".
TestString = Str(459)
' Returns "-459.65".
TestString = Str(-459.65)
' Returns " 459.001".
TestString = Str(459.001)

Sprawdź najpierw czy cyfry znajdują się na poprawnych miejscach a dopiero potem czy są na miejscach niewłaściwych.

komentarz 28 kwietnia 2017 przez Honter Użytkownik (690 p.)
Właśnie czytałem o tym, że się takie rzeczy dzieją z liczbami jak się je przekształca Str(), ale nie wiedziałem za bardzo o co chodzi. Dzięki za radę ze sprawdzaniem liczb, napiszę kod i dam znać czy działa.

Podobne pytania

0 głosów
1 odpowiedź 600 wizyt
pytanie zadane 2 lutego 2017 w Visual Basic przez Szynku Nowicjusz (120 p.)
+1 głos
4 odpowiedzi 3,321 wizyt
+5 głosów
2 odpowiedzi 666 wizyt

92,453 zapytań

141,262 odpowiedzi

319,086 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...