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

[C++, Allegro, Std::Vector]Powtarzające się wyniki (gra karciana)

Ostatnio zmodyfikowano 2010-09-18 13:51
Autor Wiadomość
lenrokskate
Temat założony przez niniejszego użytkownika
[C++, Allegro, Std::Vector]Powtarzające się wyniki (gra karciana)
» 2010-09-17 16:10:36
Napisałem algorytm który losuje karty z talii tak żeby się nie powtarzały (czyli np. ktoś nie dostał 2 asów kier), a te skubane się powtarzają.

Pliki: talia.bmp

Kod:
C/C++
#include <allegro.h>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <conio.h>

using namespace std;

//sprawdzanie poprawnosci wczytania bitmapy
bool good( BITMAP *& sprawdz )
{
    if( !sprawdz )
    {
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "nie mogę załadować obrazka Ludek !" );
        allegro_exit();
        return 0;
    }
    return 1;
}

//zwraca pozycje x danej karty w bitmapie
int retX( int q )
{
    if( q >= 0 && q <= 12 ) return q * 44;
   
    if( q >= 13 && q <= 25 ) return( q - 13 ) * 44;
   
    if( q >= 26 && q <= 38 ) return( q - 26 ) * 44;
   
    if( q >= 39 && q <= 51 ) return( q - 39 ) * 44;
   
    return 0;
}
//zwraca pozycje y danej karty w bitmapie
int retY( int q )
{
    if( q >= 0 && q <= 12 ) return 0;
   
    if( q >= 13 && q <= 25 ) return 60;
   
    if( q >= 26 && q <= 38 ) return 120;
   
    if( q >= 39 && q <= 51 ) return 180;
   
    return 0;
}

//funkcja losujaca
int rnd( int min, int max ) {
    if( max >= min ) {
        max -= min;
    } else {
        int tmp = min - max;
        min = max;
        max = tmp;
    }
    return max ? rand() % max + min
        : min;
}

BITMAP * bTalia = NULL;

int main( int argc, char ** argv )
{
    srand( time( NULL ) );
    allegro_init();
    install_keyboard();
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 );
    set_palette( default_palette );
    clear_to_color( screen, makecol( 255, 255, 255 ) );
    //deklaracje std::vectorow
    vector < int > talia( 52 );
    vector < int > reka( 2 );
    vector < int > board( 5 );
    //ladowanie bitmapy z talia
    bTalia = load_bitmap( "talia.bmp", default_palette );
    if( !good( bTalia ) ) return 0;
   
    while( true )
    {
        talia.resize( 52 );
        for( int i = 0; i < 52; i++ ) talia[ i ] = i;
       
        int x = 20;
        int y = 20, y2 = 20;
        int lt = talia.size();
       
        textprintf_ex( screen, font, 600, y2, makecol( 200, 200, 200 ), - 1, "Size of talia: %d | %d", talia.size(), lt );
        y2 += 10;
       
        for( int i = 0; i < 2; i++ )
        {
            int los = rnd( 0, talia.size() );
            reka[ i ] = los;
            vector < int >::iterator it = talia.begin() += los;
            talia.erase( it );
            lt--;
            //talia.resize(lt);
            textprintf_ex( screen, font, 600, y2, makecol( 200, 200, 200 ), - 1, "Size of talia: %d | %d", talia.size(), lt );
            y2 += 10;
        }
        for( int i2 = 0; i2 < 5; i2++ )
        {
            int los2 = rnd( 0, talia.size() );
            board[ i2 ] = los2;
            vector < int >::iterator it2 = talia.begin() += los2;
            talia.erase( it2 );
            lt--;
            //talia.resize(lt);
            textprintf_ex( screen, font, 600, y2, makecol( 200, 200, 200 ), - 1, "Size of talia: %d | %d", talia.size(), lt );
            y2 += 10;
        }
       
        for( int i3 = 0; i3 < 2; i3++ )
        {
            blit( bTalia, screen, retX( reka[ i3 ] ), retY( reka[ i3 ] ), x, y, 44, 60 );
            x += 49;
        }
        x = 20;
       
        y += 70;
       
        for( int i4 = 0; i4 < 3; i4++ )
        {
            blit( bTalia, screen, retX( board[ i4 ] ), retY( board[ i4 ] ), x, y, 44, 60 );
            x += 49;
        }
        x += 10;
        blit( bTalia, screen, retX( board[ 3 ] ), retY( board[ 3 ] ), x, y, 44, 60 );
        x += 59;
        blit( bTalia, screen, retX( board[ 4 ] ), retY( board[ 4 ] ), x, y, 44, 60 );
       
        readkey();
    }
   
    talia.clear();
    reka.clear();
    board.clear();
    destroy_bitmap( bTalia );
    allegro_exit();
    return 0;
}
END_OF_MAIN()
P-22049
DejaVu
» 2010-09-17 16:20:57
Swego czasu pisałem na szybciora program żeby się dostać do jednej firmy, więc zapodam Ci niewielką częścią programu, który wówczas pisałem.

BingoRandomizer.hpp

C/C++
#pragma once

#include <vector>

namespace bingo
{
    class CBingoRandomizer
    {
    public:
        const long m_iValuesCount;
       
        typedef long TValue;
        typedef std::vector < TValue > TValues;
        const TValue & at( long iIndex ) const;
        size_t size() const;
       
        CBingoRandomizer();
        void clear();
        bool randItem( TValue & iValue );
        TValue getLastValue() const;
        long getBallsLeft() const;
       
    protected:
        TValues m_vValues;
        TValues m_vSolution;
       
    }; //clas CBingoRandomizer
   
} //namespace bingo

BingoRandomizer.cpp

C/C++
#include "appZadanie/BingoRandomizer.hpp"

namespace bingo
{
   
    CBingoRandomizer::CBingoRandomizer()
        : m_iValuesCount( 60 )
    {
        clear();
    }
   
    void CBingoRandomizer::clear()
    {
        m_vSolution.clear();
        m_vValues.clear();
        for( TValue i = 1; i <= m_iValuesCount; i++ )
             m_vValues.push_back( i );
       
    }
   
    bool CBingoRandomizer::randItem( TValue & iValue )
    {
        if( m_vValues.empty() )
             return false;
       
        int iIndex = rand() % m_vValues.size();
        m_vSolution.push_back( m_vValues.at( iIndex ) );
        iValue = m_vValues[ iIndex ];
        m_vValues[ iIndex ] = * m_vValues.rbegin();
        m_vValues.pop_back();
        return true;
    }
   
    const CBingoRandomizer::TValue & CBingoRandomizer::at( long iIndex ) const
    {
        return m_vValues.at( iIndex );
    }
   
    size_t CBingoRandomizer::size() const
    {
        return m_vValues.size();
    }
   
    CBingoRandomizer::TValue CBingoRandomizer::getLastValue() const
    {
        if( m_vSolution.empty() )
             return 0;
       
        return * m_vSolution.rbegin();
    }
   
    long CBingoRandomizer::getBallsLeft() const
    {
        return static_cast < long >( m_vValues.size() );
    }
   
} //namespace bingo
P-22050
lenrokskate
Temat założony przez niniejszego użytkownika
» 2010-09-17 16:55:09
to chyba poziom wyżej niż mój... wolałbym naprawić to moje
P-22053
DejaVu
» 2010-09-17 20:55:29
Interesuje Ciebie metoda:
C/C++
bool CBingoRandomizer::randItem( TValue & iValue )
{
    if( m_vValues.empty() )
         return false;
   
    int iIndex = rand() % m_vValues.size();
    m_vSolution.push_back( m_vValues.at( iIndex ) );
    iValue = m_vValues[ iIndex ];
    m_vValues[ iIndex ] = * m_vValues.rbegin();
    m_vValues.pop_back();
    return true;
}
1. Tworzysz tablicę z zakresem danych, przykładowo: 1..1234
2. Losujesz indeks z tablicy (0...n-1), gdzie n oznacza ile elementów pozostało
3. Zapamiętujesz wartość, która znajduje się pod wylosowanym indeksem
4. Przenosisz ostatni element tablica[n-1] w miejsce wylosowanego indeksu.
5. Usuwasz element z tablicy (w Twoim przypadku wystarczy zmniejszyć wartość zmiennej n o jeden.
6. Zwracasz wylosowaną wartość (zapamiętaną w kroku 3).

/edit:
Można oczywiście zrobić algorytm w którym dopisujesz liczby i szukasz czy występuje, jednak w takim przypadku będziesz miał złożoność logarytmiczną lub liniową w zależności od przyjętego rozwiązania, natomiast w przypadku który omówiłem złożoność obliczeniowa jest stała.
P-22066
dmx81
» 2010-09-18 00:49:20
p.s. troche OT - ale co tam, jesli juz zaznaczone to w tekscie przez autora - udalo sie dostac do firmy? ;P
P-22076
DejaVu
» 2010-09-18 01:13:48
Nie udało się dostać do tamtej firmy - olali mnie :)
P-22077
lenrokskate
Temat założony przez niniejszego użytkownika
» 2010-09-18 11:39:28
da radę naprawić to moje? bo nieważne czy jest to szybkie i wydajne rozwiązanie czy nie, chciałbym się dowiedzieć co zrobiłem źle...
P-22080
ison
» 2010-09-18 11:57:50
a funkcji losującej
C/C++
return max ? rand() % max + min
    : min;
nie wiem jakie było założenie ale ten return nie zwraca liczby wylosowanej z przedziału od min do max tylko od min do max+min
P-22082
« 1 » 2
  Strona 1 z 2 Następna strona