Programming-C

Tasks studies - laboratory

View project on GitHub

Lab06 - Gra w kółko i krzyżyk

Gra w kółko i krzyżyk https://drive.google.com/drive/folders/1-ceXITf1pQ7zAF0N5p8NqOXGnKtbVl4-?usp=sharing

Zadania

TicTacToe.exe

Aktualny stan gry będzie przechowywany w 2 wymiarowej tablicy znaków. Stan powinien być zmienną globalną aby każda funkcja miała do niego dostęp. Ponadto przydatna będzie informacja o wielkośći planszy która może także być przechowywana w zmiennej globalnej.

char tab[3][3] = { {' ', ' ', ' '},
                   {' ', ' ', ' '},
                   {' ', ' ', ' '} }

Krok 1

Napisz funkcję renderboard() która w konsoli wypisze obecny stan gry w następującej postaci:

  A B C
1   
2   
3   
  A B C
1 X   O
2 X O
3   X

Funkcja powinna być w stanie wyrenderować planszę o rozmiarach od 3x3 do 26x26 pól. Przetestuj działanie funkcji. na tablicach:

Tablice testowe ```c int const TAB_SIZE = 4; char board[TAB_SIZE][TAB_SIZE] = { {' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' '} }; ``` ```c //Można zmienić rozmiar tablicy na mniejszy/więszy int const TAB_SIZE = 26; char board[TAB_SIZE][TAB_SIZE]; //w funkcji main ustawiane są wartośći w tablicy int main(int argc, char const *argv[]) { for (size_t i = 0; i < TAB_SIZE; i++) { for (size_t j = 0; j < TAB_SIZE; j++) { board[i][j] = ' '; } } return 0; } ```
Podpowiedź ```c // Typ char przechowuje liczby od 0 do 255 które w funkcji printf() są dekodowane na znaki widoczne w konsoli. // A - 65 // Z - 90 // a - 97 // z - 122 for(char i = 65; i<91; i++){ printf("%c ", i); } ``` Nagłowki kolumn można wypisać przed wypisywaniem wartości planszy. Nagłówki wierszy można wypisać przed iteracją po drugim wymiarze tablicy.
Rozwiązanie:

Tablicę można zainicjalizować jako zmienną globalną podobnie rozmiar tablicy:

int const TAB_SIZE = 3;
char board[3][3] = { {'X', 'O', 'O'},
                    {'X', 'X', 'O'},
                    {'O', ' ', 'X'} };

Rozmiar tablicy musi być nam znany aby sprawnie iterować po kolejnych wartościach. Funkcja renderboard może wykorzystywać globalną informacje o rozmiarze tablicy:

renderboard(){
    for(int i= 0; i< TAB_SIZE; i++){
        for(int j= 0; j< TAB_SIZE; j++){
            printf("%c", tab[i][j]);
        }
    }
}

Krok 2

Napisz funkcję makeMove() która przyjmuje symbol danego gracza na planszy i zwraca następujące kody:

  • 0 - jeśli ruch jest dozwolony (zajmujemy puste pole)
  • 1 - jeśli wykraczamy poza obszar planszy
  • 2 - jeśli chcemy zająć pole innego gracza
  • 3 - inne błędy W ciele funkcji zaimplementuj zapytania do użytkownika o wybranie pola które chce zająć.
Podpowiedź Za pomocą instrukcji scanf() możemy odczytać kilka wartości jednocześnie. ```c char col; int row; printf("Podaj wartośc col i row np. ", player); scanf(" %c %i", &col, &row); ``` Po odczytaniu wartości wystarczy zamienic je na indeksy (numerowane od 0) i sprawdzić odpowiednie warunki.

Krok 3

Napisz funkcję score() która sprawdzi w pionie, poziomie i po przekątnej czy jeden z graczy wygrał, a jeżeli tak zwróci jego symbol.

Podpowiedź Należy sprawdzać czy w kolumach, wierszach, na przekątnych znajdują się takie same znaki. Jeśli natrafimy na znak ' ' możemy przerwać dalsze poszukiwania w kolumnie, wierszu, na przekątnej. Podobnie jesli natrafimy na symbol innego gracza.

Krok 4

Zaimplementuj logikę gry w funkcji main.

*AdvancedTicTacToe.exe

Zmodyfikuj grę TicTacToe tak aby użytkownik mógł zdefiniować wielkość planszy, liczbę i symbole graczy.

Podpowiedź ```c #include #include // Zmienne globalne dostępne dla funkcji // wskaźnik na pierwszy element tablicy int *board; // rozmiar tablicy int BOARD_SIZE = 3; int main(int argc, char const *argv[]) { // Talice w pamięci są przechowyane w kolejnych adresach int tab[2][3] = { {1,2,3},{4,5,6} }; int tab_size = sizeof(tab)/sizeof(int); printf("tab_size = %i\n",tab_size); int iterations = 0; for (int *i = tab; iterations < (sizeof(tab)/sizeof(int)); i++) { printf("%i ", *i); iterations++; } printf("\n"); // Rozmiar tablicy 2x3 typu int to (2*int)*(3*int) gdzie int to wielkość typu int. int size = (BOARD_SIZE * sizeof(int)) * (BOARD_SIZE * sizeof(int)); // funkcja maloc() zarezerwuje w pamięci określoną liczbę bajtów i zwróci wskaźnik do pierwszego bajtu. board = malloc(size); // wiedząc że plansza ma rozmiar 3x3 co 3 komórka w pamięci będzie początkiem nowego wiersza. int row = 0; for (int *rowwsk = board; row < BOARD_SIZE; rowwsk + BOARD_SIZE) { int col = 0; for (int *colwsk = rowwsk; col < BOARD_SIZE; colwsk++) { *colwsk = 0; col++; } row++; } row = 0; for (int *rowwsk = board; row < BOARD_SIZE; rowwsk + BOARD_SIZE) { int col = 0; for (int *colwsk = rowwsk; col < BOARD_SIZE; colwsk++) { printf("board[%i][%i] = %i \t",row, col,*colwsk); col++; } printf("\n"); row++; } // free zwalnia pamięć free(board); return 0; } ``` ```c // +------+ // | | pointer to pointer to T // +------+ // | // v // +------+------+------+ // | | | | pointers to T // +------+------+------+ // | | | +-------------+-------------+-------------+ // | | +---->| | | | elements of type T // | | +-------------+-------------+-------------+ // | | +-------------+-------------+ // | +---->| | | elements of type T // | +-------------+-------------+ // | // v // +-------------+-------------+-------------+-------------+ // | | | | | elements of type T // +-------------+-------------+-------------+-------------+ double **tab2; tab2 = malloc(row * sizeof(double *)); for (int i = 0; i < 3; i++) { tab2[i] = calloc(col,sizeof(double)); } // pzypisujemy wartości tab2[0][0] = 0.0; tab2[0][1] = 0.1; tab2[1][0] = 1.0; tab2[1][1] = 1.1; tab2[2][0] = 2.0; tab2[2][1] = 2.1; // dla 3d array int ***tab3d; tab3d = malloc(2*sizeof(double **)); for (int i = 0; i < 2; i++) { tab3d[i] = malloc(2*sizeof(double *)); for (size_t j = 0; j < 2; j++) { tab3d[i][j] = calloc(2,sizeof(double)); } } ``` </details> ### `Task3.exe` Napisz program który będzie wypisywał w konsoli spiralę o zadanej wielkości - każde kolejne ramię np. ``` Podaj wielkość: 9 # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ``` Długość lini tworzącej spiralę zwiększa się o 1.
Jak obliczyć wielkość tablicy przechowującej spiralę o wielkościach: 5, 6, 7, 8?
Jak wyznaczyć początek rysowania spirali?
Które indeksy tablicy zmieniać poruszając się na północ, wschód, południe, zachód?