📄 mouse_sim.c
字号:
Count = EvaluatePositions(Org, Positions, &Cheese); if(Count == 0) return; p = Org; if(IsSet(pMouse->Status, CHEESE_FOUND)) {//Prendre le fromage Reset(pMouse->Status, CHEESE_FOUND); p = Cheese; } else {//Choisir une position au hasard p = ChoosePosition(pMouse, Positions, Count); } if(AffectMovement(Org, p) == FALSE) return; //Deplacer la souris pMap[Org.X + (Org.Y * MAP_X)] = NULL; pMap[p.X + (p.Y * MAP_X)] = pMouse; pMouse->P = p; //Mettre a jour l'affichage DrawPixel(Org.X, Org.Y, SOS_X86_VIDEO_FG_BLACK); DrawPixel(p.X, p.Y, pMouse->Color); sos_x86_videomem_printf( 23,0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Souris = %d; Fromages = %d; Obstacles = %d ", MouseCount, CheeseCount, ObstacleCount); //Mettre a jour les coordonnees *P = p;}//*****************************************************************************// But de la fonction : Choisir un mouvement// Entree :// pMouse : Pointeur sur la souris// Positions : Tableau de position possible// Count :Nombre de positions valides// Sortie : Aucune// Parametre retourne : Position choisie//*****************************************************************************static Point_t ChoosePosition(Element_t * pMouse, int Positions[], int Count){ int I, J; Point_t p; for(J = 0; J < Count; J++) {//Chercher dans le tableau si cette position est disponible I = Positions[J]; if(I == pMouse->Way) {//Poursuivre ce sens d'avance p = pMouse->P; switch(I) { case 0: p.Y++; break; case 1: p.X++; p.Y++; break; case 2: p.X++; break; case 3: p.Y--; p.X++; break; case 4: p.Y--; break; case 5: p.Y--; p.X--; break; case 6: p.X--; break; case 7: p.X--; p.Y++; break; } return p; } } J = random() % Count; I = Positions[J]; if(((I + 4) % 8) == pMouse->Way) {//Eviter le sens inverse J = (J + 1) % Count; I = Positions[J]; } p = pMouse->P; switch(I) {//Repere le deplacement case 0: p.Y++; break; case 1: p.X++; p.Y++; break; case 2: p.X++; break; case 3: p.Y--; p.X++; break; case 4: p.Y--; break; case 5: p.Y--; p.X--; break; case 6: p.X--; break; case 7: p.X--; p.Y++; break; } pMouse->Way = I;//Memoriser la direction selectionnee return p;}//*****************************************************************************// But de la fonction : Evaluer les positions possibles et les memoriser dans// un tableau de positions si aucun fromage n'a ete detecte. Si du fromage a// ete detecte, il sera selectionne en premier. La presence d'un fromage est// indiquee par le drapeau CHEESE_FOUND// Entree :// Org : Position de la souris// Sorties :// Positions : Tableau de positions valides// Cheese : Position du fromage// Parametre retourne : Nombre de positions valides//*****************************************************************************static int EvaluatePositions(Point_t Org, int Positions[], Point_t * Cheese){ int I; int Count = 0; Point_t p; Point_t CheesePos; for(I = 0; I < 8; I++) {//Explorer toute les directions p = Org; switch(I) {//Repere le deplacement case 0: p.Y++; break; case 1: p.X++; p.Y++; break; case 2: p.X++; break; case 3: p.Y--; p.X++; break; case 4: p.Y--; break; case 5: p.Y--; p.X--; break; case 6: p.X--; break; case 7: p.X--; p.Y++; break; } //Tester la collision if(IsCollision(Org, p, &CheesePos) == FALSE) {//La souris n'a rencontre aucun obstacle Positions[Count] = I; Count++; } } *Cheese = CheesePos; return Count;}//*****************************************************************************// But de la fonction : Affecter un mouvement a la souris// Entrees :// Org : Coordonnees de la souris// p : Coordonnees voulu par la souris// Parametre retourne : TRUE si le mouvement a eu lieu, FALSE sinon//*****************************************************************************static sos_bool_t AffectMovement(Point_t Org, Point_t p){ Element_t * pMouse = pMap[Org.X + (Org.Y * MAP_X)]; Element_t * pElement; pElement = pMap[p.X + (p.Y * MAP_X)]; //La place est libre if(pElement == NULL) return TRUE;//Autoriser le mouvement switch(pElement->Type) { case CHEESE: // Liberer l'emplacement memoire du fromage sos_kfree((sos_vaddr_t)pElement); pMap[p.X + (p.Y * MAP_X)] = NULL; //Donner le fromage a la souris Set(pMouse->Status, MOUSE_FULL); Reset(pMouse->Status, MOUSE_EMPTY); pMouse->Color = SOS_X86_VIDEO_FG_MAGENTA; CheeseCount--; return TRUE; case OUTPUT: //Supprimer la souris pMap[Org.X + (Org.Y * MAP_X)] = NULL; MouseCount--; DrawPixel(Org.X, Org.Y, SOS_X86_VIDEO_FG_BLACK); sos_x86_videomem_printf( 23,0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Souris = %d; Fromages = %d; Obstacles = %d ", MouseCount, CheeseCount, ObstacleCount); Set(pMouse->Status, MOUSE_EXITED); return FALSE; default : return FALSE; } return FALSE;}//*****************************************************************************// But de la fonction : Tester si une collision a eu lieu avec un obstacle// Entrees :// Org : Coordonnees de la souris// p : coordonnees desirees par la souris// Sortie :// Cheese : Coordonnees du fromage// Parametre retourne : TRUE si une collision a eu lieu, FALSE sinon//*****************************************************************************static sos_bool_t IsCollision(Point_t Org, Point_t p, Point_t *Cheese){ Element_t * pMouse = pMap[Org.X + (Org.Y * MAP_X)]; Element_t * pElement; //Tester les bordures de la map if((p.X < 0)||(p.Y < 0)) return TRUE; if((p.Y >= MAP_Y)||(p.X >= MAP_X)) return TRUE; pElement = pMap[p.X + (p.Y * MAP_X)]; //L'element est vide if(pElement == NULL) return FALSE; //Si du fromage a ete trouve, stopper la recherche if(IsSet(pMouse->Status, CHEESE_FOUND)) return FALSE; switch(pElement->Type) { case CHEESE: if(IsSet(pMouse->Status, MOUSE_FULL)) return TRUE; //Indiquer que du fromage a ete trouve Set(pMouse->Status, CHEESE_FOUND); //Retenir la position du fromage (*Cheese).X = p.X; (*Cheese).Y = p.Y; break; case INPUT: if(IsSet(pMouse->Status, MOUSE_EMPTY)) return TRUE; //Remplir les reserves de fromage Set(pMouse->Status, MOUSE_EMPTY); Reset(pMouse->Status, MOUSE_FULL); pMouse->Color = SOS_X86_VIDEO_FG_LTRED; //Autoriser la creation d'une autre souris sos_ksema_up(& SemMouse); return TRUE; case OUTPUT: break; default : return TRUE; } return FALSE;//Aucune collision}//*****************************************************************************// But du thread : Creer une souris et la placer autour de l'entree//*****************************************************************************static void MouseCreator(void){ while(1) { sos_ksema_down(& SemMouse, NULL); sos_ksema_down(& SemMap, NULL); CreateMouse(); sos_ksema_up(& SemMap); }}//*****************************************************************************// But de la fonction : Creer une souris et l'inserer dans la carte// Entree : Aucune// Parametre retourne : ERROR si memoire insuffisante, FALSE si souris non// cree, TRUE sinon//*****************************************************************************static sos_ret_t CreateMouse(void){ Element_t * pElement; unsigned int I; Point_t p; for(I = 0; I < 8; I++) {//Explorer tous les emplacements p.X = 0; p.Y = MAP_Y / 2; switch(I) {//Repere le deplacement case 0: p.Y++; break; case 1: p.X++; p.Y++; break; case 2: p.X++; break; case 3: p.Y--; p.X++; break; case 4: p.Y--; break; case 5: p.Y--; p.X--; break; case 6: p.X--; break; case 7: p.X--; p.Y++; break; } if((p.X >= 0)&&(p.Y >= 0)&&(p.X < MAP_X)&&(p.Y < MAP_Y)) {//L'emplacement est valide pElement = pMap[p.X + (p.Y * MAP_X)]; if(pElement == NULL) {//Creer la souris pElement = (Element_t *)sos_kmalloc(sizeof(Element_t), 0); if(pElement != NULL) {//Initialiser l'entree pElement->Type = MOUSE; Set(pElement->Status, MOUSE_EMPTY); pElement->Color = SOS_X86_VIDEO_FG_LTRED; pElement->P = p; pElement->Way = 0; pElement->ThreadID = sos_create_kernel_thread("Mouse", (sos_kernel_thread_start_routine_t)Mouse, pElement, SOS_SCHED_PRIO_TS_LOWEST-1); if(pElement->ThreadID == 0) { sos_kfree((sos_vaddr_t)pElement); pElement = NULL; return -SOS_ENOMEM; } pMap[p.X + (p.Y * MAP_X)] = pElement; MouseCount++; DrawPixel(p.X, p.Y, pElement->Color); sos_x86_videomem_printf(23, 0, SOS_X86_VIDEO_FG_YELLOW | SOS_X86_VIDEO_BG_BLUE, "Souris = %d; Fromages = %d; Obstacles = %d ", MouseCount, CheeseCount, ObstacleCount); return SOS_OK; } } } } return -SOS_EBUSY;}//*****************************************************************************// C'est fini !!!!//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -