Merge Sort

In questo breve tutorial andremo a vedere implementazione, funzionamente e spiegazione dell’algoritmo merge sort.

Ingredienti

 

Merge sort: Cosa e’? A cosa serve?

Merge sort e’ un algoritmo di ordinamento con una complessita’ minore rispetto agli altri algoritmi di ordinamento visti fino ad ora.
Difatti, nel caso pessimo, in mergesort avremo comunque una complessita’ nlog(n).

Merge sort: Come funziona?

Merge sort, sfruttando la tecnica del divide et impera, divide il problema piu’ grande che in questo caso sarebbe l’array preso per intero in due parti.
In questo modo si va a creare 2 sottoproblemi, altri due array ai quali andra’ ad applicare la stessa tecnica, fino ad arrivare a una serie di array formati da 2 elementi (“fino ad arrivare al problema minimo”).
Una volta arrivato ad avere i vari sottoarray composti da due elementi, va a confrontare i valori interni ad essi ordinandoli in modo crescente/decrescente a seconda di come abbiamo deciso di andare ad ordinare l’array.

Ordinati tutti i vari sotto-array, mettiamo caso che io abbia 3 array cosi composti : 2-4 | 3-7 | 5-6.

Quello che andra’ a fare ora merge sort sara’ “fondere” questi array in maniera ordinata.
Andra’ quindi a confrontare il 2 del primo array con il 3 del secondo array e, vedendo che il 2 e’ gia’ minore del 3, non avra’ bisogno di andarlo a confrontare anche con il 7, in quanto sappiamo gia’ che il 3 e’ gia minore di 7.

Una volta confrontato il 2, l’algoritmo andra’ a confrontare il 4 con il 3, vedra’ che e’ maggiore, e quindi sara’ costretto a confrontarlo anche con il 7.
Vedra’ che questi e’ minore e quindi il 4 andra’ a prendere il posto del 3 andando a creare l’array formato da 4 elementi cosi composto: 2-3-4-7.

Quello che andra’ a fare ora l’algoritmo sara’ fondere i due sotto array rimanenti “2-3-4-7 | 5-6” utilizzando lo stesso metodo.

Vi allego un’immagine presa da wikipedia per farvi capire meglio:
animazionemergesort

Merge sort: Implementiamolo in c per capire meglio

 

 

#include ;
#define max 5

int a[6] = { 2, 4, 3, 7, 5, 6};
int b[6];

void merging(int low, int mid, int high) {
int l1, l2, i;
for(l1 = low, l2 = mid + 1, i = low; l1 <= mid && l2 <= high; i++) {
if(a[l1] <= a[l2])
b[i] = a[l1++];
else
b[i] = a[l2++];
}

while(l1 <= mid)
b[i++] = a[l1++];

while(l2 <= high)
b[i++] = a[l2++];

for(i = low; i <= high; i++)
a[i] = b[i];
}

void sort(int low, int high) {
int mid;

if(low < high) {
mid = (low + high) / 2;
sort(low, mid);
sort(mid+1, high);
merging(low, mid, high);
} else {
return;
}
}

int main() {
int i;

printf("List before sorting\n");

for(i = 0; i <= max; i++)
printf("%d ", a[i]);

sort(0, max);

printf("\nList after sorting\n");

for(i = 0; i <= max; i++)
printf("%d ", a[i]);
}

Il codice stavolta l ho preso da tutorialspoint potete provarlo con un compilatore e otterrete il seguente output:

List before sorting
2 4 3 7 5 6 
List after sorting
2 3 4 5 6 7

 

 

alghoritmtable

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Bubble sort

Bubble Sort

Ingredienti

 

Bubble sort: Cosa e’? A cosa serve?

Bubble sort e’ un’altro algoritmo di ordinamento per array che puo’ andare a sostituire il precedente caso visto “Select Sort”.

Perche’ proprio bolla? Beh, come andremo a vedere di seguito, i vari elementi si potranno andare a identificare come varie “bollicine”, le quali a seconda del loro peso verranno spostate all’interno dell’array.

 

Bubble sort: Come funziona?

Dando in pasto alla funzione Bubble Sort un’array disordinato o non, questa funzione, andra’ a confrontare ogni elemento dell’array con il suo elemento adiacente, e andra’ a scambiarli di posto  a seconda del loro peso.

Per esempio:

Prendiamo in considerazione l’array: 4 – 3 – 1 – 2.

Quello che fara’ la funzione all’array sara’ andare a confrontare il 4 con il 3 vedere che il 4 e’ maggiore di 3 e che quindi pesa di piu’ del 3, e spostera’ il valore maggiore a destra di quello minore, quindi dopo il primo passaggio avremo: 3 – 4 – 1 – 2.

Fatto questo ripetera’ l’operazione andando a confrontare il 4 con l 1 e poi il quatro con il 2 fino a ottenere l’array : 3 -1 – 2 – 4.

Fatto il primo passaggio, ci ritroveremo con l’elemento piu’ pesante dell’array, cioe’ nel nostro caso il 4 all’estremita’ destra dell’array, e potremo andare a ripetere l’operazione per il “sotto array” 3  -1 – 2 che ci e’ rimasto.

Per farvi capire meglio vi mostro questa gif animata presa da WikiPedia.

bubble-sort-example-300px

 

Bubble sort: In che modo trova l’elemento piu’ piccolo?

Non si puo’ esattamente dire che bubble sort vada a trovare l’elemento piu’ piccolo di un’array, va semplicemente a spostare gli elementi piu’ grandi nel fondo dell’array come bollicine che risalgono dal fondo del mare.

Ovviamente una volta messi tutti i valori piu’ grandi del valore piu’ piccolo al loro posto avremo trovato il valore piu’ piccolo dell’array.

Bubble sort: Implementiamolo in c per capire meglio

int main()
{
int array[10] = {3,7,9,2,1,4,5,6,8,0};
int n, c, d, swap;

for (c = 0 ; c < 10; c++)
{
for (d = 0 ; d < 10 - c - 1; d++)
{
if (array[d] > array[d+1]) /* For decreasing order use < */
{
swap       = array[d];
array[d]   = array[d+1];
array[d+1] = swap;
}
}
printf("\npassaggio numero %d\n",c);
for ( int i = 0 ; i < 10 ; i++ )
printf(" %d -", array[i]);
}

printf("\n\n Array ordinato:\n");

for ( c = 0 ; c < 10 ; c++ )
printf("%d -", array[c]);

return 0;
}

Se provate a eseguire questo codice, avrete un bubblesort funzionante che vi mostrera’ tutti i passaggi dell’ordinamento.
La variabile “swap” e’ una variabile d’appoggio che ci permette di scambiare i due valori confrontati nel caso ce ne sia bisogno.

 

 

alghoritmtable

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Visto che con i tutorial in c siamo arrivati a parlare di array, con questo nuovo tipo di tutorial, iniziero’ a farvi vedere i principali algoritmi di ordinamento partendo dal selection sort.

 

Selection Sort

Ingredienti

 

Selection sort: Cosa e’? A cosa serve?

Selection sort e’ un algoritmo che ci permette di ordinare gli elementi interni a un’array, opera sul posto e il suo tempo di esecuzione dipende unicamente dalla dimensione dell’array.

 

Selection sort: Come funziona?

Partendo da una sequenza completamente disordinata, selection sort andra’ a cercare l’elemento piu’ piccolo dell’array e lo spostera’ all’inizio di esso, per cosi iniziare a creare una sequenza ordinata.

esempio:

Abbiamo l’array composto da questi numeri: 4 – 3 – 1 – 2.

Selection sort andra’ a cercare l’elemento piu’ piccolo dell’array e lo spostera’ nella prima posizione, quindi l’array diventera’: 1 – 3 – 4 – 2.

A questo punto selection sort andra’ a ignorare la prima posizione, alla quale e’ gia’ stato assegnato il valore minore, e andra’ invece a lavorare nelle restanti ancora disordinate, quindi nel nostro secondo passaggio,

ignorera’: 1

e lavorera’ sull’array: 3 – 4 – 2

andando a cercare nuovamente su di esso l’elemento minore spostandolo all’inizio e

facendo diventare l’Array : 2 – 4 – 3

Il processo continuera’ a ripetersi fino a che l’array da “ignorare” perche’ gia ordinato sara’ pieno e l’array sul quale lavorare perche’ ancora disordinato sara’ vuoto.

 

Selection sort: In che modo trova l’elemento piu’ piccolo?

Come potete dal “balletto” soprastante, l algoritmo non fa altro che comparare tutti gli elementi con l’elemento ritenuto fino ad ora il piu’ piccolo.

Nel caso ne andasse a trovare uno minore quello andrebbe a prendere il suo posto.

 

Selection sort: Implementiamolo in c per capire meglio

#include ;
#include <stdbool.h>
#define MAX 4

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

void printline(int count) {
int i;

for(i = 0;i <count-1;i++) {
printf("=");
}

printf("=\n");
}

void display() {
int i;
printf("[");

// navigate through all items
for(i = 0;i<MAX;i++) {
printf("%d ", intArray[i]);
}

printf("]\n");
}

void selectionSort() {

int indexMin,i,j;

// loop through all numbers
for(i = 0; i < MAX-1; i++) {

// set current element as minimum
indexMin = i;

// check the element to be minimum
for(j = i+1;j<MAX;j++) {
if(intArray[j] < intArray[indexMin]) {
indexMin = j;
}
}

if(indexMin != i) {
printf("Items swapped: [ %d, %d ]\n" , intArray[i], intArray[indexMin]);

// swap the numbers
int temp = intArray[indexMin];
intArray[indexMin] = intArray[i];
intArray[i] = temp;
}

printf("Iteration %d#:",(i+1));
display();
}
}

main() {
printf("Input Array: ");
display();
printline(50);
selectionSort();
printf("Output Array: ");
display();
printline(50);
}

Se provate a eseguire questo codice, dove MAX sta a indicare il numero di elementi degli array e  1,2,3,4 sono gli elementi interni all’array, vedrete passo per passo i vari risultati dell’algoritmo.

Complessita’ dell’algortimo

Di certo questo non e’ l’algoritmo migliore per andare a ordinare un’array, difatti risulta essere molto lento rispetto ad altri, qui vi riporto il link con i vari paragoni http://bigocheatsheet.com/.

alghoritmtable

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Gli array

 

array

 

In questo tutorial andremo a conoscere gli array.

 

Ingredienti:

 

Che cos’e’ un array?

Possiamo vedere un’array come un’insieme di elementi dello stesso tipo dove ogni elemento e’ collegato a una locazione ben precisa.

Possiamo per esempio avere un insieme di 10 interi disposti nel seguente ordine { 0,1,2,3,4,5,6,7,8,9 } se volessimo rappresentarlo nel linguaggio c andremo a scrivere int numeri[10] = { 0,1,2,3,4,5,6,7,8,9 }.

Dove il numero 10 sta a indicare la grandezza degli array, mentre dentro le graffe abbiamo i vari elementi dell’array separati da una virgola.

Nel caso volessi recuperare il numero 0 dell’array mi basterebbe indicarne nell’indice la posizione ora, abbiamo messo lo 0 nella prima posizione del nostro array, quindi nel caso volessi andarlo a recuperare, mi basterebbe usare “numeri[0]”, ricordatevi che si inizia a contare sempre dallo 0 e non dall’1.

 

Implementiamo e stampiamo un’array

Avendo piu’ o meno capito cosa e’ un’array, ora proviamo a implementarlo, assegnargli degli elementi e andarlo a stampare sulla nostra console.

Come esempio vi propongo un codice base:
#include ;

int main()
{
int numeri[10] = {0,1,2,3,4,5,6,7,8,9};

for(int i=0; i<10;i++)
printf("%d",numeri[i]);

return 0;
}

In questo esempio, sfruttiamo un for per sfogliare e visitare tutto l'array in modo da andare a stampare tutti i suoi elementi interni.

 

Implementazione dinamica di un'array

Ora, stare ogni volta a scrivere ogni elemento interno dell'array, puo' diventare un'attivita' dispendiosa, sopratutto quando si va a lavorare con array di grandi dimensioni.

Per risolvere questo problema, possiamo inserire dinamicamente i valori all'interno del nostro array, ad esempio, nel nostro caso, dove abbiamo int numeri[10] = {0,1,2,3,4,5,6,7,8,9}, l'implementazione potrebbe avvenire in questo modo:

#include <stdio.h>

int main()
{
int numeri[10];

for(int i=0; i<10;i++){
numeri[i] = i;
printf("%d",numeri[i]);
}
return 0;
}

Andiamo a implementare i valori del nostro array direttamente nel nostro for sapendo che la funzione che collega i valori degli array agli indici e' f(x) = x dove f(x) rappresenta il valore interno, mentre la x rappresenta l'indice.

Ad esempio, volessimo cambiare e andare invece a salvare dentro il nostro array la tabellina del 2, avremo un f(x) = 2x, e quindi riscriveremo il codice semplicemente cosi:

#include <stdio.h>

int main()
{
int numeri[10];

for(int i=0; i<10;i++){
numeri[i] = 2*i;
printf("%d",numeri[i]);
}
return 0;
}

Ogni qual volta i valori interni al nostro array sono collegati in qualche modo (modo che e’ possibile riscrivere matematicamente), e’ bene utilizzare l implementazione dinamica, magari andando con un commento a dire cosa si sta andando a salvare per maggiore chiarezza.

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

In questo tutorial andremo a conoscere le funzioni andando a implementare una semplice funzione.

Possiamo vedere questo tutorial come un’infarinatura generale giusto per andare a comprendere la logica di quello che stiamo andando a creare.

 

Ingredienti:

 

Che cos’e’ una funzione?

Possiamo vedere una funzione, come un vero e proprio “programma” a parte che il nostro codice puo’ andare a sfruttare.

E’ uno strumento molto potente che ci consente di andare a riutilizzare linee di codice senza doverle riscriverle ogni vollta.

Possiamo quindi, andare a creare funzioni contenenti parti di linee di codice che sappiamo dover andare a utilizzare piu’ volte.

Le funzioni in c possono ritornare un valore tramite il comando “return”, nel caso questo sia assente non ritorneranno alcun valore e quindi non potranno essere immesse nel lato destro di una espressione.

 

Calcoliamo le tabelline tramite una funzione

Mettiamo caso di voler creare la matrice delle tabelline che vanno da 0 a 10, per crearla tramite una funzione, potremmo farlo tramite il seguente codice:
#include ;
void tabellina(int);

int main()
{
printf("\n");
printf("Tabellina\n");
for(int i = 0; i <= 10; i++)
tabellina(i);

return 0;
}

void tabellina(int a){

for(int i = 0; i <= 10; i++){
printf("%d ",a*i);
}
printf("\n");
return;
}

Per prima cosa, in alto andiamo a dire cosa ci restituira’ la nostra funzione andandola a dichiarare, nel nostro caso sara’ la funzione stessa a restituirci i risultati delle varie tabelline e quindi non servira’ che ci restituisca niente possiamo quindi andare a dichiarare la nostra funzione con un void “void tabellina” e prendera’ in pasto un intero “dobbiamo dirgli di cosa deve calcolare la tabellina” quindi “void tabellina(int)”.

Una volta dichiarata la nostra funzione dobbiamo andarla a implementare e dirgli cosa deve fare

void tabellina(int a){

for(int i = 0; i <= 10; i++){
printf(“%d “,a*i);
}
printf(“\n”);
return;
}

una volta implementata dobbiamo richiamarla quando ci serve andandogli a passare i giusti valori

    for(int i = 0; i <= 10; i++)
tabellina(i);

Andando a eseguire il codice vi ritroverete con la matrice delle tabelline che vanno ad 0 a 10

 

 

Questo e’ stato un’esempio un po’ blando e carente di definizioni, ma si impara meglio con la pratica, quindi vi invito a provare a implementare questo codice, e altri semplici codici, per allenarvi con le funzioni e i vari concetti visti fino ad ora.

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Con questo Tutorial Andremo a migliorare l’utilizzo della memoria da parte della nostra applicazione tramite il disposing degli elementi e l’utilizzo del garbage collector.

 

Ingredienti:

 

Disposing Objects

Abbiamo gia visto, in uno degli scorsi tutorial, come andare a disporre i vari oggetti del nostro programma.

Ora, avendo aggiunto altri elementi come nuove texture, e nuovi loop di game (a ogni loop le texture vengono ricreate), dobbiamo andare a fare un po’ di pulizie.

 

Disposing degli ostacoli

Andiamo nella nostra classe “ostacoli” e aggiungiamo una funzione di disposing, per farsi che ogni tubo venga eliminato correttamente alla chiusura di uno stato di gioco.

 

public void dispose(){
    TuboSuperiore.dispose();
    TuboInferiore.dispose();
}

Questa funzione la andremo a richiamare quando faremo il dispose di un nostro stato di gioco.

 

Disposing del protagonista

Facciamo la stessa cosa per il protagonista, entriamo nella classe “Bird” e andiamo a creare un metodo dispose dove ci liberiamo della texture del giocatore.

public void dispose(){
    texture.dispose();
}

Anche questo metodo lo andremo a richiamare quando andremo a fare il dispose del nostro stato di gioco.

 

Disposing dello stato di gioco

Ora non ci rimane che creare il metodo dispose nello stato di gioco che andremo a richiamare ogni qualvolta ci sara’ un cambio di stato.

Dobbiamo ricordarci di andare a fare il dispose di tutti gli sotacoli presenti nel gioco, quindi sara’ necessario creare un ciclo.

public void dispose() {
    sfondo.dispose();
    bird.dispose();
    for(Ostacoli ostacolo : tubi){
        ostacolo.dispose();
    }
    System.gc();

}

Il Garbage Collector

Come vedete nel dispose del nostro stato di gioco, sono andato ad aggiungere anche la stringa “System.gc()”, questa stringa, andra’ a richiamare il garbage collector e pulira’ la nostra applicazione da eventuali risorse inutilizzate.

 

Disposing GameState Manager

Una volta settati i vari dispose, dobbiamo andare a ricordare al nostro programma, che ogni volta che fa un “pop” di uno stato, deve anche lanciare il dispose di esso.

Per fare cio’ andate nella classe gamestatemanager  e aggiungete un .dispose dopo il pop:

public void pop(){
    stati.pop().dispose();
}

public void set(Stato stato){
    stati.pop().dispose();
    stati.push(stato);
}

Se ora provate a monitorare l utilizzo di memoria dell’applicazione, vedrete che e’ diventata stabile senza andare a aumentare a ogni ciclo di gioco.

 

I file aggiornati fino a questo tutorial : game1

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Con questo Tutorial Andremo a implementare la collision detection.

 

Ingredienti:

 

Le collisioni

Per ora, il nostro gioco, risulta al quanto facile, in quanto possiamo passare attraverso i tubi senza scontrarci contro di essi.

Ovviamente noi non vogliamo cio’, vogliamo vedere la terza legge di newton venga rispettata, e che i nostri sprite si comportino come dei corpi rigidi.

 

I rettangoli

Per fare cio’ possiamo disegnare intorno ai nostri sprite un “rettangolo” e andare a controllare quando due “rettangoli” vanno a intersecarsi, nel caso avviene un’intersezione tra i due rettangoli, allora abbiamo una collisione.

Iniziamo quindi con l’aggiungere nella classe ostacoli, due rettangoli, uno per il tubo superiore e uno per il tubo inferiore.

public class Ostacoli{

    private Texture TuboSuperiore, TuboInferiore;
    private  Vector2 posizioneSuperiore, posizioneInferiore;
    private Random rand;
    private Rectangle RettangoloTuboSuperiore, RettangoloTuboInferiore;


Quindi andiamo a settarli nel nostro costruttore, dandogli una dimensione e una posizione le quali, dovranno corrispondere alle dimensioni e alle posizioni dei nostri rettangoli.

 

public Ostacoli(int x) {
    TuboSuperiore = new Texture("TuboSuperiore.png");
    TuboInferiore = new Texture("TuboInferiore.png");
    rand = new Random();

    posizioneSuperiore = new Vector2(x, rand.nextInt(150)+ 100 + 110);
    posizioneInferiore = new Vector2(x, posizioneSuperiore.y - 150 - TuboInferiore.getHeight());

    rettangoloTuboSuperiore = new Rectangle(posizioneSuperiore.x,posizioneSuperiore.y,getTuboSuperiore().getWidth(),getTuboSuperiore().getHeight());
    rettangoloTuboInferiore = new Rectangle(posizioneInferiore.x,posizioneInferiore.y,getTuboInferiore().getWidth(),getTuboInferiore().getHeight());
    
}

Impostati i rettangoli, dobbiamo ricordarci di riposizionarli ogni volta che si riposiziona un tubo, quindi andremo a riposizionarli nella funzione riposizionamento.

 

public void riposiziona(float x){
    posizioneSuperiore.set(x, rand.nextInt(150)+ 100 + 110);
    posizioneInferiore.set(x, posizioneSuperiore.y - 150 - TuboInferiore.getHeight());
    rettangoloTuboSuperiore.setPosition(posizioneSuperiore.x,posizioneSuperiore.y);
    rettangoloTuboInferiore.setPosition(posizioneInferiore.x,posizioneInferiore.y);

}

Ora andiamo a creare una funzione, che ci servira’ a capire quando i Rettangoli dei tubi, andranno a intersecarsi con il rettangolo ( che andremo successivamente a creare ) del nostro giocatore.

public boolean collisionDetection(Rectangle giocatore){
    return giocatore.overlaps(rettangoloTuboSuperiore) || giocatore.overlaps(rettangoloTuboInferiore);
}

Ora possiamo uscire dalla classe degli ostacoli, e andare a creare il rettangolo per il nostro giocatore, andiamo quindi nella classe “Bird”.
Andiamo a fare quindi la stessa cosa implementando un rettangolo per il giocatore e posizionandolo e dimensionandolo adeguatamente.

public static final int GRAVITY = -10;
private static final int VELOCITA_ORIZZONTALE = 120;

private Vector2 velocita;
private Rectangle rettangoloGiocatore;

public Bird(int x, int y) {
    super(x, y);
    texture = new Texture("flappybird.png");
    velocita = new Vector2(0,0);
    rettangoloGiocatore = new Rectangle(x,y,texture.getWidth(),texture.getHeight());
}

E ricordiamoci di aggiornare la posizione del rettangolo mentre il giocatore si muove:

public void update(float dt) {
    if(this.posizione.y >= 0) {
        velocita.add(0, GRAVITY);
        velocita.scl(dt);
        posizione.add(VELOCITA_ORIZZONTALE * dt, velocita.y);
        velocita.scl(1 / dt);
    }
    if(this.posizione.y < 0){
        this.posizione.y = 0;
    }
    rettangoloGiocatore.setPosition(posizione.x,posizione.y);
}

Ora, non ci rimane che andare a creare una funzione che vada a restituire il rettangolo del nostro giocatore, quindi:

public Rectangle getRettangoloGiocatore(){
    return rettangoloGiocatore;
}

Controllando l’avvenuta colllisione

Ora dobbiamo controllare se durante lo stato di gioco avvengono delle collisioni tra i rettangoli, dobbiamo quindi andare nella nostra classe stato di gioco e controllare a ogni ciclo se e’ avvenuta una collisione, andiamo quindi a lavorare nell update nel ciclo che gia’ abbiamo creato.

public void update(float deltaTime) {
    InputManager();
    bird.update(deltaTime);

    camera.position.x = bird.getPosizione().x + 50;

    for(Ostacoli ostacolo : tubi){
        if(camera.position.x - (camera.viewportWidth/2) > ostacolo.getPosizioneSuperiore().x + ostacolo.getTuboSuperiore().getWidth()){
            ostacolo.riposiziona(ostacolo.getPosizioneSuperiore().x + ((55 + SPAZIO))*NUMERO_TUBI);
        }
        if (ostacolo.collisionDetection(bird.getRettangoloGiocatore())){
            gsm.set(new StatoMenu());
        }
    }

    camera.update();
}

Una volta controllato con quell’if la collisione, io ho scelto che ad avvenuta collisione il gioco sarebbe tornato nello stato del gioco resettandolo, ma successivamente andremo a creare uno stato gameOver.

yay

 

Nel prossimo tutorial andremo a disporre tutti gli elementi grafici in modo che non rappresentino un peso a ogni restart.

 

I file aggiornati fino a questo momento: game

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

In questo tutorial andremo a vedere cosa e’ e come utilizzare un costruttore condizionale e cosa e’ una condizione.

 

Ingredienti:

 

Che cosa e’ una condizione?

Una condizione e’ un qualcosa che riesce a far compiere una scelta al nostro programma “se questa condizione e’ verificata allora fai questo altrimenti fai quest’altro o semplicemente non fare niente”.

E’ una definizione un po’ blanda, ma andando avanti con gli esempi, il concetto dovrebbe entrarvi in testa piu’ facilmente.

Partiamo con degli esempi che non riguardano il linguaggio di programmazione ma vicende normali.

Facciamo finta di essere degli studenti e di dire “Se riesco a prendere 10 allo scritto stasera mi rilasso e mi premio con una pizza con gli amici”, qui abbiamo la nostra condizione ” se voto == 10 ” e la nostra azione che andremo a eseguire se e’ stata soddisfatta “prendo una pizza con gli amici e mi rilasso”. Quindi se vogliamo pensare a un modo per scriverlo, incominciando ad avvicinarci a un linguaggio di programmazione potremmo fare ” se ( voto == 10) allora stasera = pizza + riposo;

Capito questo esempio iniiziamo a vedere esattamente come scriverlo in c

 

L’if

L’if (in italiano se) imposta esattamente la nostra condizione si costruisce in questo modo :

if(condizione){ avvenimenti da eseguire se la condizione e’ vera }

Passiamo direttamente a un’esempio pratico per capire cosa succede
#include <stdio.h>

int main()
{
int a;
a = 2;
if(a == 2){
printf("la a vale 2!");
}
}

Se provate a scrivere nel compilatore questo stralcio di codice, quello che fate, e’ andare a controllare se il valore della nostra a e’ uguale a 2 e nel caso lo e’, allora andremo a stampare ” la a vale 2!” altrimenti non faremo niente

 

else

l’else (in italiano altrimenti), possiamo utilizzarlo in presenza di un’if per dirgli se la condizione dell’if non e’ vera allora fai quest’altra cosa, si struttura cosi:

if(condizione){cose che succedono se la condizione e’ verificata}

else{cose che succedono se la condizione non e’ verificata).

Riprendendo il programma di prima, andiamo a dirgli di stampare che la a non vale due nel caso abbia un valore diverso da 2.
#include <stdio.h>
int main()
{
int a;
a = 2;
if(a == 2){
printf("la a vale 2!");
}
else{
printf("la a non vale 2");
}
}

In questo caso, dentro l’else, andremo a dire al programma di stampare  “la a non vale 2” nel caso non valga 2.

 

else if

Se vogliamo scendere piu’ nello specifico, cioe’, se abbiamo la nostra condizione a==2 ma la nostra a vale 3, possiamo andare a specificare al nostro programma che se la vale 3 deve stampare “la a vale 3!” e che nel caso non valga ne 2 ne 3 stampi “la a non vale ne due ne tre”.

Per fare cio’ procediamo scrivendo questo codice:
int main()
{
int a;
a = 4;
if(a == 2){
printf("la a vale 2!");
}
else if (a == 3){
printf("la a vale 3");
}

else{
printf(“la a non vale ne 2 ne 3”);
}
return 0;
}
Questo codice ci stampera’ 2 se la a vale 2, 3 se la a vale 3, “la a non vale ne 2 ne 3” se la a non vale ne due ne tre.

Per testarlo vi basta cambiare l assegnamento alla a, in questo caso ad a assegnamo 4, di conseguenza il nostro programma entrera’ nell’ultimo else.

 

Switch

Lo switch,  possiamo utilizzarlo nel caso dobbiamo andare a specificare cosa succede in particolari valori di a.

Sara’ strutturato nel seguente modo:

switch(“variabile”) { case(“valore della variabile”) “cosa succede se il valore corrisponde” break }

Vediamo velocemente un esempio:
int main()
{
int a;
a = 4;
switch(a){
case(1):
printf("la a vale 1");
break;
case(2):
printf("la a vale 2");
break;
case(3):
printf("la a vale 3");
break;
case(4):
printf("la a vale 4");
break;
default:
printf("la a non vale ne 1 ne 2 ne 3 ne 4");
break;
}
return 0;
}

Alla fine, nel default, andate a scrivere quello che succede se la variabile non ha nessun valore tra quelli analizzati nei case.

Per concludere, vi segnalo un’altro ottimo compilatore online, visto che quello di tutorial point a volte puo’ dare dei problemi (o almeno a me a volte li sta dando non riuscendo a caricare il compilatore).

Nel caso potete usare QUESTO

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Con questo Tutorial Andremo volando tra gli ostacoli di gioco.

 

Ingredienti:

 

Aumentiamo il numero di ostacoli!

Nell’ultimo tutorial, siamo andati a creare la classe ostacoli, per andare a rappresentare i vari tubi nel gioco.

Ora prima di iniziare a far volare il nostro protagonista tra di essi, dovremo crearne tanti in sequenza, e fare in modo, che quelli superati e usciti dalla schermo, si riposizionino davanti, cosi da andare a creare una sequenza infinita di ostacoli.

Iniziamo con il creare la funzione “riposiziona” nella classe degli ostacoli.

 

La funzione riposiziona

Tutto quello che dovra’ fare questa funzione, sara’ riposizionare i nostri in una nuova X, di conseguenza, all’interno della funzione, non faremo altro che settare la nuova posizione.

public void riposiziona(float x){
    posizioneSuperiore.set(x, rand.nextInt(150)+ 100 + 110);
    posizioneInferiore.set(x, posizioneSuperiore.y - 150 - TuboInferiore.getHeight());

}

 

Un po’ di spazio tra i tubi

Creata la funzione che ci permette di riposizionare i tubi una volta usciti dallo schermo, ora andiamo a creare due costanti che ci serviranno in futuro.

Una costante ci rappresentera’ lo spazio che vogliamo lasciare tra due coppie di tubi, mentre un’altra costante ci rappresentera’ il numero di coppie di tubi che vogliamo avere nel nostro gioco.

Andiamo quindi nella classe stato di gioco e aggiungiamo queste due stringhe:

public class StatoGioco extends Stato {

    private static final int SPAZIO = 100;
    private static final int NUMERO_TUBI = 6;

 

Un’array di ostacoli

Ora, finalmente possiamo andare ad aumentare il numero di ostacoli presenti nel gioco.

Per fare cio’ creiamo all’interno del nostro gioco un’array di ostacoli e chiamiamolo tubi.

private Array<Ostacoli> tubi;

E andiamo a crearli dentro il costruttore sfruttando la costante creata prima per il loop.

ostacoli = new Ostacoli(150);

tubi = new Array<Ostacoli>();
for(int i = 0; i < NUMERO_TUBI;i++){
    tubi.add(new Ostacoli(i * (SPAZIO + 55 )));
}

Fatto cio’, possiamo eliminare il vecchio tubo creato nella lezione precedente in quanto ora ne abbiamo un’intero array.

 

Riposizioniamo i tubi

Ora, dentro la classe dello stato di gioco, dentro la funzione update, andiamo a controllare quando un tubo esce fuori dallo schermo, e nel caso accada, andiamo a riposizionarlo.

Quindi andiamo a scrivere:

for(Ostacoli ostacolo : tubi){
    if(camera.position.x - (camera.viewportWidth/2) > ostacolo.getPosizioneSuperiore().x + ostacolo.getTuboSuperiore().getWidth()){
        ostacolo.riposiziona(ostacolo.getPosizioneSuperiore().x + ((55 + SPAZIO))*NUMERO_TUBI);
    }
}

Ci sono molte operazioni in questo stralcio di codice, ma sostanzialmente, quello che andiamo a fare, e’ spostare il nostro tubo appena uscito fuori dallo schermo, dopo l’ultimo tubo che deve ancora arrivare, con la propria spaziatura, in modo tale da andare a creare un loop infinito di tubi.

 

Renderizziamo i vari tubi

Nella funzione render, stiamo ancora renderizzando solo un tubo, quello vecchio che abbiamo rimosso, ora dobbiamo levarlo e andare invece a renderizzare tutti gli altri tubi (in ogni caso esattamente come avevamo fatto per quello).

La nostra nuova funzione di render sara’ quindi cosi:

 

public void render(SpriteBatch spriteBatch) {
    spriteBatch.setProjectionMatrix(camera.combined);
    spriteBatch.begin();
    spriteBatch.draw(sfondo,camera.position.x - (camera.viewportWidth / 2),0,FlappyBirdsGame.LARGHEZZA / 2,FlappyBirdsGame.ALTEZZA / 2);
    spriteBatch.draw(bird.getTexture(),bird.getPosizione().x,bird.getPosizione().y);
    for(Ostacoli ostacolo : tubi) {
        spriteBatch.draw(ostacolo.getTuboSuperiore(), ostacolo.getPosizioneSuperiore().x, ostacolo.getPosizioneSuperiore().y);
        spriteBatch.draw(ostacolo.getTuboInferiore(), ostacolo.getPosizioneInferiore().x, ostacolo.getPosizioneInferiore().y);
    }
    spriteBatch.end();
}

 

Muoviamoci nell’asse delle x

Ora andiamo nella classe “bird” e diamo una velocita’ orizzontale al nostro protagonista.

Andiamo quindi a settare una velocita’ orizzontale costante:

public class Bird extends Sprite {

    public static final int GRAVITY = -10;
    private static final int VELOCITA_ORIZZONTALE = 120;

E all’interno di update, sempre nella classe “bird” modifichiamo la stringa posizione.add e aggiungiamoci la velocita’ orizzontale.

public void update(float dt) {
    if(this.posizione.y >= 0) {
        velocita.add(0, GRAVITY);
        velocita.scl(dt);
        posizione.add(VELOCITA_ORIZZONTALE * dt, velocita.y);
        velocita.scl(1 / dt);
    }

Fatto cio’ possiamo tornare nel nostro stato di gioco, perche’ quello che dovremo fare, sara’ tenere l’uccello al centro dello schermo, e questo lo faremo grazie alla camera.

In update andiamo quindi a cambiare la posizione della nostra camera:

public void update(float deltaTime) {
    InputManager();
    bird.update(deltaTime);

    camera.position.x = bird.getPosizione().x + 50;

    for(Ostacoli ostacolo : tubi){
        if(camera.position.x - (camera.viewportWidth/2) > ostacolo.getPosizioneSuperiore().x + ostacolo.getTuboSuperiore().getWidth()){
            ostacolo.riposiziona(ostacolo.getPosizioneSuperiore().x + ((55 + SPAZIO))*NUMERO_TUBI);
        }
    }
camera.update();
}

yay

 

 

 

Ora, avremo che la camera seguira il nostro protagonista.

PS: non scordatevi il camera.update alla fine, dobbiamo far sapere al nostro programma che la posizione della camera e’ stata cambiata.

 

Fatto cio’ possiamo andare testare il programma e goderci il risultato, finalmente si riesce a vedere bene la forma del gioco 🙂

 

 

 

 

 

File creati durante questo tutorial: game

 

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+

Nello scorso tutorial, vi avevo lasciato un’esempio nel quale andavo a utilizzare dei cicli for.
In questo nuovo tutorial, andremo a capire cosa sono questi cicli e come possiamo utilizzarli.

 

Ingredienti:

 

Che cosa e’ un ciclo?

I cicli in programmazione, rappresentano il ripetersi di un’evento o una serie di eventi da noi specificati fino a un dato momento sempre da noi specificato.

Possiamo pensarli come una cosa del genere :

Creazione del ciclo, Controllo della condizione del ciclo(vera) -> Esecuzione degli eventi interni al ciclo -> Controllo della condizione del ciclo(falsa) -> Uscita dal ciclo.

Solitamente, all’interno dell’esecuzione degli eventi interni al ciclo, troveremo una qualche variabile, che andra’ prima o poi a rendere la condizione del ciclo falsa, e quindi di darci la possibilita’ di uscire dal ciclo senza rimanere bloccati al suo interno.

 

Il ciclo While

In c, solitamente anche in molti altri diversi linguaggi di programmazione,  possiamo trovare quanto schematizzato li sopra, nel while (in italiano per l”appunto ciclo).

Il while ci si presenta cosi,

while(condizione){ istruzioni interne al while }

E possiamo leggerlo nel seguente modo: while(finche’) questa condizione e’ vera, esegui le istruzioni interne al while.

Ora, vi faccio un’esempio pratico di utilizzo, mettiamo che volessi stampare a schermo la tabellina del 2, allora in codice dovrei scrivere:
#include <stdio.h>

int main()
{
int a,i;
i=0;
printf("\n\n");
while(i<=10){
a = 2;
a *= i;
i++;
printf("%d - ",a);
}
return 0;
}

In questo caso, l’espressione while, possiamo leggerla in questo modo: Finche, la i e’ minore uguale al valore 10, assegna alla variabile a il valore due, assegna ad a il risultato del’operazione “a*i”, incrementa i di un’unita’, stampa a, ricontrolla la condizione.

Quindi, avremo che a ogni ciclo, il valore della nostra i si aumentera’ di una unita’, e quando sara’ arrivata ad avere un valore superiore al 10, riusciremo ad uscire dal ciclo e andremo a eseguire “return 0” andando a chiudere il programma.

Questo e’ l’output di quel programma:

base2

 

Il ciclo Do While

Molto simile al ciclo while ma al posto di leggerlo “finche questa condizione e’ vera, fai questo”, lo andremo a leggere come “fai questo finche questa condizione e’ vera”, questo ci assicurera’ di eseguire le istruzioni interne al ciclo almeno una volta.

La sua struttura e’ questa:  do{ istruzioni interne } while ( condizione ).

Quindi, ripeto, si leggera’: fai(do) queste istruzioni interne finche'(while) questa condizione e’ vera.

Possiamo riscrivere lo stesso programma di prima, in questo modo:
#include <stdio.h>

int main()
{
int a,i;
i=0;
printf("\n\n");
do{
a = 2;
a *= i;
i++;
printf("%d - ",a);
}while(i<=10);

return 0;
}

E andremo a ottenere esattamente lo stesso output.

 

Il ciclo for

Solitamente anche se lascia meno liberta, questo ciclo risulta essere il piu’ usato, ed e’ sicuramente il piu’ ordinato tra i tre.

La sua struttura si presenta in questo modo for( assegnazione variabile; condizione di ciclo; evoluzione variabile ){ istruzioni interne al ciclo }

Dove andiamo a spostare tutte le stringhe riguardanti la variabile associata alla condizione del ciclo, all’interno dei parametri del for in questo modo: for( int i = 0; i < 10; i++)

Il primo parametro, l inizializzazione della variabile per la condizione con il suo settaggio al valore 0, verra’ eseguita soltanto una volta, mentre il controllo della condizione( se vera o falsa ) e in questo caso l’incremento della variabile i, verranno eseguiti all’inizio di ogni ciclo.

Andiamo nuovamente a riscrivere il programma della tabellina del 2:
#include <stdio.h>

int main()
{
int a;
printf("\n\n");

for(int i = 0; i <= 10;i++){
a = 2;
a *= i;
printf("%d - ",a);
}

return 0;
}

Come vedete, andiamo a risparmiarci un po’ di righe di codice, riuscendo a rendere tutto piu’ bello visivamente e leggibile.

Nel prossimo tutorial parleremo meglio delle condizioni.

 

 

 

Saluti dal vostro nabbo Developer

Marco Tamagno

Facebook

Google+