Custom Input Handling Implemantation
#ifndef KEY_READER_H
#define KEY_READER_H
#include <termios.h>
#include <unistd.h>
int read_key() {
struct termios original_settings, modified_settings;
tcgetattr(STDIN_FILENO, &original_settings);
modified_settings = original_settings;
modified_settings.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &modified_settings);
int key_value = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &original_settings);
return key_value;
}
#endif
Game Representation and Initialization
#define EMPTY 0
#define PLAYER 1
#define WALL 2
#define BOX 3
#define TARGET 4
#define PLAYER_ON_TARGET 5
#define BOX_ON_TARGET 7
char game_grid[8][8] = {
{0,0,2,2,2,2,0,0},
{0,0,2,4,4,2,0,0},
{0,2,2,0,4,2,2,0},
{0,2,0,0,3,4,2,0},
{2,2,0,3,0,0,2,2},
{2,0,0,2,3,3,0,2},
{2,0,0,1,0,0,0,2},
{2,2,2,2,2,2,2,2}
};
int player_row = 6, player_col = 3;
int move_count = 0;
Game Rendering and Input Processing
while(1) {
system("clear");
int completed_targets = 0;
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 8; j++) {
switch(game_grid[i][j]) {
case EMPTY: printf(" "); break;
case PLAYER: printf("\u25B2 "); break;
case WALL: printf("\u2588\u2588"); break;
case BOX: printf("\u25A0 "); break;
case TARGET: printf("\u25CB "); break;
case PLAYER_ON_TARGET: printf("\u25B3 "); break;
case BOX_ON_TARGET: printf("\u25A1 "); completed_targets++; break;
}
}
printf("\n");
}
if(completed_targets == 4) {
printf("Game completed in %d moves\n", move_count);
return 0;
}
int input = read_key();
int next_row = player_row;
int next_col = player_col;
switch(input) {
case 183: next_row--; break; // Up
case 184: next_row++; break; // Down
case 185: next_col++; break; // Right
case 186: next_col--; break; // Left
}
if(game_grid[next_row][next_col] == EMPTY ||
game_grid[next_row][next_col] == TARGET) {
game_grid[next_row][next_col] += PLAYER;
game_grid[player_row][player_col] -= PLAYER;
player_row = next_row;
player_col = next_col;
move_count++;
}
else if(game_grid[next_row][next_col] == BOX ||
game_grid[next_row][next_col] == BOX_ON_TARGET) {
int push_row = next_row + (next_row - player_row);
int push_col = next_col + (next_col - player_col);
if(game_grid[push_row][push_col] == EMPTY ||
game_grid[push_row][push_col] == TARGET) {
game_grid[push_row][push_col] += BOX;
game_grid[next_row][next_col] -= BOX - PLAYER;
game_grid[player_row][player_col] -= PLAYER;
player_row = next_row;
player_col = next_col;
move_count++;
}
}
}