GRA W WʯA

pewno╢ci▒ gra│e╢ kiedy╢ w wΩ┐a - grΩ, w kt≤rym kieruje siΩ wΩ┐em zbieraj▒c odpowiednie pola i uwa┐aj▒c, ┐eby nie zapl▒taµ gada. Powsta│o mn≤stwo implementacji tej gry, pocz▒wszy od prymitywnych tetris≤w. Poza tym jest to zadanko chΩtnie zadawane ucz▒cym siΩ programowania. Poni┐ej zamieszczam kod takiej gierki napisany w C++ i gotowy do skompilowania w Borland C++ dla DOSa. Aha, zanim przyst▒pisz do czytania kodu i zaczniesz wykonywaµ jakie╢ modyfikacje, ╢ci▒gnij sobie na dysk plik spakowany ZIP-em i pograj, bo w ten spos≤b utrwalisz sobie regu│y (r≤┐ne wΩ┐e mog▒ siΩ bowiem r≤┐niµ od siebie).

W moim programie g│ow▒ wΩ┐a kieruje siΩ kursorami. Nie mo┐na siΩ zapl▒taµ ani wyj╢µ poza planszΩ, bo wtedy przegrywamy. Nale┐y zbieraµ migaj▒ce pola - dostajemy za to punkty. Ka┐de zebrane pole wyd│u┐a jednak wΩ┐a. Zobacz sam... Aha, czerwone pola to "ceg│y", przez kt≤re nie da siΩ przej╢µ, bo ┐ycie nie jest │atwe....

Nale┐y siΩ jeszcze kr≤tkie wyja╢nienie. WΩ┐a zadeklarowa│em jako klasΩ. Zawiera ona: sta│e wyliczeniowe pozwalaj▒ce │atwo okre╢liµ rodzaj pola na planszy, macierz kwadratow▒, kt≤rej ka┐dy element opisuje jedno pole planszy (za pomoc▒ wspomnianych sta│ych). Opr≤cz tego, struktura "tzlapaj" ze wsp≤│rzΩdnymi aktualnego migaj▒cego kwadratu. Tablica pozycja zawiera wsp≤│rzΩdne kolejnych "segment≤w" wΩ┐a. Funkcja "newzlap()" ustawia nowe wsp≤│rzΩdne migaj▒cego kwadratu. "dlugosc" okre╢la d│ugo╢µ wΩ┐a, czyli ilo╢µ jego segment≤w. Typ wyliczeniowy "kier" i zmienna "kierunek" pomaga okre╢liµ, czy w▒┐ porusza siΩ do g≤ry, w d≤│, w lewo czy w prawo. Funkcja "rysuj" kre╢li planszΩ i wΩ┐a na ekranie. Gra pracuje w trybie tekstowym, co pozwala skupiµ siΩ na rzeczywistym algorytmie, a nie na szczeg≤│ach szybkiego operowania grafik▒ w Dosie. Funkcja zawiera te┐ trzy publiczne metody. MetodΩ "void inicjuj()" traktujemy podobnie do konstruktora. Wywo│aµ j▒ trzeba na pocz▒tku programu. Funkcja "int nastΩpny()" musi byµ wywo│ywana cyklicznie co pewien czas, aby w▒┐ wykona│ kolejny krok. U mnie jest to co 200 milisekund, ale oczywi╢cie dobiera siΩ wg potrzeb. Funkcja zwraca warto╢µ -1, je╢li siΩ przegra│o. Funkcja "void ustawkierunek(char c)" ustawia kierunek, w kt≤ym bΩdzie siΩ porusza│ w▒┐. Kierunek zmienia siΩ w zale┐no╢ci od wciskania kursor≤w i domy╢lnie w▒┐ porusza siΩ do g≤ry (na pocz▒tku).

To chyba wszystko. Je╢li masz jakie╢ pytania dot. kodu, pisz do mnie!

/*Gra Wí» w trybie tekstowym.
  Autor: Micha│ Staszkiewicz
  e-mail: pasman@wp.pl
  http://pasman.republika.pl
  Kompilator: Borland C++ 3.1
  Byt≤w, luty 2001*/
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#include <stdlib.h>

class wezyk {                     //Klasa opisuj▒ca wΩ┐a
  enum {cegla,waz,puste,zlap};    //Mo┐liwe stany p≤l tablicy
  int tablica[21][21];            //Obraz planszy - stan poszczeg≤lnych p≤l
  struct pozycja {int x,y;};
  struct tzlapaj {int x,y;};
  tzlapaj zlapaj;
  int punkty;
  pozycja waztab[400];                //Obraz wΩ┐a - pozycje poszczeg≤lnych
				      //segment≤w (0-g│owa)
  void newzlap();
  int dlugosc;                    // D│ugo╢µ wΩ┐a
  enum kier {gora,dol,lewo,prawo};
  kier kierunek;		 //Kierunek w kt≤rym posuwa siΩ w▒┐
  void rysuj();                  //Rysowanie wΩ┐a na ekranie
  public:
  void inicjuj();                 //Inicjacja wΩ┐a
  int nastepny();                 //Kolejny krok wΩ┐a
  void ustaw_kierunek(char c); //Ustawia kierunek ruchu wΩ┐a
};

void wezyk::newzlap()
{
    int x,y;
    do{
      x=random(21);
      y=random(21);
    }while (tablica[x][y]!=puste);
    tablica[x][y]=zlap;
    zlapaj.x=x;
    zlapaj.y=y;
}

void wezyk::ustaw_kierunek(char c)
{
  switch (c){
    case 75:
      if (waztab[0].x>0 && tablica[waztab[0].x-1][waztab[0].y]!=cegla) kierunek=lewo;
      break;
    case 77:
      if (waztab[0].x<20 && tablica[waztab[0].x+1][waztab[0].y]!=cegla) kierunek=prawo;
      break;
    case 80:
      if (waztab[0].y<20 && tablica[waztab[0].x][waztab[0].y+1]!=cegla) kierunek=dol;
      break;
    case 72:
      if (waztab[0].y>0 && tablica[waztab[0].x][waztab[0].y-1]!=cegla) kierunek=gora;
      break;
  }
}

void wezyk::rysuj()               //Rysowanie;
{
  textbackground(0);
  gotoxy(1,1);
  int x,y,count,kolor;
  for (y=0;y<21;y++) {
    for (x=0;x<21;x++) {
      switch (tablica[x][y]){
	case cegla:
	  kolor = 11;
	  break;
	case puste:
	  kolor = 1;
	  break;
	case waz:
	  kolor=12;
	  break;
	case zlap:
	  kolor=5+128;
	  break;
      }
      textcolor(kolor);
      for (count=0;count<3;count++) cprintf("█");
    }
    cout << '\n';
  }
}

void wezyk::inicjuj() //Inicjacja
{
  clrscr();
  int x,y;
  for (x=0;x<21;x++)
    for (y=0;y<21;y+=2)
      tablica[x][y]=puste; //Puste linie
  for (x=0;x<21;x+=2)
    for (y=1;y<21;y+=2)
      tablica[x][y]=puste; //Puste co drugie
  for (x=1;x<21;x+=2)
    for (y=1;y<21;y+=2)
      tablica[x][y]=cegla; //Co drugie to ceg│a
    tablica[10][10]=waz;
    dlugosc=1;
    waztab[0].x=10;
    waztab[0].y=10;
    kierunek=gora;
    newzlap();
    punkty=0;
  rysuj();
}

int wezyk::nastepny()
{
  int newx=waztab[0].x,newy=waztab[0].y; //Nowe wsp≤│rzΩdne g│owy
  switch (kierunek){
  case gora:
    newy--;
    break;
  case dol:
    newy++;
    break;
  case lewo:
    newx--;
    break;
  case prawo:
    newx++;
    break;
  }
  if (tablica[newx][newy]==zlap) {cout <<'\a';
    dlugosc++;newzlap();
    punkty+=10;
    gotoxy(1,23);
    cout << "Punkty: " << punkty;
  }
  if (newx<0 || newx>20 || newy<0 || newy>20) return -1;
  int index;
  for (index=dlugosc;index>0;index--) {
    waztab[index].x=waztab[index-1].x;
    waztab[index].y=waztab[index-1].y;
  }
  if (tablica[newx][newy]==waz) return -1;
  waztab[0].x=newx;
  waztab[0].y=newy;
  int x,y;
  for (x=0;x<21;x++)
    for (y=0;y<21;y++)
      if (tablica[x][y]==waz) tablica[x][y]=puste;
  for (index=0;index<dlugosc;index++)
      tablica[waztab[index].x][waztab[index].y]=waz;
  rysuj();
  return 0;
}

main()
{

  char znak1,znak2=72;
  wezyk waz;
  waz.inicjuj();
  znak1='\0';
  randomize();
  do
  {
    delay(200);
    if (kbhit()) {znak1=getch();}
    if (kbhit()) {znak2=getch();}
    while (kbhit()) getch();
    waz.ustaw_kierunek(znak2);
  } while (znak1!=27 && znak2!=27 && waz.nastepny()!=-1);
}


Baner reklamowy: