|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 14429 (0x385d) Types: TextFile Names: »gamedev.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/X/Xwanderer/gamedev.c«
#include "wand_head.h" #define viable(x,y) ((screen[y][x] == ' ') || (screen[y][x] == ':') ||\ (screen[y][x] == '@') || (screen[y][x] == '+')) && (y >= 0) &&\ (x >= 0) && (y < NOOFROWS) && (x < ROWLEN) typedef struct mon_rec { int x,y,mx,my; char under; struct mon_rec *next; }; typedef struct { int d[2] } direction; extern void draw_symbol(); extern void display(); extern int fall(); extern void map(); /* Add a spirit to the chain */ struct mon_rec *make_monster(x,y) int x,y; { struct mon_rec *malloc(), *monster; if((monster = malloc(sizeof(struct mon_rec))) == NULL) return NULL; monster->x = x; monster->y = y; monster->mx = 1; /* always start moving RIGHT. (fix later) */ monster->my = 0; monster->under = ' '; monster->next = NULL; return monster; } /* 'follow lefthand wall' algorithm for sprites */ direction new_direction(screen,x,y,bx,by) int x,y,bx,by; char screen[NOOFROWS][ROWLEN+1]; { direction out; if(viable((x+by),(y-bx))) { out.d[0] = by; out.d[1] = -bx; return out; } if(viable((x+bx),(y+by))) { out.d[0] = bx; out.d[1] = by; return out; } if(viable((x-by),(y+bx))) { out.d[0] = -by; out.d[1] = bx; return out; } if(viable((x-bx),(y-by))) { out.d[0] = -bx; out.d[1] = -by; return out; } out.d[0] = -bx; out.d[1] = -by; return out; } /* Actual game function - Calls fall() to move boulders and arrows recursively */ char *playscreen(screen,score,bell,maxmoves,keys) int maxmoves, *bell, *score; char screen[NOOFROWS][ROWLEN+1], keys[6]; { int x,y,nx,ny,deadyet =0, sx = -1,sy = -1,tx = -1,ty = -1,lx = 0,ly = 0,mx = -1,my = -1, bx, by, nbx, nby, newnum, num = 1, diamonds = 0, nf = 0,hd ,vd ,xdirection,ydirection; char (*frow)[ROWLEN+1] = screen, ch, buffer[25], howdead[25]; direction new_disp; struct mon_rec *monster,*mon_ptr, *current; mon_ptr = NULL; for(x=0;x<=ROWLEN;x++) for(y=0;y<NOOFROWS;y++) { if((screen[y][x] == '*')||(screen[y][x] == '+')) diamonds++; if(screen[y][x] == 'A') /* note teleport arrival point & */ { /* replace with space */ tx = x; ty = y; screen[y][x] = ' '; } if(screen[y][x] == '@') { sx = x; sy = y; } if(screen[y][x] == 'M') /* Put megamonster in */ { mx = x; my = y; } if(screen[y][x] == 'S') /* link small monster to pointer chain */ { if((monster = make_monster(x,y)) == NULL) { strcpy(howdead,"running out of memory"); return howdead; } if(mon_ptr == NULL) current = mon_ptr = monster; else current = current->next = monster; } if(screen[y][x] == '-') screen[y][x] = ' '; }; x=sx; y=sy; if((x == -1)&&(y == -1)) /* no start position in file ? */ { strcpy(howdead,"no start position!"); return(howdead); } move(0,48); (void) addstr("Score\t Diamonds"); move(1,48); (void) addstr("\tFound\tTotal"); move(3,48); (void) sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); move(6,48); (void) sprintf(buffer,"Current screen %d",num); (void) addstr(buffer); if(maxmoves != 0) (void) sprintf(buffer,"Moves remaining = %d ",maxmoves); else { (void) strcpy(buffer," Unlimited moves "); maxmoves = -1; }; move(15,48); (void) addstr(buffer); if(mx != -1) /* tell player if monster exists */ draw_symbol(48,10,'M'); else draw_symbol(48,10,' '); display(sx,sy,frow,*score); /* ACTUAL GAME FUNCTION - Returns method of death in string */ while(deadyet == 0) { ch = getchar(); nx=x; ny=y; if(ch == keys[3]) nx++; if(ch == keys[2]) nx--; if((ch == keys[1]) && (y<(NOOFROWS-1))) ny++; if(ch == keys[0]) ny--; if(ch == '1') { move(10,45); *bell = 1; (void) addstr("Bell ON "); printf("\007"); move(16,0); refresh(); } if(ch == '0') { *bell = 0; move(10,45); (void) addstr("Bell OFF"); move(16,0); refresh(); } if(ch == '~') /* level jump */ { strcpy(howdead,"~~"); return howdead; } if(ch == '!') { map(frow); display(sx,sy,frow,*score); } if(ch == 'q') { strcpy(howdead,"quitting the game"); return howdead; } if(screen[ny][nx] == 'C') { screen[ny][nx] = ':'; *score+=4; if (*bell) printf("\007"); if(maxmoves != -1) maxmoves+=250; } switch(screen[ny][nx]) { case '@': break; case '*': *score+=9; if (*bell) printf("\007"); nf++; case ':': *score+=1; move(3,48); sprintf(buffer,"%d\t %d",*score,nf); (void) addstr(buffer); case ' ': screen[y][x] = ' '; screen[ny][nx] = '@'; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); if(deadyet ==0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if((deadyet ==0) && (nx != (x+1))) deadyet = fall(&mx,&my,x+1,y,sx,sy,screen,howdead); if((deadyet ==0) && (nx != (x-1))) deadyet = fall(&mx,&my,x-1,y,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x+1,y+1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x-1,y+1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x-1,y-1,sx,sy,screen,howdead); if((deadyet ==0) && (ny != (y+1))) deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead); if((deadyet ==0) && (ny != (y-1))) deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead); if(deadyet ==0) deadyet = fall(&mx,&my,x+1,y-1,sx,sy,screen,howdead); move(16,0); refresh(); y = ny; x = nx; break; case 'O': if(screen[y][nx*2-x] == 'M') { screen[y][nx*2-x] = ' '; mx = my = -1; if(*bell) printf("\007"); *score+=100; move(3,48); sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); } if(screen[y][nx*2-x] == ' ') { screen[y][nx*2-x] = 'O'; screen[y][x] = ' '; screen[ny][nx] = '@'; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); draw_symbol((nx*2-x-sx+5)*3,(y-sy+3)*2,'O'); if(deadyet==0) deadyet = fall(&mx,&my,nx*2-x,y+1,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x*2-nx,y,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y-1,sx,sy,screen,howdead); if(deadyet==0) deadyet = fall(&mx,&my,x,y+1,sx,sy,screen,howdead); move(16,0); refresh(); y = ny; x = nx; } break; case '<': case '>': if(screen[ny*2-y][x] == 'M') { screen[ny*2-y][x] = ' '; mx = my = -1; if(*bell) printf("\007"); *score+=100; move(3,48); sprintf(buffer,"%d\t %d\t %d ",*score,nf,diamonds); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); } if(screen[ny*2-y][x] == ' ') { screen[ny*2-y][x] = screen[ny][nx]; screen[y][x] = ' '; screen[ny][nx] = '@'; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); draw_symbol((x-sx+5)*3,(ny*2-y-sy+3)*2,screen[ny*2-y][x]); if(deadyet == 0) deadyet = fall(&mx,&my,x,y,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x-1,(ny>y)?y:(y-1),sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x+1,(ny>y)?y:(y-1),sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x-1,ny*2-y,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,x+1,ny*2-y,sx,sy,screen,howdead); move(16,0); refresh(); y = ny; x = nx; } break; case '!': strcpy(howdead,"an exploding landmine"); deadyet = 1; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); draw_symbol((nx-sx+5)*3,(ny-sy+3)*2,'@'); move(16,0); refresh(); break; case 'X': if(nf == diamonds) { *score+=250; if(*bell) printf("\007"); strcpy(howdead,"finishing the screen."); return howdead; } break; case 'T': if(tx > -1) { screen[ny][nx] = ' '; screen[y][x] = ' '; lx = x; ly = y; y = ty; x = tx; screen[y][x] = '@'; sx = x; sy = y; *score += 20; display(sx,sy,frow,*score); deadyet = fall(&mx,&my,nx,ny,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx,ly,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx+1,ly-1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx+1,ly+1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx-1,ly+1,sx,sy,screen,howdead); if(deadyet == 0) deadyet = fall(&mx,&my,lx-1,ly-1,sx,sy,screen,howdead); move(16,0); refresh(); } else { screen[ny][nx] = ' '; printf("Teleport out of order"); } break; case 'M': strcpy(howdead,"a hungry monster"); deadyet = 1; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); move(16,0); refresh(); break; case 'S': strcpy(howdead,"walking into a monster"); deadyet = 1; draw_symbol((x-sx+5)*3,(y-sy+3)*2,' '); move(16,0); refresh(); break; default: break; } if((y == ny) && (x == nx) && (maxmoves>0)) { (void) sprintf(buffer,"Moves remaining = %d ",--maxmoves); move(15,48); (void) addstr(buffer); } if(maxmoves == 0) { addstr("You ran out of time! \007\007"); refresh(); } if ((x<(sx-3))&& (deadyet ==0)) /* screen scrolling if necessary */ { sx-=6; if(sx < 4) sx = 4; display(sx,sy,frow,*score); } if ((y<(sy-2))&& (deadyet == 0)) { sy-=5; if(sy < 2) sy = 2; display(sx,sy,frow,*score); } if ((x>(sx+3)) && (deadyet == 0)) { sx+=6; if(sx>(ROWLEN -5)) sx = ROWLEN -5; display(sx,sy,frow,*score); } if ((y>(sy+2))&& (deadyet ==0)) { sy+=5; if(sy > (NOOFROWS-3)) sy = NOOFROWS -3; display(sx,sy,frow,*score); } /* MONSTER SECTION - Put all these in a separate function later */ if(mx == -2) /* has the monster been killed ? */ { *score+=100; mx = my = -1; move(3,48); sprintf(buffer,"%d\t %d\t",*score,nf); (void) addstr(buffer); draw_symbol(48,10,' '); move(16,0); refresh(); } if(mx != -1) /* no? then move that monster ! */ { screen[my][mx] = ' '; if(mx>x) xdirection = -1; else xdirection = 1; if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6))) draw_symbol((mx-sx+5)*3,(my-sy+3)*2,' '); if((hd = (mx-x))<0) hd = -hd; if((vd = (my-y))<0) vd = -vd; if((hd>vd)&&((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@'))) mx+=xdirection; else { if(my>y) ydirection = -1; else ydirection = 1; if((screen[my+ydirection][mx] == ' ')||(screen[my+ydirection][mx] == '@')) my+=ydirection; else if((screen[my][mx+xdirection] == ' ')||(screen[my][mx+xdirection] == '@')) mx+=xdirection; } if((my<(sy+4))&&(my>(sy-4))&&(mx<(sx+6))&&(mx>(sx-6))) draw_symbol((mx-sx+5)*3,(my-sy+3)*2,'M'); if(screen[my][mx] == '@') /* ha! gottim! */ { strcpy(howdead,"a hungry monster"); move(16,0); refresh(); deadyet = 1; screen[my][mx] = 'M'; } screen[my][mx] = 'M'; move(16,0); refresh(); } current = monster = mon_ptr; while((monster != NULL)&&(!deadyet))/* deal with those little monsters */ { new_disp = new_direction(screen, monster->x, monster->y, monster->mx, monster->my ); screen[monster->y][monster->x] = monster->under; if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,monster->under); if(monster->under == ' ') deadyet = deadyet | fall(&mx,&my,monster->x,monster->y,sx,sy,screen,howdead); monster->mx = new_disp.d[0]; monster->my = new_disp.d[1]; monster->x += monster->mx; monster->y += monster->my; monster->under = screen[monster->y][monster->x]; screen[monster->y][monster->x] = 'S'; /* move into new space */ if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'S'); if(monster->under == '@') /* monster hit you? */ { strcpy(howdead,"the little monsters"); move(16,0); refresh(); deadyet = 1; monster->under = ' '; } if(monster->under == '+') /* monster hit cage? */ { *score +=20; if(*bell) printf("\007"); if(monster == mon_ptr) /* remove from chain */ mon_ptr = mon_ptr->next; else current->next = monster-> next; screen[monster->y][monster->x] = '*'; if((monster->y < (sy+4)) && (monster->y > (sy-4)) && (monster->x < (sx+6)) && (monster->x > (sx-6))) draw_symbol((monster->x-sx+5)*3,(monster->y-sy+3)*2,'*'); } if(monster->under == 'S') monster->under = ' '; if(monster != mon_ptr) current = current->next; monster = monster->next; move(16,0); refresh(); } if(deadyet != 0) { move(16,0); addstr("You are dead, killed by "); addstr(howdead); addstr("\nPress any key to come back to life."); refresh(); ch = getchar(); move(16,0); addstr(" \n"); addstr(" "); move(16,0); refresh(); deadyet = 0; } } return(howdead); }