LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General > LinuxQuestions.org Member Success Stories
User Name
Password
LinuxQuestions.org Member Success Stories Just spent four hours configuring your favorite program? Just figured out a Linux problem that has been stumping you for months?
Post your Linux Success Stories here.

Notices

Reply
 
Search this Thread
Old 06-14-2009, 05:03 PM   #1
jr_bob_dobbs
LQ Newbie
 
Registered: Mar 2009
Posts: 24

Rep: Reputation: 1
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);
}
 
  


Reply

Tags
ncurses


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to print text in color by ncurses without opening a ncurses window Greatrebel Programming 0 12-20-2006 10:15 AM
Yay. Rod Beauvex LinuxQuestions.org Member Intro 1 05-05-2004 05:48 PM
Yay ! phoeniXflame Slackware 1 02-13-2003 07:47 PM
yay for me fatpig Linux - General 4 02-08-2003 08:32 PM
ncurses-5.2-28 conflicts with file from package ncurses-5.2-12 tubby Linux - Software 4 06-16-2002 01:00 AM


All times are GMT -5. The time now is 04:18 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration