03-06-2006, 05:10 PM | #1 | ||
Join Date: May 2005
Location: Aurora, United States
Posts: 606
|
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);} Code:
**********...** ...** ... **********...** ...** ... **********...** ...** ... ******** +===+**...**+===+ ******** | 4 |**...**| 6 | ******** +===+**...**+===+ **********...** ...**+===+ **********...** ...**| 3 | **********...** ...**+===+ ****************move ? Code:
******** +===+ +===+ +===+ ******** | 7 | | 8 | | 9 | ******** +===+ +===+ +===+ ******** +===+**...**+===+ ******** | 4 |**...**| 6 | ******** +===+**...**+===+ ******** +===+ +===+ +===+ ******** | 1 | | 2 | | 3 | ******** +===+ +===+ +===+ ****************Goal!!! 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();}} Code:
789 *.. ..6 **. .23 ..* move? Code:
7.. *.. 45. **. ..3 ..* move? 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); } Code:
**bd = rand () % 0x01FE + 1; Code:
**bd = rand () % 0x01FE + 1; goal[lv] = rand () % 0x01FF; |
||
|
|
05-06-2006, 10:12 AM | #2 | ||
Join Date: Jun 2004
Location: Jan Mayen, Svalbard and Jan Mayen
Posts: 2,167
|
Please post a few more.
Did you try to optmize your programs for speed as well or merely fo as small as possibl ? You don't mention the header files that are needed and getche isn't available at my place.
__________________
Flowing with the stream of life |
||
|
|
05-06-2006, 03:21 PM | #3 | ||
Join Date: May 2005
Location: Aurora, United States
Posts: 606
|
<div class='quotetop'>QUOTE(Data @ Jun 5 2006, 10:12 AM) [snapback]234432[/snapback]</div>
Quote:
Header files are unnecessary. everything is kept in the single file. just be sure to name it with a .c instead of .cpp and every complier I've used can handle it. (Even M$, although I've only complied in a windows environment. If your complier is different, let me know.) As for getche(), that is a non-standard function. But all of my programs are designed so that getche () can be replaced with the ANSI standard getchar() and (1) still funciton and (2) not consume any more space. (I leave a space after getche_ for the extra letter in getchar every time.) No, my programs are not optimized for speed. For programs as small as this that's kind of silly. Besides, I'm not very good at optimizing for speed. more programs to come... |
||
|
|
05-06-2006, 08:14 PM | #4 | ||
Join Date: May 2005
Location: Aurora, United States
Posts: 606
|
So, which one to continue with? I'll start with a small one and move on to a somewhat bigger one, then let you all choose.
Jumping Balls (please hold back the grade school snickering) What inspired this little programming spree was when I found a couple of old books of BASIC programs that I would read in High School. Of course, by High School BASIC was a thing of the past, so all I could do was read the programs an imagine how cool it'd be to play them. So when I found the entire text of both books online years later I decided that I would like to finally see these programs run. Only, instead of whipping out gwBASIC (or whatever) I'd convert the programs in it to C! One of these programs I found such a suscinct way of expressing in C that I decided to see if it would fit in a sig. It did, and in 3 lines no less: Code:
main(){char b[11]="\toooo.OOOO";int e=5,n,t=0;puts("\t123456789");puts(b);for(;n &&strcmp("\tOOOO.oooo",b);puts(b)){n=getche();if(n-='0'){if(n>0&&n<=9&&(abs(n-e) ==2||abs(n-e)==1)){b[e]=b[n];b[n]='.';e=n;t++;}}}if(n)printf("\n%d moves\n",t);} In a a perfect game you can win in 24 moves. How well can you do? Below is the full, more readable, and longer more compelte version Code:
/* Jumping Balls * By Joseph Larson * Inspired by a BASIC game of the same name by Anthony Rizzolo * as found in 'More BASIC Computer Games' edited by David H. Ahl (c) 1979 */ #include <stdio.h> #include <string.h> #include <math.h> #include <ctype.h> int main (void) { **char yn, b[10], *start = "XXXX.OOOO", *end = "OOOO.XXXX"; **int empty, input, t; ** **puts ("Jumping Balls\n------- -----\n" **"This is a game of solitare. It is played with 8 balls in 9 holes. The X's\n" **"and O's are the balls in this game and the period ('.') is the empty hole.\n" **"The object is to get all the X's and O's to switch sides. You can move by\n" **"either moving a ball into the empty space or jumping one ball over another\n" **"into the empty space.\n\n" **"On your turn input the number from the left of the space of the ball you\n" **"want to move or jump into the empty space.\n\n" **"If you want to quit input '0' as your move.\n\n" **"Press ENTER to start..."); **getchar (); **do { ****empty = 4; t = 0; strcpy (b, start); ****puts ("\t123456789"); ****printf ("\t%s\t? ", b); scanf ("%d", &input); ****while (input && strcmp (b, end)) { ******if (input--) { ********if (input >= 0 && input < 9 && **********(abs (input - empty) == 2 || abs (input - empty) == 1)) { **********b[empty] = b[input]; b[input] = '.'; empty = input; t ++; ********} else puts ("Invalad move."); ******} ******printf ("\t%s\t? ", b); if (strcmp (b, end)) scanf ("%d", &input); ****} ****if (!strcmp (b, end)) ******printf ("\nCongratulations! You solved it in %d moves!\n\n" ******"Do you want to try for a better score? (y/n) ", t); ****else printf ("Do you want to start again ? (y/n) "); ****do yn = getchar (); while (!isalpha (yn)); **} while (tolower (yn) != 'n'); **puts ("Thanks for playing!"); **exit (0); } |
||
|
|
09-06-2006, 12:03 AM | #5 | ||
Join Date: May 2006
Location: ,
Posts: 29
|
Interesting how compact source code can be, even though I have a different view about what "minimal" source code is.
What I would like to know is how long it would take you to complete such a transformation on code that you have not seen before? |
||
|
|
09-06-2006, 03:10 AM | #6 | ||
Join Date: May 2005
Location: Aurora, United States
Posts: 606
|
<div class='quotetop'>QUOTE(Eagg @ Jun 9 2006, 12:03 AM) [snapback]235363[/snapback]</div>
Quote:
Which is a perfect segway into the next program. Robot Escape The instructions are in the game, so just read down a few lines to see them: Code:
/* Robot Escape * by Joseph Larson 2005 */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <ctype.h> #define W 77 #define H 21 #define MAX_LOC**W * H #define SQ(a) (a) * (a) typedef struct {int loc, type;} STUFF; STUFF **p; int numobj; char msg[W], icons[4] = {' ', '#', 'O', '+'}; void intro (void) { **printf ("Robot Escape\n------------\n" **"You are being chased by robots. Fortunately you have two advantages. First,\n" **"your pursures aren't very smart. Second, you have a teleport-a-matic at\n" **"your command should you need it.\n\n" **"The robots will take the most direct route to you, even if it means running\n" **"into another robot. When two robots crash they make a debris heap that you\n" **"can crash other robots into. When all robots are destroyed you win and go\n" **"on to the next level. Try to make it to level 10!\n\n" **"If you have to use your teleport-a-matic remember that it might teleport\n" **"you into your enemies, so use it sparingly.\n\n" **"You move using the number keys. (Be sure num-lock is on) Use the 5 key if\n" **"you don't want to move for a turn. Use the 0 key to turn on your\n" **"teleport-a-matic. And if you don't need to move for the rest of the level\n" **"type a period ('.') for your move. Otherwise 8 is up, 2 is down, 4 is left\n" **"and 6 is right and the corner keys are diagonal.\n\n" **"\nGood luck! Press any the ENTER key start.\n\n"); **getchar (); } int setup (int lv) { **int n, numleft; **numobj = numleft = 3 + lv * 4; **p = malloc ((numobj + 1) * sizeof (STUFF *)); **n = rand () % numleft; **while (numleft >= 0) { ****p[numleft] = malloc (sizeof (STUFF)); ****p[numleft]->loc = (numleft - numobj) ? ******numleft * (MAX_LOC / numobj) + rand() % (MAX_LOC / numobj) : MAX_LOC + W; ****p[numleft]->type = (n != numleft--) + 2; **} **return n; } void takedown (void) { **int n; **for (n = 0; n < numobj; n++) free (p[n]); **free (p); } int draw_floor (int l) { **int c, d, n, s = 1; **STUFF *temp; **putchar ('\n'); puts (msg); **putchar ('-'); for (c = W; c; c--) putchar ('-'); **for (d = 0; d <= numobj; d++) { ****for (n = numobj; d < numobj && n > d; n--) ******if (p[n]->loc < p[n - 1]->loc) { ********temp = p[n]; p[n] = p[n - 1]; p[n - 1] = temp; ******} ****if (d) { ******if (p[d]->loc == p[d - 1]->loc) {p[d]->type = p[d - 1]->type = 1;} ******else do { ********if (!(c % W)) printf ("|\n|"); ********putchar (icons[(p[d - 1]->loc == c) ? p[d - 1]->type : 0]); ******} while (++c < p[d]->loc && c < MAX_LOC); ******if (p[d - 1]->type == 3) s = 0; ****} **} **printf ("|\n|"); for (c = W; c; c--) putchar ('-'); printf ("-\n"); **sprintf (msg, "Level %d", l); **return s; } void gorobo (STUFF *pl) { **int n; **for (n = 0; n < numobj; n++) if (p[n]->type == 3) { ****if ((p[n]->loc % W) > (pl->loc % W)) p[n]->loc -= 1; **else if ((p[n]->loc % W) < (pl->loc % W)) p[n]->loc += 1; ****if ((p[n]->loc / W) > (pl->loc / W)) p[n]->loc -= W; **else if ((p[n]->loc / W) < (pl->loc / W)) p[n]->loc += W; **} } int main (int argc, char *argv[]) { **int n, m, w, level, d[9]; **char in; **STUFF *pl; **srand (time (NULL)); **intro (); **for (n = 0; n < 9; n++) d[n] = W * (1 - n / 3) + (n % 3 - 1); **level = (--argc) ? (atoi (argv[1]) - 1) : 0; **sprintf (msg, "Game Start!"); **do { ****pl = p[setup (++level)]; m = 1; ****draw_floor (level); ****do { ******printf ("Move : "); ******if (m) { ********do in = getche (); while (iscntrl (in)); ********if (in == '.') m = 0; ********else if (!(in - '0')) { **********gorobo (pl); pl->loc = rand () % MAX_LOC; **********sprintf (msg, "Stunned... Press ENTER"); draw_floor (level); **********getche (); **********gorobo (pl); ********} else if (in > '0' && in <= '9') { **********n = pl->loc + d[in - '1']; **********if (SQ((n % W) - (pl->loc % W)) < 2 && n < MAX_LOC && n >= 0) ************pl->loc = n; **********else sprintf (msg, "You were stopped by the wall."); **********gorobo(pl); ********} else sprintf (msg, "Invalad entry."); ******} else gorobo(pl); ******w = draw_floor (level); ****} while (!w && pl->type == 2); ****if ((w = pl->type) == 2) sprintf (msg, "level %d complete! ", level); ****takedown (); **} while (w == 2 && level < 10); **if (w == 2) printf ("You Win!"); **else printf ("You were captured by the robots at level %d\n", level); **exit (0); } Code:
Stunned... Press ENTER ------------------------------------------------------------------------------| |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |**************************************************************************** | |************************************************************ +************** | |**************************************************************************** | |**************************+**************************************************| |**************************************************************************** | |********************************+********************************************| |**************************************************** +**O********************| |**************************************************************************** | |**************************************************************************** | |********************************************** +**************************** | |**************************************************************************** | |**************************************************************************** | |**********************+******** #**** +********************+**************** | |------------------------------------------------------------------------------ I wanted to see how small I could get it. My goal was 1K, less than 1024 characters. After much work I got it. But oh the sacrifices that had to be made: Code:
#define q(a)(a)*(a) #define f(u,v) if((p[n]->l u 79)v(l->l u 79))p[n]->l typedef struct{int l,t;}z;z*p[99];int y;k(){int a=0,b,c=0,d=0;z*e;for(;a<=y;a++ ){for(b=y;a<y&&b>a;b--)if(p[b]->l<p[b-1]->l){e=p[b];p[b]=p[b-1];p[b-1]=e;}if(a) {if(p[a]->l==p[a-1]->l)p[a]->t=p[a-1]->t=3;else do{if(!(c%79))puts("");putchar( " O+#"[(p[a-1]->l==c)?p[a-1]->t:0]);}while(++c<p[a]->l&&c<=1817);d+=(p[a-1]->t ==2);}}return d;}main(){int n=0,m,w,e=0,d[9],i;z*l;srand(time(0));for(;n<99;n++ ){if(n<9)d[n]=79*(1-n/3)+(n%3-1);p[n]=malloc(sizeof(z));p[n]->l=1976;}do{y=m=7+ ++e*4;n=rand()%m;w=1817;while(m-->0){p[m]->l=w-=rand()%(w/(m+1))+1;p[m]->t=(n!= m)+1;}l=p[n];printf("\nLevel %d",e);m=k();do{if(m){do i=getche ();while(iscntrl (i));if(i=='.')m=0;else if(!(i-'0'))l->l=rand()%1817;else if(i>'0'&&i<='9'){n=l ->l + d[i-'1'];if(q((n%79)-(l->l%79))<2&&n<1817&&n>=0)l->l=n;}}for(n=0;n<y;n++) if(p[n]->t==2){f(%,>)-=1;else f(%,<)+=1;f(/,>)-=79;else f(/,<)+=79;}w=k();} while(w&&l->t==1);}while(!w);if(w)printf("Ended on %d\n",e);} In the 1k version there is technically no winning condition, so you can play until you are overwhelmed by sheer numbers. But Robotescape1k has a fixed max number of enemies on screen which, by the way, is 98 enemies and you makes 99. I was so crammed for space that adding one more digit to that number would have put me over. You exceed the maximum if you make it to level 24, which will consequenly crash the game. This however is an highly difficult thing to do, so consider the game beaten if you make it that far. The 1k restriction also introduced a bug concerning the conditions of winning a level where it checks to see if all the robots are dead before checking if you are. In other words, if the last robot(s) kill themselves upon you, you still win and move on to the next level. Ah well, such is the price of this sort of pursuit. However, it can be a strange sort of satisfying to win by kamikaze / jihad / whatever. .:EDIT:. CRA...UD. I wrote this ages ago and just noticed in the last line that "if(w)" can be removed, saving me 5 characters meaning I could take the game up to 9999999 on screen characters, more than the screen can handle, erradicating the level 24 cap. Meh, screw it. I never survived past level 16 myself anyways. |
||
|
|
09-06-2006, 04:25 PM | #7 | ||
Join Date: Feb 2006
Location: Vienna, Austria
Posts: 74
|
I would give a Toe to understand this.. :wallbash:
|
||
|
|
10-06-2006, 12:41 AM | #8 | ||
Join Date: May 2005
Location: Aurora, United States
Posts: 606
|
Poll at the end of this post, don't forget to vote!
<div class='quotetop'>QUOTE(U-Boat Commander David @ Jun 9 2006, 04:25 PM) [snapback]235479[/snapback]</div> Quote:
Sound like too much work? Hey, you wanted to give up a toe. If I just take the pinky toe you have to learn how to walk all over. You think you don't need it, but it's got so much to do with balance. Trust me, typing a few tried and tested programs is easier than learning how to walk again. So what program should I do next? Maybe I'll let the people decide. Here's the list of possible choices:
|
||
|
|
10-06-2006, 07:54 AM | #9 | ||
Join Date: Dec 2004
Location: Eindhoven, Netherlands
Posts: 1,508
|
May I ask why you chose C and it's old-fashioned procedural programming paradigm over more modern ones such as OO? Mind you, I can appreciate the beauty in an obfuscated piece of C-code (although as a Java guy, I really hate doing memory managment myself), I was just curious.
|
||
|
|
10-06-2006, 10:13 AM | #10 | ||
Join Date: Jun 2004
Location: Jan Mayen, Svalbard and Jan Mayen
Posts: 2,167
|
4 in a row please.
Interrested in seeing the ai part especially. Reup OO is a way solving the problem. not the way. there is nothing wrong with procedural programming I think. OO was overrated in its hype. (which fortuntaly has a passed a bit)
__________________
Flowing with the stream of life |
||
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Happy Birthday Guesst | Japo | Birthdays & Celebrations | 8 | 06-07-2007 09:50 AM |
Happy Birthday, Guesst | Shrek | Blah, blah, blah... | 10 | 08-07-2006 09:31 AM |
Thread Tools | |
Display Modes | |
|
|
||
  |