Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
GiocoDel15 - nanosleep... chi era costui?

GiocoDel15

Sommario | Admin | Forum | Bugs | Todo | Files

Avatar
AldoBaldo (Member)
Guru


Messaggi: 614
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 21:55
Domenica, 24/01/2021
La semicitazione dal Manzoni è per chiedere lumi sulla funzione nanosleep(), che il compilatore mi segnala come sconosciuta con "C:\Users\Cicci\Desktop\GiocoDel15_CODEBLOCKS\main.c|65|warning: implicit declaration of function 'nanosleep' [-Wimplicit-function-declaration]|". Addirittura, un errore riferito alla variabile ts (C:\Users\Cicci\Desktop\GiocoDel15_CODEBLOCKS\main.c|43|error: storage size of 'ts' isn't known|) blocca la compilazione del programma.

A quanto pare si tratta di funzioni e tipi dati non standard.
Da una ricerca molto superficiale, parrebbe trattarsi di materiale "esclusivo" di linux.

Soluzioni?


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 838
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 10:49
Lunedì, 25/01/2021
nanosleep è implementato in time.h
l'ho usato perché Sleep, mi viene segnalato come deprecato e che è stato sostituito da nanosleep (lavora in nanosecondi), dopo essermi documentato sulle modalità d'uso, l'ho implementato, funziona perfettamente con il mio GCC sotto Win.
Il programma non funziona sotto Linux perché usa windows.h, se qualche linuxxiano può dare info su come si potrebbe fare il porting del programma, ne sarei felicissimo.

Di seguito la routine int main() con Sleep al posto di nanosleep:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <windows.h>
  5. #include <ctype.h>
  6.  
  7. int main()
  8. {
  9.     SetConsoleTitle(Titolo);
  10.     POINT pCoor;
  11.     HWND hwnd=0;
  12.  
  13.     //attende la creazione della finestra per prelevare hwnd
  14.     while (hwnd==0)
  15.         hwnd=FindWindow(NULL, Titolo); // handle della finestra
  16.     //------------------------------------------------------
  17.  
  18.     HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE); // handle del processo
  19.  
  20.     MenuScelta();
  21.     GenSequenza(); // sequenza ordinata
  22.     Schermo(console); // prima visualizzazione schema
  23.  
  24.     while(1){ // loop infinito mouse
  25.         Sleep(50); // lascia la CPU libera, limita i cicli in 1000/50=20 al secondo
  26.         if((GetKeyState(GiocoDel15.MouseButton) & 0x8000) != 0){ // bottone mouse
  27.             GetCursorPos(&pCoor); // coordinate assolute cursore
  28.             ScreenToClient(hwnd, &pCoor); // coordinate relative cursore
  29.             TrovaCasella(pCoor.x, pCoor.y, console); // TrovaCasella modifica la struct GiocoDel15
  30.             if (GiocoDel15.riga!=0 && GiocoDel15.colonna!=0){ // click dentro lo schema
  31.                 for (int i=0; i<4; i++){ // controllo in 4 direzioni predefinite in aControllo
  32.                    if (GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]==0){ // è la casella vuota, swap
  33.                         GiocoDel15.iSequenza[aControllo[GiocoDel15.casella][i]]=GiocoDel15.iSequenza[GiocoDel15.casella]; // scrivo il valore della casella cliccata nella casella vuota
  34.                         GiocoDel15.iSequenza[GiocoDel15.casella]=0; // nella casella cliccata metto zero, lo swap è completo
  35.                         GiocoDel15.mosse++; // incremento le mosse
  36.                         /* per test
  37.                         printf("\n\nCasella = %d", GiocoDel15.casella+1);
  38.                         printf(" Vuota = %d", aControllo[GiocoDel15.casella][i]+1);*/
  39.                         break;
  40.                    }
  41.                 }
  42.                 int risolto=Schermo(console); // aggiorno lo schermo, la funzione restituisce se c'è soluzione
  43.                 printf("\n\n  ");
  44.                 if (risolto==1){
  45.                     SetConsoleTextAttribute(console, 14|0); // giallo nero
  46.                     printf(" Risolto,");
  47.                     SetConsoleTextAttribute(console, 10|0); // verde nero
  48.                 }
  49.                 printf(" mosse = %d",GiocoDel15.mosse); // visualizzo le mosse
  50.             }
  51.         Sleep(200); // Ritardo evita doppio click, al massimo vengono rilevati 5 click al secondo
  52.         }
  53.     }
  54. }


Ho inserito gli include per "forzare" il riconoscimento della formattazione C

Ultima modifica effettuata da Carlo il 27/01/2021 alle 15:44


in programmazione tutto è permesso
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 614
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 13:48
Lunedì, 25/01/2021
Avevo immaginato che fosse "parente" di Sleep(), però nanosleep() non mi risulta in time.h
Magari perché è richiesta una versione più recente del compilatore?
Oppure perché non è strettamente standard ed esiste solo in alcune implementazioni?
Una funzione con una risoluzione del genere è senz'altro intrigante...

Avevo già provato io stesso a sostituire nanosleep() con Sleep() (tra l'altro, praticamente con gli stessi valori che suggerisci tu ora). Il programma vien compilato correttamente, il lancio riesce e il primo menù, quello nel quale viene chiesto di scegliere la versione del sistema operativo, risulta funzionante. La successiva schermata si apre con tutte le componenti grafiche apparentemente in ordine, però poi i comandi non "lavorano" come dovrebbero (nessuna area risulta sensibile al click).

Al solito, viviamo in un Mistero Insondabile.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Carlo (Member)
Guru


Messaggi: 838
Iscritto: 29/01/2018

Segnala al moderatore
Postato alle 14:59
Lunedì, 25/01/2021
Nel mio time.h c'è, sarà una questione di versioni.

Il codice l'ho provato sulla console di Win7 32bit e di Win10 64bit.
nella routine trovacasella c'è un printf remmato che mostra le variabili modificate dopo un click.

Se trovacaselle non viene eseguita il click del mouse nel while(1) non è stato intercettato:
Codice sorgente - presumibilmente Plain Text

  1. if((GetKeyState(GiocoDel15.MouseButton) & 0x8000) != 0){ // bottone mouse


GiocoDel15.MouseButton  1 = tasto sinistro (win7), 2 = tasto destro (win10)

Se trovacaselle viene eseguita devi verificare le coordinate restituite se cadono nel range di valori da me estrapolati.

Questo è il primo codice che ho scritto per verificare le coordinate del mouse nella finestra console.
Codice sorgente - presumibilmente C++

  1. #include <windows.h>
  2.  
  3. const char Titolo[] = "TEST coordinate";
  4.  
  5. int main(){
  6.     SetConsoleTitle(Titolo);
  7.     HWND hwnd = 0;
  8.     //attende la creazione della finestra
  9.     while (hwnd == 0)
  10.         hwnd = FindWindow(NULL, Titolo);
  11.     //-----------------------------------
  12.  
  13.     POINT aCoor;
  14.  
  15.     while(1){
  16.         system ("cls");
  17.         GetCursorPos(&aCoor);
  18.         ScreenToClient(hwnd,&aCoor); // se eliminato le coordinate sono del desktop
  19.         printf( "Posizione x = %d  y = %d", aCoor.x, aCoor.y);
  20.     }
  21.  
  22.     return 0;
  23. }



senza Sleep il loop viene eseguito milioni di volte al secondo, può causare il blocco della console se si esce con la x sulla console.

EDIT:
scusa se scrivo una cosa scontata, ma è una possibilità del malfunzionamento:
Sleep(200), attende 200 ms.
sleep(200), attende 200 secondi, più di tre minuti...

Ultima modifica effettuata da Carlo il 25/01/2021 alle 16:19


in programmazione tutto è permesso
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6130
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 7:33
Mercoledì, 27/01/2021
Con windows si usano i multimedia timer..

Comunque ecco l'implementazione di mingw in windows della nanosleep

https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64- ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti (uno dei padri fondatori del moderno Calcolo delle probabilità) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote