Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kółko i krzyżyk

Ostatnio zmodyfikowano 2017-09-22 21:23
Autor Wiadomość
Lich555
Temat założony przez niniejszego użytkownika
Kółko i krzyżyk
» 2017-09-17 20:44:05
Witam.
Wiem, że proszę o dużo. Nie jest to sprawdzenie kilku linijek. Będę bardzo wdzięczny jak komuś się będzie chciało sprawdzić ten kod :)
Program mi się uruchamia, ale po pytaniu gdzie chcę wstawić kółko/krzyżyk nie widzę kółka/krzyżyku. Dalej są tam numerki planszy.
main.cpp:
C/C++
#include <iostream>
#include <conio.h>
#include "game.h"
extern GAMESTATE g_StanGry;

using namespace std;

int main()
{
    StartGry();
   
    for(;; )
    {
        RysujPlansze();
       
        if( g_StanGry == GS_MOVE )
        {
            unsigned uNumerPola;
            cin >> uNumerPola;
            Ruch( uNumerPola );
        }
        else if( g_StanGry == GS_WON || g_StanGry == GS_DRAW )
             break;
       
    }
    getch(); //gra wylaczy sie dopiero po wcisnieciu jakiegos klawisza
   
    return 0;
}

game.h:
C/C++
#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

enum SIGN { SGN_CIRCLE = 'O', SGN_CROSS = 'X' };
enum FIELD { FLD_EMPTY, FLD_CIRCLE = SGN_CIRCLE, FLD_CROSS = SGN_CROSS };
enum GAMESTATE { GS_NOTSTARTED, GS_MOVE, GS_WON, GS_DRAW };

// rozpoczecie gry

bool StartGry();

// wykonanie ruchu
bool Ruch( unsigned ); //argument to nr pola na ktorym ma byc postawiony kolko/krzyzyk

// rysowanie planszy
bool RysujPlansze();

#endif // GAME_H_INCLUDED

game.cpp
C/C++
#include "game.h"
#include <iostream>
#include <ctime>
#include <cstdlib>

using namespace std;

FIELD g_aPlansza[ 3 ][ 3 ] = { { FLD_EMPTY, FLD_EMPTY, FLD_EMPTY },
    { FLD_EMPTY, FLD_EMPTY, FLD_EMPTY },
    { FLD_EMPTY, FLD_EMPTY, FLD_EMPTY } };
GAMESTATE g_StanGry = GS_NOTSTARTED;
SIGN g_AktualnyGracz;

bool StartGry()
{
    if( g_StanGry != GS_NOTSTARTED ) return false; //spr. czy funkcja wywolana jest w dobrym momencie (tj. przed rozpoczeciem rozgrywki)
   
    //losujemy gracza, ktory bedzie zaczynal
    srand( static_cast < unsigned >( time( NULL ) ) ); //unsigned = unsigned int; static_cast <new_type> (expression) to nowy typ konwersji
    g_AktualnyGracz =( rand() % 2 == 0 ? SGN_CIRCLE
        : SGN_CROSS );
   
    // ustawiamy stan gry na ruch graczy
    g_StanGry = GS_MOVE;
   
    return true;
}

bool Ruch( unsigned uNumerPola ) //Cel: umiescic w danym polu znak aktualnego gracza (kolko/krzyzyk) oraz spr. stan gry pod katem ew. wygranej lub remisu
{
    if( g_StanGry != GS_MOVE ) return false; //spr. czy funkcja wywolana jest w dobrym momencie (tj. w trakcie rozgrywki)
   
    if( !( uNumerPola >= 1 && uNumerPola <= 9 ) ) return false; //spr. czy wprowadzony nr pola jest w przedziale <1, 9>
   
    //przeliczenie, zamieniajace poj. nr pola (z zakresu od 1 do 9) na 2 indeksy naszej tablicy g_aPlansza (kazdy z przedziału od 0 do 2)
    unsigned uY =( uNumerPola - 1 ) / 3;
    unsigned uX =( uNumerPola - 1 ) % 3;
   
    if( g_aPlansza[ uY ][ uX ] == FLD_EMPTY )
         g_aPlansza[ uY ][ uX ] == static_cast < FIELD >( g_AktualnyGracz );
    else return false;
   
    const int LINIE[][ 3 ][ 2 ] = { { { 0, 0 }, { 0, 1 }, { 0, 2 } },
        { { 1, 0 }, { 1, 1 }, { 1, 2 } },
        { { 2, 0 }, { 2, 1 }, { 2, 2 } },
        { { 0, 0 }, { 1, 0 }, { 2, 0 } },
        { { 0, 1 }, { 1, 1 }, { 2, 1 } },
        { { 0, 2 }, { 1, 2 }, { 2, 2 } },
        { { 0, 0 }, { 1, 1 }, { 2, 2 } },
        { { 2, 0 }, { 1, 1 }, { 0, 2 } } };
   
    FIELD Pole, ZgodnePole;
    unsigned uLiczbaZgodnychPol;
    for( int i = 0; i < 8; ++i )
    {
        //i przebiega po kolejnych mozliwych liniach (jest ich osiem)
        //zerujemy zmienne pomocnicze
        Pole = ZgodnePole = FLD_EMPTY; // obie zmienne == FLD_EMPTY
        uLiczbaZgodnychPol = 0;
       
        for( int j = 0; j < 3; ++j )
        {
            //j przebiega po 3 polach w kazdej linii
           
            //pobieramy rzeczone pole
            Pole = g_aPlansza[ LINIE[ i ][ j ][ 0 ] ][ LINIE[ i ][ j ][ 1 ] ];
           
            //jesli sprawdzone pole rozni sie od tego, ktore ma sie zgadzac...
            if( Pole != ZgodnePole )
            {
                ZgodnePole = Pole;
                uLiczbaZgodnychPol = 1;
            }
            else
            //jesli oba pola sie zgadzaja to...
                 ++uLiczbaZgodnychPol; //inkrementujemy licznik zgodnych pol
           
        }
       
        //teraz sprawdamy czy udalo nam sie zgodzic linijke
        if( uLiczbaZgodnychPol == 3 && ZgodnePole != FLD_EMPTY )
        {
            //jezeli tak, to ustawiamy stan gry na wygrana
            g_StanGry = GS_WON;
            //przerywamy petle i funkcje
            return true;
        }
    }
   
    unsigned uLiczbaZapelnionychPol = 0; //spr remis
    //czy plansza jest zapelniona, a nie ma zadnego ukladu zwyciezajacego gre
    for( int i = 0; i < 3; ++i )
    {
        for( int j = 0; j < 3; ++j )
        if( g_aPlansza[ i ][ j ] != FLD_EMPTY )
             ++uLiczbaZapelnionychPol;
       
    }
   
    if( uLiczbaZapelnionychPol == 9 ) //oznacza to, ze wszystkie pola sa pelne, ale nie ma zadnej "trojki"
    {
        g_StanGry = GS_DRAW;
        return true;
    }
    //koniec sytuacji konczacych gre, czyli wygrana albo remis; teraz napiszemy zwykla akcje bez zadnych rezultatow, 1 gracz konczy ture i zaczyna ja drugi gracz
    g_AktualnyGracz =( g_AktualnyGracz == SGN_CIRCLE ? SGN_CROSS: SGN_CIRCLE ); //jesli teraz wykonal ruch gracz "kolo" to zmienmy na krzyzy, a jesli krzyzyk to na kolo
   
    return true;
}

bool RysujPlansze() //wyswietlenie na ekranie biezacego stanu gry
{
    if( g_StanGry == GS_NOTSTARTED ) return false; //jesli gra sie nie rozpoczela przerwij dzialanie funkcji (zabezpieczenie przed ew. bledem)
   
    system( "cls" ); //wyczyszczenie ekranu gry
    //rysujemy gore planszy
    cout << "   KOLKO I KRZYZYK   " << endl;
    cout << "---------------------" << endl << endl;
    //teraz rysujemy plansze z liczbami, kolkami i krzyzykami
    cout << "        -----" << endl;
    for( int i = 0; i < 3; ++i )
    {
        //lewa czesc ramki
        cout << "        |";
        //wiersz
        for( int j = 0; j < 3; ++j )
        {
            if( g_aPlansza[ i ][ j ] == FLD_EMPTY )
            //nr pola
                 cout << i * 3 + j + 1;
            else //wyswietlimy kolko i krzyzyk
                 cout << static_cast < char >( g_aPlansza[ i ][ j ] );
           
        }
        //prawa cz. ramki
        cout << "|" << endl;
    }
    cout << "        -----" << endl << endl;
   
    switch( g_StanGry )
    {
    case GS_MOVE:
        //prosba o nastepny ruch
    cout << "Podaj numer pola, w ktorym chcesz postawic " <<( g_AktualnyGracz == SGN_CROSS ? "krzyzyk": "kolko" ) << ": ";
        break;
    case GS_WON:
        //info o wygranej
    cout << "Wygral gracz stawiajacy " <<( g_AktualnyGracz == SGN_CROSS ? "krzyzyki!": "kolka!" );
        break;
    case GS_DRAW:
        //info o remisie
        cout << "Remis!";
        break;
    }
   
    return true;
}
P-164968
Kinexity
» 2017-09-17 21:16:28
Program działa, tylko twój mózg nie zauważa zmiany znaku dopóki się nie przyjrzysz. A tak w ogóle to sądząc po tym na jakim etapie nauki jesteś ("od zera do gier kodera" - 1.5), sam powinieneś szukać błędów, ponieważ masz już wystarczającą wiedzę.
P-164970
Monika90
» 2017-09-18 10:45:40
Kompilator zna odpowiedź, wystarczy go zapytać

game.cpp: In function 'bool Ruch(unsigned int)':
game.cpp:40:33: warning: statement has no effect [-Wunused-value]
          g_aPlansza[ uY ][ uX ] == static_cast < FIELD >( g_AktualnyGracz );
                                 ^
P-164975
Lich555
Temat założony przez niniejszego użytkownika
» 2017-09-20 22:45:50
Chodzi o to, że wstawiałem spację przy static_cast? Napisałem tak i już się nie rzuca:
C/C++
g_aPlansza[ uY ][ uX ] = static_cast < FIELD >( g_AktualnyGracz );

Jeszcze się rzuca o to:
C/C++
C:\U sers\Kacper\Desktop\C++\I nne\Kolko i krzyzyk\game.cpp || In function 'bool RysujPlansze()':|
C:\U sers\Kacper\Desktop\C++\I nne\Kolko i krzyzyk\game.cpp | 136 | warning: enumeration value 'GS_NOTSTARTED' not handled in switch[ - Wswitch ] |

Chodzi o to, że "wydałem rozkazy" w switchu dla wszystkich wartości mojego typu
enum GAMESTATE
, a dla GS_NOTSTARTED nie powiedziałem co robić? Jak się tego pozbyć? Nie chcę, żeby cokolowiek tam było robione :P

@Edit
Jak robi się to, że wiadomość z loga (warningi i errory) są na takim czarnym tle, a nie takie jak ja tutaj mam?
P-165053
carlosmay
» 2017-09-20 23:07:32
» KursyKurs STC kurs
P-165055
Monika90
» 2017-09-21 09:21:58

Chodzi o to, że wstawiałem spację przy static_cast?
Chodzi o to że użyłeś operatora == zamiast =, więc tablica nie była modyfikowana.

To drugie ostrzeżenie to fałszywy alarm. Można w switchu dodać
case GS_NOTSTARTED: break;
.
P-165059
Lich555
Temat założony przez niniejszego użytkownika
» 2017-09-22 21:23:14
O rany, faktycznie. Dzięki wielkie :)
P-165125
« 1 »
  Strona 1 z 1