View Single Post
Old 03-06-2006, 05:10 PM   #1
guesst
Abandonia Homie
 
guesst's Avatar

 
Join Date: May 2005
Location: Aurora, United States
Posts: 606
Default

Buttons (hey, you come up with a better name then...)
The game in my sig, as I said, is a smaller, stripped down version of a bigger program. The code has been formated in a less readable format so it fits in as few lines as possible. I actually made 2 version of this. The other version is 7 lines, has better looking graphics, but only 1 solution. However, this actually makes a better intro game, so I'll post it here:
Code:
#define z printf
#define L(a,b) for(c=a;c<a+3;c++)z(x[b*!!(d&1<<c)],c+1)
#define R(a) z("\n\n\t");L(a,1);z("\n\t");L(a,2);z("\n\t");L(a,1)
char *x[]={"**... "," +===+"," | %d |"},n;int d,m[]={27,7,54,73,186,292,216,448,
432};p(){int c;R(6);R(3);R(0);}main() {srand (time(0));d=1+rand ()%511;p();do{z(
"\n\t\tmove ? ");do n=getche ()-'1';while(n<0||n>8);if(d&1<<n)d^=m[n];p();}while
(d&&(d==495)?!z("\n\n\t\tGoal!!!\n"):1);}
This 7 line version, when you load and run it looks like this:
Code:
**********...** ...** ...
**********...** ...** ...
**********...** ...** ...

******** +===+**...**+===+
******** | 4 |**...**| 6 |
******** +===+**...**+===+

**********...** ...**+===+
**********...** ...**| 3 |
**********...** ...**+===+
****************move ?
The avaible buttons to press are represented, with a number in the middle, and the non available ones with dots. Start pressing buttons and the board will change. You win when it looks like:
Code:
******** +===+ +===+ +===+
******** | 7 | | 8 | | 9 |
******** +===+ +===+ +===+

******** +===+**...**+===+
******** | 4 |**...**| 6 |
******** +===+**...**+===+

******** +===+ +===+ +===+
******** | 1 | | 2 | | 3 |
******** +===+ +===+ +===+

****************Goal!!!
Easy, huh?

Well, the 5 line version below looks a bit different but plays similarly. I'll repost the code here incase I change my sig:
Code:
int n,d[2],m[9]={27,7,54,73,186,292,216,448,432};p(){int c=6,k=0;puts("");for(;c
>=0;){putchar((d[k]&1<<c)?k?'*':'1'+c:'.');if (++c%3)continue;putchar(' ');c-=3;
if(k=!k)continue;puts("");c-=3;}}main(){srand(time(0));*d=1+rand()%511;d[1]=rand
()%512;p();for(;*d&&((*d-d[1])?1:puts("Goal!"));){printf("move?");do n=getche ()
-'1';while(n<0||n>8);if(*d&1<<n)*d^=m[n];p();}}
When you run it you'll see:
Code:
789 *..
..6 **.
.23 ..*
move?
Alot of prettyness goes with those 2 lines. However, I was able to make the goals different every time. In this version the 3x3 on the left are your buttons, and the 3x3 on the right is your goal. So in this case you don't win until you see
Code:
7.. *..
45. **.
..3 ..*
move?
Some goals are more challanging than others, but there is a fantastic sense of accomplishment that goes along with working a solution backwards like this.

So there you go, an explination of my sig and a teaser for future programs to come. Feedback is welcome and if you all like it I'll post more of my super-cool C programs.

For anyone who wants a more readable version of the game, here it is:
Code:
/* Buttons
 * by Joseph Larson
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

#define L(a,b) for (c = a; c < a + 3; c++) printf(gfx[b * !!(bd & 1 << c)], c+1)
#define R(a) printf ("\t");L(a,1);printf ("\n\t");L(a,2);printf ("\n\t");L(a,1)
#define D(a) ".O"[!!(goal[lv] & 1 << a)]
#define NUMGOAL 8

char *gfx[] = { "**... ", " +===+", " | %d |"};
int bd, lv, won, won_mask,
move[] = {0x001b, 0x0007, 0x0036, 0x0049, 0x00ba, 0x0124, 0x00d8, 0x01c0, 0x01b0}
,goal[] = {0x01ef, 0x0010, 0x0054, 0x01d2, 0x004F, 0x001b, 0x0145, 0x0000};
/* O, ., \, T, L, square, corners, blank */

void show_buttons (void) {
**int c;
**
**printf ("\n\n");
**R(6); printf ("\tGoal:\n\n\t");
**L(3, 1); printf ("\t %c%c%c\n\t", D(6), D(7), D(8));
**L(3, 2); printf ("\t %c%c%c\n\t", D(3), D(4), D(5));
**L(3, 1); printf ("\t %c%c%c\n\n", D(0), D(1), D(2));
**R(0);
}

void puzzle (void) {
**char in;
**
**do lv = rand() % NUMGOAL; while (won_mask & 1 << lv);
**bd = rand () % 0x01FE + 1;
**do {
****show_buttons ();
****printf ("\n\n\t\tmove ? ");
****do in = getchar (); while (in < '0' || in > '9');
****if (in -= '0')
******if (bd & 1 << in - 1) bd ^= move [in - 1];
******else puts ("Invalad. That button is not up.");
**} while (bd && bd != goal[lv] && in);
**if (bd == goal[lv]) {
******show_buttons ();
****puts ("\n\n\t\tGoal!!!");
****won++;
****won_mask |= 1 << lv;
**} else if (!bd) {
****show_buttons ();
****puts ("\n\n\tYou have no more moves.");
**}
}

int want_more (void) {
**char yn;
**
**if (won < NUMGOAL) {
****printf ("\nDo you want to try another one? (y/n)");
****do yn = getchar (); while (tolower (yn) != 'y' && tolower (yn) != 'n');
****return tolower (yn) == 'y';
**} else puts ("Congratulations! You've solved all the puzzles!\n\n"
****"You are a master button pusher.\n\nThanks for playing.");
**return 0;
}

int main (void) {
**won_mask = won = 0;
**srand (time (NULL));
**puts ("Buttons\n-------\n"
**"Try to make the field of buttons look like the goal. You can press any\n"
**"button that is up by typing the number on the button, but when you press\n"
**"a button other buttons around it will change. Each button always changes\n"
**"the same buttons around it.\n"
**"Type zero ('0') as your move to quit\n"
**"There are several goals to accomplish. Try to get them all!\n\n"
**"Press ENTER to start...");
**getchar ();
**do puzzle (); while (want_more ());
**puts ("Good bye!");
**exit (0);
}
Note, if you take the line:
Code:
**bd = rand () % 0x01FE + 1;
And add this to the end:
Code:
**bd = rand () % 0x01FE + 1; goal[lv] = rand () % 0x01FF;
you will always have random boards to finish. Do this when the set of winning boards gets to boring.
guesst is offline                         Send a private message to guesst
Reply With Quote