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

Algorytm wykrywania pustych miejsc w grze kółko i krzyżyk

Ostatnio zmodyfikowano 2013-12-15 19:31
Autor Wiadomość
glumis1994
Temat założony przez niniejszego użytkownika
Algorytm wykrywania pustych miejsc w grze kółko i krzyżyk
» 2013-12-14 19:28:33
Witam!!!

Chciałbym prosić o pomoc. Napisałem kod na grę kółko i krzyżyk, gracz vs komputer. Komputer losuje miejsce położenia znaku za pomocą funkcji rand. Jednak borykam się cały czas z problemem odrzucenia powtarzających się już miejsc, tzn., że jeśli gracz wybierze pewne miejsce to żeby komputer nie wybrał tego samego. Proszę zwrócić uwagę na algorytm w funkcji "easy", który ma pełnić to zadanie.
C/C++
#include "winbgi2.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

// zdefiniowanie funckji wykorzystywanych w programie

void easy( int * tab, int b );
void rysuj( int * tab );
void spr( int * tab );
/*void hard(int *tab, int b);*/


void main()
{
    int a, b;
    int tab[ 9 ];
   
   
   
    /*...............................................................wstęp...................................................*/
    // Nagłówek
    printf( "*******************************************************************************\n" );
    printf( "*******************************************************************************\n" );
    printf( "***\t\t\t\t\t\t\t\t\t    ***\n" );
    printf( "***\t\t\t   GRA W KOLKO I KRZYZYK   \t\t\t    ***\n" );
    printf( "***\t\t\t\t\t\t\t\t\t    ***\n" );
    printf( "***     Copyright by Hubert Buczynski             ***\n" );
    printf( "***\t\t\t\t\t\t\t\t\t    ***\n" );
    printf( "*******************************************************************************\n" );
    printf( "*******************************************************************************\n" );
   
    //użytkownik wybiera opcje
    printf( "\n\n1).........................::Wybierz poziom gry::...............................\n\n \tEASY <1>\t\t\t \tHARD <2>\t:" ); scanf( "%d", & a );
    printf( "\n\n2)........................::Wybierz swoj znak, X <1> lub O <0> \t:" ); scanf( "%d", & b );
    printf( "\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ZACZYAMY GRE<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n" );
   
    //zapisuje tablice
   
   
    //zdefiniowanie tabeli do gry
    graphics( 900, 900 );
    line( 300, 150, 300, 600 ); //1 linia
    line( 450, 150, 450, 600 ); //2 linia
    line( 150, 300, 600, 300 ); //3 linia
    line( 150, 450, 600, 450 ); //4 linia
   
    for( int i = 0; i < 9; i++ )
    {
        tab[ i ] = 12 + i;
    }
   
    //przydzielenie do funckji na bazie opcji uzytkownika
    if( a == 1 )
         easy( tab, b );
    //else if (a == 2)
    //hard(tab, b);
   
    wait();
   
   
}


/*....................................łatwy  poziom gry..................................*/
void easy( int * tab, int b )
{
    int c[ 5 ];
    int d[ 5 ];
    int L = 9;
    int e = 0;
   
    for( int m = 0; m < 5; m++ )
    {
        c[ m ] = 12;
        d[ m ] = 12;
    }
   
    // gracz zaczynajacy X
    if( b == 1 )
    {
        for( int i = 0; i < 4; i++ )
        {
            // ruch gracza
            printf( "\nRuch zawodnika: \t" ); scanf( "%d", & c[ i ] );
            tab[ c[ i ] - 1 ] = 1;
            rysuj( tab );
            printf( "%d tab[%d]= %d", c[ i ], c[ i ] - 1, tab[ c[ i ] - 1 ] );
            spr( tab );
           
            printf( "\nRuch wykonuje komputer\n" );
            srand( time( NULL ) );
           
            // komputer losuje pole
            do
            {
                // sprawdzam czy komputer nie wylosował zajętego pola
                d[ i ] = rand() % L + 1;
                for( int j = 0; j < 4; j++ )
                {
                    if(( d[ i ] != d[ j ] ) &&( d[ i ] != c[ j ] ) )
                    {
                        tab[ d[ i ] - 1 ] = 0;
                        e = 1;
                    }
                }
            } while( e == 0 );
           
            printf( "%d", d[ i ] );
            rysuj( tab ); spr( tab );
        }
       
        // ostatni ruch gracza
        printf( "\nRuch zawodnika: \t" ); scanf( "%d", & c[ 5 ] );
        tab[ c[ 5 ] - 1 ] = 1;
        rysuj( tab ); spr( tab );
        printf( "%d tab[%d]= %d", c[ 5 ], c[ 5 ] - 1, tab[ c[ 5 ] - 1 ] );
        printf( "\n >>> REMIS <<<" );
    }
   
    // gracz zaczynajacy O
    else if( b == 0 )
    {
        for( int i = 0; i < 4; i++ )
        {
            // ruch gracza
            printf( "\nRuch zawodnika: \t" ); scanf( "%d", & c[ i ] );
            tab[ c[ i ] - 1 ] = 0;
            rysuj( tab );
            printf( "%d tab[%d]= %d", c[ i ], c[ i ] - 1, tab[ c[ i ] - 1 ] );
            spr( tab );
           
           
            printf( "\nRuch wykonuje komputer\n" );
            srand( time( NULL ) );
            // komputer losuje pole
           
            do
            {
                // sprawdzam czy komputer nie wylosował zajętego pola
                d[ i ] =( int )( rand() % L + 1 );
                for( int j = 0; j < 4; j++ )
                {
                    if(( d[ i ] != d[ j ] ) &&( d[ i ] != c[ j ] ) )
                    {
                        tab[ d[ i ] - 1 ] = 1;
                        e = 1;
                    }
                }
            } while( e == 0 );
           
            printf( "%d", d[ i ] );
            rysuj( tab ); spr( tab );
        }
       
        // ostatni ruch gracza
        printf( "\nRuch zawodnika: \t" ); scanf( "%d", & c[ 5 ] );
        tab[ c[ 5 ] - 1 ] = 0;
        rysuj( tab ); spr( tab );
        printf( "%d tab[%d]= %d", c[ 5 ], c[ 5 ] - 1, tab[ c[ 5 ] - 1 ] );
       
        printf( "\n >>> REMIS <<<" );
    }
}


/*..............................................Rysowanie elementów...............................................*/
void rysuj( int * tab )
{
    if( tab[ 0 ] == 1 ) // pole 1 dla krzyzyka
    {
        line( 150, 150, 290, 290 );
        line( 290, 150, 150, 290 );
       
    }
    if( tab[ 0 ] == 0 ) // pole 1 dla kółka
    {
        circle( 225, 225, 70 );
    }
    if( tab[ 1 ] == 1 ) //pole 2 dla krzyzyka
    {
        line( 310, 150, 440, 290 );
        line( 310, 290, 440, 150 );
    }
    if( tab[ 1 ] == 0 ) // pole 2 dla kółka
    {
        circle( 375, 225, 70 );
    }
    if( tab[ 2 ] == 1 ) // pole 3 dla krzyzyka
    {
        line( 460, 150, 600, 290 );
        line( 460, 290, 600, 150 );
    }
    if( tab[ 2 ] == 0 ) // pole 3 dla kółka
    {
        circle( 525, 225, 70 );
    }
    if( tab[ 3 ] == 1 ) // pole 4 dla krzyżyka
    {
        line( 150, 310, 290, 440 );
        line( 150, 440, 290, 310 );
    }
    if( tab[ 3 ] == 0 ) //pole 4 dla kółka
    {
        circle( 225, 375, 70 );
    }
    if( tab[ 4 ] == 1 ) // pole 5 dla krzyzka
    {
        line( 310, 310, 440, 440 );
        line( 310, 440, 440, 310 );
    }
    if( tab[ 4 ] == 0 ) // pole 5 dla kółka
    {
        circle( 375, 375, 70 );
    }
    if( tab[ 5 ] == 1 ) // pole 6 dla krzyzyka
    {
        line( 460, 310, 590, 440 );
        line( 460, 440, 590, 310 );
    }
    if( tab[ 5 ] == 0 ) // pole 6 dla kółka
    {
        circle( 525, 375, 70 );
    }
    if( tab[ 6 ] == 1 ) // pole 7 dla krzyzyka
    {
        line( 150, 460, 290, 600 );
        line( 150, 600, 290, 460 );
    }
    if( tab[ 6 ] == 0 ) // pole 7 dla kółka
    {
        circle( 225, 525, 70 );
    }
    if( tab[ 7 ] == 1 ) // pole 8 dla krzyżyka
    {
        line( 310, 460, 440, 590 );
        line( 310, 590, 440, 460 );
    }
    if( tab[ 7 ] == 0 ) // pole 8 dla kółka
    {
        circle( 375, 525, 70 );
    }
    if( tab[ 8 ] == 1 ) // pole 9 dla krzyzyka
    {
        line( 460, 460, 590, 590 );
        line( 460, 590, 590, 460 );
    }
    if( tab[ 8 ] == 0 ) // pole 9 dla kółka
    {
        circle( 525, 525, 70 );
    }
}

/*...................................................Sprawdzenie wygranej..................................................*/
void spr( int * tab )
{
    /* sprawdz wiersze */
   
    if(( tab[ 0 ] == tab[ 1 ] && tab[ 0 ] == tab[ 2 ] && tab[ 2 ] == tab[ 1 ] ) ||( tab[ 3 ] == tab[ 4 ] && tab[ 3 ] == tab[ 5 ] && tab[ 4 ] == tab[ 5 ] ) ||( tab[ 6 ] == tab[ 7 ] && tab[ 6 ] == tab[ 8 ] && tab[ 7 ] == tab[ 8 ] ) )
    {
        printf( " Wygrales, koniec gry" ); wait();
    }
    //sprawdż kolumny
    if(( tab[ 0 ] == tab[ 3 ] && tab[ 3 ] == tab[ 6 ] && tab[ 0 ] == tab[ 6 ] ) ||( tab[ 1 ] == tab[ 4 ] && tab[ 7 ] == tab[ 1 ] && tab[ 4 ] == tab[ 7 ] ) ||( tab[ 2 ] == tab[ 5 ] && tab[ 8 ] == tab[ 5 ] && tab[ 2 ] == tab[ 8 ] ) )
    {
        printf( " Wygrales, koniec gry" ); wait();
    }
   
    //sprawdź skosy
    if(( tab[ 0 ] == tab[ 4 ] && tab[ 4 ] == tab[ 8 ] && tab[ 0 ] == tab[ 8 ] ) ||( tab[ 2 ] == tab[ 4 ] && tab[ 4 ] == tab[ 6 ] && tab[ 2 ] == tab[ 6 ] ) )
    {
        printf( " Wygrales, koniec gry" ); wait();
    }
   
}
P-99214
pekfos
» 2013-12-15 11:51:40
Masz tablicę jednowymiarową z planszą i komputer losuje puste pole. Sprawdzenie tego, to zwykłe wyciągnięcie wartości z tablicy i porównanie jej z czymś.
C/C++
do
a = rand() % 9;
while( tab[ a ] != puste );
P-99255
glumis1994
Temat założony przez niniejszego użytkownika
» 2013-12-15 19:14:49
zmieniłem warunek na taki:
C/C++
do
{
    // komputer losuje pole
    z = rand() % L + 1;
   
} while(( tab[ z ] == 0 ) ||( tab[ z ] == 1 ) ); // sprawdzam czy komputer nie wylosował zajętego pola

Pole będzie zajęte gdy dany numer tablicy będzie miał przypisane 0 lub 1.
Jednak dalej zdarza się, że komputer wybiera zajęte już miejsca i nie wiem w czym tkwi problem ;/

Zamieszczam dodatkowo przekształcony cały kod funkcji:
C/C++
void easy( int * tab, int b )
{
    int L = 9;
    int e = 0;
    int z = 0;
   
   
    // gracz zaczynajacy X
    if( b == 1 )
    {
        for( int i = 0; i < 4; i++ )
        {
            // ruch gracza
            printf( "\nRuch zawodnika: \t" ); scanf( "%d", & e );
            tab[ e - 1 ] = 1;
            rysuj( tab );
            printf( "%d tab[%d]= %d", e, e - 1, tab[ e - 1 ] );
            spr( tab );
           
            printf( "\nRuch wykonuje komputer\n" );
            srand( time( NULL ) );
           
           
            do
            {
                // komputer losuje pole
                z = rand() % L + 1;
               
            } while(( tab[ z ] == 0 ) ||( tab[ z ] == 1 ) ); // sprawdzam czy komputer nie wylosował zajętego pola
           
            printf( "%d", z );
            tab[ z - 1 ] = 0;
            rysuj( tab ); spr( tab );
        }
       
        // ostatni ruch gracza
        printf( "\nRuch zawodnika: \t" ); scanf( "%d", & e );
        tab[ e - 1 ] = 1;
        rysuj( tab ); spr( tab );
        printf( "%d tab[%d]= %d", e, e - 1, tab[ e - 1 ] );
        printf( "\n >>> REMIS <<<" );
    }
    /*
    // gracz zaczynajacy O
    else if (b == 0)
    {
    for (int i = 0; i < 4; i++)
    {
    // ruch gracza
    printf("\nRuch zawodnika: \t"); scanf("%d", &c[i]);
    tab[c[i] - 1] = 0;
    rysuj(tab);
    printf("%d tab[%d]= %d", c[i], c[i] - 1, tab[c[i] - 1]);
    spr(tab);
   
   
    printf("\nRuch wykonuje komputer\n");
    srand(time(NULL));
    // komputer losuje pole
   
    do
    {
    // sprawdzam czy komputer nie wylosował zajętego pola
    d[i] = (int)(rand() % L + 1);
    for (int j = 0; j < 4; j++)
    {
    if ((d[i] != d[j]) && (d[i] != c[j]))
    {
    tab[d[i] - 1] = 1;
    e = 1;
    }
    }
    } while (e == 0);
   
    printf("%d", d[i]);
    rysuj(tab); spr(tab);
    }
   
    // ostatni ruch gracza
    printf("\nRuch zawodnika: \t"); scanf("%d", &c[5]);
    tab[c[5] - 1] = 0;
    rysuj(tab); spr(tab);
    printf("%d tab[%d]= %d", c[5], c[5] - 1, tab[c[5] - 1]);
   
    printf("\n >>> REMIS <<<");
    }*/
}
P-99312
pekfos
» 2013-12-15 19:16:41
Przypisujesz wartość do innego pola niż te, które wylosowałeś.
P-99313
glumis1994
Temat założony przez niniejszego użytkownika
» 2013-12-15 19:21:45
Już poprawiłem, powinno być tak:
C/C++
do
{
    // komputer losuje pole
    z = rand() % L + 1;
   
} while(( tab[ z - 1 ] == 0 ) ||( tab[ z - 1 ] == 1 ) )
Poprzednio dałem zły warunek, ale już wszystko działa.

Dzięki wielkie ;)
P-99314
pekfos
» 2013-12-15 19:31:25
Pomijając to, że dodajesz 1, by wszędzie odejmować 1..
P-99316
« 1 »
  Strona 1 z 1