140 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "game.h"
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <time.h>
 | |
| 
 | |
| #define MOUSE_COUNT 5
 | |
| 
 | |
| void* init_game(){
 | |
|     srand(time(NULL));
 | |
|     struct game* g = malloc(sizeof(struct game));
 | |
| 
 | |
|     // Frame size
 | |
|     int frame_width = 30;
 | |
|     int frame_height = 10;
 | |
| 
 | |
|     // Get the screen size
 | |
|     int width, height;
 | |
|     getmaxyx(stdscr, height, width); // Set the size of the terminal
 | |
| 
 | |
|     int start_x = (width - frame_width) / 2;
 | |
|     int start_y = (height - frame_height) / 2;
 | |
| 
 | |
|     // Cat coordinate in frame
 | |
|     g->catx = start_x + (frame_width / 2);
 | |
|     g->caty = start_y + (frame_height / 2);
 | |
| 
 | |
|     // Mice coordinate in frame
 | |
|     for(int i = 0; i < MOUSE_COUNT; i++){
 | |
|         g->mousex[i] = rand() % (frame_width - 2) + start_x + 1;
 | |
|         g->mousey[i] = rand() % (frame_height - 2) + start_y + 1;
 | |
|         g->mouse_state[i] = 0;
 | |
|     }
 | |
| 
 | |
|     strcpy(g->message, "Use arrow keys to catch the mice!");
 | |
|     return g;
 | |
| }
 | |
| 
 | |
| int check_collision(struct game* g, int x, int y){
 | |
|     for(int i = 0; i < MOUSE_COUNT; i++){
 | |
|         if(g->mouse_state[i] == 0 && g->mousex[i] == x && g->mousey[i] == y){
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int game_event(struct event* event, void* gptr){
 | |
|     struct game* g = (struct game*)gptr;
 | |
| 
 | |
|     int width, height;
 | |
|     getmaxyx(stdscr, height, width);
 | |
| 
 | |
|     int frame_width = 30;
 | |
|     int frame_height = 10;
 | |
| 
 | |
|     int start_x = (width - frame_width) / 2;
 | |
|     int start_y = (height - frame_height) / 2;
 | |
| 
 | |
|     int min_x = start_x + 1, max_x = start_x + frame_width - 2;
 | |
|     int min_y = start_y + 1, max_y = start_y + frame_height - 2;
 | |
| 
 | |
|     if (event->type == EVENT_KEY) {
 | |
|         switch (event->key) {
 | |
|             case KEY_UP:    if (g->caty > min_y) g->caty--; break;
 | |
|             case KEY_DOWN:  if (g->caty < max_y) g->caty++; break;
 | |
|             case KEY_LEFT:  if (g->catx > min_x) g->catx--; break;
 | |
|             case KEY_RIGHT: if (g->catx < max_x) g->catx++; break;
 | |
|             case 27: // ESC
 | |
|             case 'q':
 | |
|                 return 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Mice move
 | |
|     int alive = 0;
 | |
|     for(int i = 0; i < MOUSE_COUNT; i++){
 | |
|         if(g->mouse_state[i] == 0){
 | |
|             // If cat catch mice
 | |
|             if(g->mousex[i] == g->catx && g->mousey[i] == g->caty){
 | |
|                 g->mouse_state[i] = 1;
 | |
|             }else{
 | |
|                 // Random move
 | |
|                 int dir = rand() % 4;
 | |
|                 int new_mousex = g->mousex[i];
 | |
|                 int new_mousey = g->mousey[i];
 | |
|                 switch(dir){
 | |
|                     case 0: if (new_mousey > min_y) new_mousey--; break;
 | |
|                     case 1: if (new_mousey < max_y) new_mousey++; break;
 | |
|                     case 2: if (new_mousex > min_x) new_mousex--; break;
 | |
|                     case 3: if (new_mousex < max_x) new_mousex++; break;
 | |
|                 }
 | |
| 
 | |
|                 // Checking whether it overlaps with another mouse
 | |
|                 if(!check_collision(g, new_mousex, new_mousey)){
 | |
|                     g->mousex[i] = new_mousex;
 | |
|                     g->mousey[i] = new_mousey;
 | |
|                 }
 | |
|             }
 | |
|             alive++;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     clear_screen();
 | |
| 
 | |
|     // Draw a frame
 | |
|     for(int x = start_x; x < start_x + frame_width; x++){
 | |
|         set_cell('#', x, start_y);
 | |
|         set_cell('#', x, start_y + frame_height - 1);
 | |
|     }
 | |
|     for(int y = start_y + 1; y < start_y + frame_height - 1; y++){
 | |
|         set_cell('#', start_x, y);
 | |
|         set_cell('#', start_x + frame_width - 1, y);
 | |
|     }
 | |
| 
 | |
|     // Draw a cat
 | |
|     set_cell('C', g->catx, g->caty);
 | |
| 
 | |
|     // Draw a mice
 | |
|     for(int i = 0; i < MOUSE_COUNT; i++){
 | |
|         if (g->mouse_state[i] == 0) {
 | |
|             set_cell('m', g->mousex[i], g->mousey[i]);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // Message
 | |
|     if(alive == 0){
 | |
|         set_message("You win! Press ESC or q to quit.", 2, height - 2);
 | |
|     }else{
 | |
|         char msg[100];
 | |
|         snprintf(msg, sizeof(msg), "Mice left: %d", alive);
 | |
|         set_message(msg, 2, height - 2);
 | |
|     }
 | |
| 
 | |
|     // If no mice left quit the game by press ESC or press q for quit any time
 | |
|     if(alive == 0 && (event->key == 27 || event->key == 'q')){
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| } |