jr_bob_dobbs |
06-14-2009 04:03 PM |
learnign ncurses, just wrote this, yay :D
So I've started to teach myself ncurses programming. Actually got a program working, a simple maze game. You start in the upper left and the goal/end is the lower right. Thought I'd share it here (curse_maze_2.c) :
Code:
/* gcc -o curses_maze_2 -lncurses curses_maze_2.c */
#include <curses.h>
#include <signal.h>
#include <time.h> /* for random */
#ifndef memmove
#include <string.h>
#endif
#ifndef srand
#include <stdlib.h>
#endif
#define neq !=
#define eq ==
#define DOOPS 20
#define OKDOKEY 0
#define mod %
#define maze_width 72
#define maze_height 28
#define drill_north 0
#define drill_south 1
#define drill_west 2
#define drill_east 3
/* global vars */
char *maze;
int player_x, player_y, player_x_maze, player_y_maze;
int where_i_was_x, where_i_was_y, what_was_under_char;
int maze_displace_x, maze_displace_y;
unsigned int end_x_maze, end_y_maze;
unsigned short turns;
int pcc_use_colors;
/* forward references */
void handle_ctrl_c(int);
void build_maze();
void draw_info_line();
void draw_map();
void redraw_board();
void draw_under_character();
void draw_character();
/* start of actual program */
void handle_ctrl_c(s)
int s;
{
ungetch('q'); /* put in quit command as an input char */
}
void build_maze()
{
int y, x, turns, a, direction;
for (y = 0; y neq maze_height; y++) {
for (x = 0; x neq maze_width; x++) {
maze[((y * maze_width) + x)] = '#';
}
}
x = 1;
y = maze_height / 2;
maze[((y * maze_width) + x)] = ' '; /* start drilling */
for (turns = 0; turns neq 800000; turns++) {
y = 1 + (rand() mod (maze_height - 2));
x = 1 + (rand() mod (maze_width - 2));
if ('#' eq maze[((y * maze_width) + x)]) { /* if not already dug */
/* At this point, we are at a filled spot. */
/* Now, only if there is one space adjacent in a non-diagonal
direction, can we drill/dig this spot */
a = 0;
if (' ' eq maze[(((y - 1) * maze_width) + x)]) { a++; direction = drill_north; }
if (' ' eq maze[(((y + 1) * maze_width) + x)]) { a++; direction = drill_south; }
if (' ' eq maze[((y * maze_width) + (x - 1))]) { a++; direction = drill_west; }
if (' ' eq maze[((y * maze_width) + (x + 1))]) { a++; direction = drill_east; }
if (1 eq a) {
/* we have one adjacent non-diagonal space.
Maybe we can drill. the two diaognals opposing this draw_map(0, 0, old_height, old_width);
space must be un-dug for this to work */
switch (direction) {
case drill_north : /* check south diagonals */
if (' ' eq maze[(((y + 1) * maze_width) + (x - 1))]) a = 0; /* can't drill */
if (' ' eq maze[(((y + 1) * maze_width) + (x + 1))]) a = 0; /* can't drill */
break;
case drill_south : /* check north diagonals */
if (' ' eq maze[(((y - 1) * maze_width) + (x - 1))]) a = 0; /* can't drill */
if (' ' eq maze[(((y - 1) * maze_width) + (x + 1))]) a = 0; /* can't drill */
break;
case drill_west : /* check east diagonals */
if (' ' eq maze[(((y - 1) * maze_width) + (x + 1))]) a = 0; /* can't drill */
if (' ' eq maze[(((y + 1) * maze_width) + (x + 1))]) a = 0; /* can't drill */
break;
case drill_east : /* check west diagonals */
if (' ' eq maze[(((y - 1) * maze_width) + (x - 1))]) a = 0; /* can't drill */
if (' ' eq maze[(((y + 1) * maze_width) + (x - 1))]) a = 0; /* can't drill */
break;
} /* end switch */
if (1 eq a) {
/* we can drill/dig! YAY! */
maze[((y * maze_width) + x)] = ' ';
}
}
}
}
}
void draw_info_line()
{
attron(A_BOLD);
mvprintw(
(LINES - 1), 0,
"-- pcc maze --- %3d -- %3d -- ",
player_x_maze, player_y_maze
);
attroff(A_BOLD);
}
void draw_side_bar_stats()
{
attron(A_BOLD);
mvprintw(
1,
((COLS - 8) + 2),
" "
);
mvprintw(
1,
((COLS - 8) + 2),
"%d", turns
);
attroff(A_BOLD);
}
void draw_side_bar()
{
mvprintw(0, (COLS - 8), "+-------");
mvaddch(1, (COLS - 8), '|');
mvaddch(2, (COLS - 8), '|');
draw_side_bar_stats();
}
void draw_map()
{
int x, y, xlim, ylim, c;
xlim = COLS - 8;
ylim = LINES - 1;
for (y = 0; y neq ylim; y++) {
for (x = 0; x neq xlim; x++) {
if (((x + maze_displace_x) < maze_width) &&
((y + maze_displace_y) < maze_height)) {
c = maze[(((y + maze_displace_y) * maze_width) + (x + maze_displace_x))];
if (('.' eq c) && pcc_use_colors) {
attron(COLOR_PAIR(3));
}
if ('X' eq c) {
attron(A_BOLD);
if (pcc_use_colors) {
attron(COLOR_PAIR(4));
}
}
mvaddch(
y, x,
c
);
if ('X' eq c) {
if (pcc_use_colors) {
attroff(COLOR_PAIR(4));
}
attroff(A_BOLD);
}
if (('.' eq c) && pcc_use_colors) {
attroff(COLOR_PAIR(3));
}
} else {
mvaddch(
y, x,
' '
);
}
}
}
}
void redraw_board()
{
draw_map(0, 0);
draw_side_bar();
draw_info_line();
move(player_y, player_x); refresh();
}
void pick_start_point()
{
player_x = 1;
player_y = 1;
while (
' '
neq
maze[
(
(player_y * maze_width) + player_x
)
]
)
{
player_x++;
}
player_x_maze = player_x;
player_y_maze = player_y;
}
void pick_end_point()
{
end_x_maze = maze_width - 2;
end_y_maze = maze_height - 2;
while (
' '
neq
maze[
(
(end_y_maze * maze_width) + end_x_maze
)
]
)
{
end_x_maze--;
}
maze[((end_y_maze * maze_width) + end_x_maze)] = 'X';
}
void draw_under_character()
{
what_was_under_char = maze[((player_y_maze * maze_width) + player_x_maze)];
where_i_was_x = player_x_maze;
where_i_was_y = player_y_maze;
if (('.' eq what_was_under_char) && pcc_use_colors) {
attron(COLOR_PAIR(3));
}
mvaddch(player_y, player_x, what_was_under_char);
if (('.' eq what_was_under_char) && pcc_use_colors) {
attroff(COLOR_PAIR(3));
}
}
void draw_character()
{
attron(A_BOLD);
mvaddch(player_y, player_x, '@');
attroff(A_BOLD);
move(player_y, player_x);
}
void update_trail()
{
if ('.' eq maze[((player_y_maze * maze_width) + player_x_maze)]) {
maze[((where_i_was_y * maze_width) + where_i_was_x)] = ' ';
} else {
if (' ' eq maze[((player_y_maze * maze_width) + player_x_maze)]) {
maze[((where_i_was_y * maze_width) + where_i_was_x)] = '.';
}
}
draw_map();
}
int check_for_match()
{
if (player_x_maze eq end_x_maze) {
if (player_y_maze eq end_y_maze) {
return(1);
}
}
return(0);
}
main()
{
int c;
srand((unsigned int) time(NULL) );
maze = malloc(maze_width * maze_height);
if (NULL eq maze) {
fprintf(stderr, "memory failure\n");
exit(DOOPS);
}
turns = 0;
build_maze();
pick_start_point();
pick_end_point();
maze_displace_x = maze_displace_y = 0;
signal(SIGINT, handle_ctrl_c);
initscr();
pcc_use_colors = 0;
if (TRUE eq has_colors()) {
pcc_use_colors++;
start_color();
use_default_colors();
init_pair(3, COLOR_CYAN, -1); /* Blue-green on clear */
init_pair(4, COLOR_GREEN, -1); /* green on clear */
}
keypad(stdscr, TRUE);
cbreak();
noecho();
halfdelay(1);
redraw_board();
draw_character(player_y, player_x);
while (1) {
if (check_for_match()) break;
c = getch();
switch (c) {
case 0xc : /* ^l */ /* user presses ^l to force redraw */
redraw_board();
break;
case 3 : /* control-c to exit */
case 'q' : /* q to exit */
move((LINES - 1), 0); refresh();
endwin();
exit(OKDOKEY);
case '6' : /* move east/right */
case KEY_RIGHT :
switch (maze[((player_y_maze * maze_width) + (player_x_maze + 1))]) {
case ' ' :
case '.' :
case 'X' :
draw_under_character();
/* if we reached this point, then we can move east/right in the
maze. However, can we move east in the "window"? */
if (player_x eq (COLS - 10)) {
maze_displace_x++; /* do not change player_x!!! */
draw_map();
} else {
player_x++;
}
player_x_maze++;
turns++;
update_trail();
draw_info_line();
draw_side_bar_stats();
draw_character();
refresh();
break;
} /* end switch */
break;
case '4' : /* move west/left */
case KEY_LEFT :
switch (maze[((player_y_maze * maze_width) + (player_x_maze - 1))]) {
case ' ' :
case '.' :
case 'X' :
draw_under_character();
/* if we reached this point, then we can move west/left in the
maze. However, can we move north in the "window"? */
if (player_x eq 1) { /* need to scroll maze first */
maze_displace_x--; /* do not change player_x!!! */
draw_map();
} else {
player_x--;
}
player_x_maze--;
turns++;
update_trail();
draw_info_line();
draw_side_bar_stats();
draw_character();
refresh();
break;
} /* end switch */
break;
case '8' : /* move north/up */
case KEY_UP :
switch (maze[(((player_y_maze - 1) * maze_width) + player_x_maze)]) {
case ' ' :
case '.' :
case 'X' :
draw_under_character();
/* if we reached this point, then we can move north/up in the
maze. However, can we move north in the "window"? */
if (player_y eq 1) { /* need to scroll maze first */
maze_displace_y--; /* do not change player_y!!! */
draw_map();
} else {
player_y--;
}
player_y_maze--;
turns++;
update_trail();
draw_info_line();
draw_side_bar_stats();
draw_character();
refresh();
break;
} /* end switch */
break;
case '2' : /* move south/down */
case KEY_DOWN :
switch (maze[(((player_y_maze + 1) * maze_width) + player_x_maze)]) {
case ' ' :
case '.' :
case 'X' :
draw_under_character();
/* if we reached this point, then we can move down/south in the
maze. However, can we move south in the "window"? */
if (player_y eq (LINES - 3)) { /* need to scroll maze first */
maze_displace_y++; /* do not change player_y!!! */
draw_map();
} else {
player_y++;
}
player_y_maze++;
turns++;
update_trail();
draw_info_line();
draw_side_bar_stats();
draw_character();
refresh();
break;
}
break;
} /* end switch */
} /* end while */
/* we could only reach this point if we sucesfully reached the
end goal of the maze */
maze[((where_i_was_y * maze_width) + where_i_was_x)] = '.';
draw_map();
attron(A_BOLD);
mvprintw(2, (COLS - 8) + 2, "YOU");
mvprintw(3, (COLS - 8) + 2, "WIN!");
attroff(A_BOLD);
draw_character();
refresh();
while (-1 eq (c = getch())); /* pause before exit */
move((LINES - 1), 0); refresh();
endwin();
exit(OKDOKEY);
}
|