Tablice - gra Układanka

Zapoznaj się z materiałami przedstawionymi na poprzednich zajęciach koła:

 

Utwórz nowy katalog projektowy. Skopiuj do niego pliki biblioteki:

newconio.cpp  -  plik źródłowy biblioteki
newconio.h  - plik nagłówkowy dla biblioteki

Utwórz nowy projekt konsoli w Dev-C++. Do projektu dodaj plik źródłowy newconio.cpp z twojego katalogu projektowego.

 

Tablica

Tablica jest złożoną strukturą danych, zbudowaną z elementów tego samego typu. Tablice umożliwiają w jednolity sposób przechowanie dużych ilości danych (np. wyniki pomiarów pewnej wielkości fizycznej w różnych punktach czasu, wartości funkcji dla kolejnych argumentów, itp.).

Jak każda zmienna, również tablica musi być zdefiniowana przed pierwszym użyciem. Robimy to w sposób następujący:

 

typ_elementów  nazwa_tablicy[liczba_elementów];

typ_elementów - określa rodzaj informacji, które będą umieszczane w komórkach tablicy. Może to być typ prosty: int, double, char, bool itd. lub dowolny inny.

nazwa_tablicy  - tworzona jest wg tych samych zasad, co nazwa zmiennej - może składać się z liter łacińskich małych lub dużych (są rozróżnialne), cyfr oraz znaku podkreślenia. Pierwszy znak musi być literą lub podkreśleniem.

liczba_elementów  - określa rozmiar tablicy, czyli liczbę przechowywanych w niej elementów o danym typie.

 

Przykład:

int a[100];  // tworzy tablicę 100 liczb całkowitych ze znakiem o nazwie a

 

Przy definiowaniu zmiennych można mieszać tablice ze zmiennymi prostymi (nie zalecam tego jednak):

double x,y,z[25];  // tworzy dwie zmienne proste x i y typu double oraz tablicę z zawierającą 25 liczb typu double

 

Dostęp do elementów tablicy odbywa się poprzez ich numery zwane indeksami. Numeracja elementów w tablicy rozpoczyna się zawsze od 0. Zatem tablica:

char c[10];

zawiera elementy (znaki) o indeksach:

c[0]   c[1]   c[2]   c[3]   ...   c[8]   c[9]

Zauważ, iż w tej tablicy NIE MA elementu c[10]! Zwracam na to uwagę, gdyż uczniowie często popełniają błąd polegający na odwoływaniu się do nieistniejącego elementu tablicy. Co gorsza, kompilator zwykle nie zgłosi błędu, tylko sięgnie poza obszar tablicy, co może skończyć się fatalnie dla programu.

 

Element tablicy jest "normalną" zmienną. Możemy jej przypisywać dowolne (lecz dozwolone dla danego typu) wartości:

...

int a[3];  // tworzymy trzyelementową tablicę a
...
a[0] = 15;
a[1] = 6;
a[2] = 33// teraz tablica a zawiera w kolejnych komórkach liczby 15, 6, 33

...

for(int i = 0; i < 3; i++) cout << a[i] << endl; // wypisujemy zawartość tablicy a
...

 

Tablicę można inicjować w trakcie jej definicji:

int a[5] = {4,3,8,2,1};

 

Tablice mogą posiadać więcej niż jeden wymiar. Tablicę dwuwymiarową możemy sobie wyobrazić jako tablicę, której elementy są tablicami:

int a[3][4];

Zostaje utworzona tablica a o dwóch wymiarach. Tablica ta zawiera jakby trzy tablice 4-elementowe. Dostęp do elementów uzyskujemy poprzez dwa indeksy - pierwszy indeks wybiera element-tablicę, drugi indeks wybiera element w tej tablicy. Powyższa definicja tworzy następujące elementy:

tablica a[0] → a[0][0]   a[0][1]   a[0][2]   a[0][3]

tablica a[1] → a[1][0]   a[1][1]   a[1][2]   a[1][3]

tablica a[2] → a[2][0]   a[2][1]   a[2][2]   a[2][3]

Możemy również wyobrazić sobie taką tablicę jak dwuwymiarową tabelę, w której pierwszy indeks określa numer wiersza a drugi numer kolumny. Indeksy te wybierają element leżący w danym wierszu i w danej kolumnie:

  0 1 2 3
  0 a[0][0] a[0][1] a[0][2] a[0][3]
  1 a[1][0] a[1][1] a[1][2] a[1][3]
  2 a[2][0] a[2][1] a[2][2] a[2][3]

Tablicę dwuwymiarową inicjujemy następująco:

int a[3][4] = {{1,2,3,4},{4,3,2,1},{2,2,2,2}};

 

Wewnętrzne klamerki inicjują kolejne elementy-tablice a[0], a[1] i a[2]. Tablica a zawiera takich tablic trzy.

 

Gra Układanka

Gra toczy się na planszy 5 x 5 pól, na której znajduje się 24 kwadraty z literkami od A do X. Jedno pole jest puste. Na puste pole można przesunąć sąsiedni kwadrat. Kwadraty zostają losowo pomieszane. Celem gry jest doprowadzenie do następującego układu kwadratów:

A B C D E
F G H I J
K L M N O
P Q R S T
U V W X  

W grze kwadraty przesuwamy klawiszami kursora. Kończymy szybko rozgrywkę klawiszem ESC.

 

Program

// Układanka
// (C)2009 Koło informatyczne w I LO w Tarnowie
// Kurs programowania w C++ dla początkujących
//--------------------------------------------

#include "newconio.h"
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

// Dane
//-------------------

// Tablica wzorcowego układu segmentów
//------------------------------------
char wtab[5][5] = {{'A','B','C','D','E'},
                   {'F','G','H','I','J'},
                   {'K','L','M','N','O'},
                   {'P','Q','R','S','T'},
                   {'U','V','W','X',' '}};

// Tablica robocza, uzywana w grze do przesuwania segmentów
//---------------------------------------------------------
char rtab[5][5];

// Pozycja pustego segmentu - kolumna, wiersz
//-------------------------------------------
int pk,pw;

// Licznik ruchów
//---------------
int licznik;

// Rysuje planszę gry
//-------------------
void plansza()
{
  fullscreen(true);
  cursoroff();
  textbackground(BLUE);
  clrscr();
  fillrectattr(GREEN << 4,26,11,52,37);
  fillrectattr(0,29,14,49,34);
  textattr(0x1f);
  center(3,_pl("U K Ł A D A N K A"));
  textattr(0x1e);
  center(5,_pl("(C)2009 Koło Informatyczne w I-LO w Tarnowie"));    
}

// Pyta, czy jeszcze jedna gra...
//-------------------------------
bool jeszcze_raz()
{
  fillrect(' ',0xf0,0,49,79,49);
  textattr(0xf0);
  center(49,_pl("Czy chcesz zagrać jeszcze raz? (T = Tak)"));

  char klawisz;

  while(!(klawisz = getch()));
  return (klawisz=='T') || (klawisz=='t');  
}

// Inicjuje zmienne
//-----------------
void inicjalizacja()
{
  for(int i = 0; i < 5; i++)
    for(int j = 0; j < 5; j++)
      rtab[i][j] = wtab[i][j];
  pw = pk = 4;  // pozycja pustego segmentu w rtab
}

// Wyświetla zawartość tablicy rtab
//---------------------------------
void wyswietl()
{
  int kolor;
  for(int i = 0; i < 5; i++)   // wiersze
    for(int j = 0; j < 5; j++) // kolumny
    {
      if(rtab[i][j] == wtab[i][j])
        kolor = 0xe0;  // żółty
      else
        kolor = 0xc0;  // czerwony
      if(rtab[i][j] == ' ') kolor = 0;
      textattr(kolor);
      gotoxy(31+4*j,16+4*i);
      cout << rtab[i][j];
      fillrectattr(kolor,30+4*j,15+4*i,32+4*j,17+4*i);        
    }
  textattr(0x1e);
  gotoxy(30,47);
  cout << _pl("Liczba ruchów :") << setw(5) << licznik;     
}

// Przesuwa segment na puste miejsce
//----------------------------------
void ruch(int kierunek)
{
  switch(kierunek)
  {
    case 0: // w górę;
      if(pw < 4)
      {
        swap(rtab[pw][pk],rtab[pw+1][pk]);
        pw++;
      }
      break;
    case 1: // w prawo
      if(pk > 0)
      {
        swap(rtab[pw][pk],rtab[pw][pk-1]);
        pk--;
      }
      break;
    case 2: // w dół
      if(pw > 0)
      {
        swap(rtab[pw][pk],rtab[pw-1][pk]);
        pw--;
      }
      break;
    case 3: // w lewo
      if(pk < 4)
      {
        swap(rtab[pw][pk],rtab[pw][pk+1]);
        pk++;
      }
      break;
  }
  licznik++;
  wyswietl();
}

// Miesza planszę
//---------------
void mieszaj()
{
  for(int i = 0; i < 1000; i++)
  {
    ruch(rand() % 4);
    delay(1);
  }     
}

// Sprawdza, czy rtab = wtab
//--------------------------
bool test()
{
  for(int i = 0; i < 5; i++)
    for(int j = 0; j < 5; j++)
      if(rtab[i][j] != wtab[i][j])
        return true;
  textattr(0x4e);
  center(47," >>> G R A T U L A C J E ! ! ! <<< ");
  return false;
}

// Główna program gry
//-------------------
main()
{  
  _cinit();                         // inicjujemy bibliotekę newconio
  srand((unsigned)time(NULL));      // inicjujemy generator liczb pseudolosowych
  do                                // tutaj jest główna pętla gry
  { 
    plansza();                      // wyświetlamy planszę gry
    inicjalizacja();                // inicjujemy rtab, pk, pw, licznik
    mieszaj();                      // losowo mieszamy kwadraty z literkami w rtab
    licznik = 0;                    // ustawiamy liczbę wykonanych ruchów na zero
    wyswietl();                     // wyświetlamy licznik
    do                              // tutaj jest pętla rozgrywki
    {
      char klawisz;
      
      while(!(klawisz = getch()));  // czekamy na klawisz
      if(klawisz == 27) break;      // jeśli klawisz ESC, przerywamy pętlę rozgrywki
          
      switch(klawisz)               // wykonujemy ruch wg naciśniętego klawisza
      {
        case 72: ruch(0); break;    // strzałka w górę
        case 77: ruch(1); break;    // strzałka w prawo
        case 80: ruch(2); break;    // strzałka w dół
        case 75: ruch(3); break;    // strzałka w lewo
      }
    } while(test());                // po każdym ruchu sprawdzamy, czy układanka jest skończona
  } while(jeszcze_raz());           // sprawdzamy, czy gracz chce zagrać ponownie
  fullscreen(false);
  cursoron(); textattr(7); clrscr();
}

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe