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

#include "adv_func.h"
#include "adv_io.h"
#include "adv_magic.h"
#include "adv_readdb.h"
#include "adv_struc.h"  
#include "adv_util.h"
#include "adven2.h"
 
void calculate_score(BOOL scorng)
{
// EXIT CODE.  WILL EVENTUALLY INCLUDE SCORING.  FOR NOW, HOWEVER, ...

// THE PRESENT SCORING ALGORITHM IS AS FOLLOWS:
//    OBJECTIVE:          POINTS:        PRESENT TOTAL POSSIBLE:
// GETTING WELL INTO CAVE   25                    25
// EACH TREASURE < CHEST    12                    60
// TREASURE CHEST ITSELF    14                    14
// EACH TREASURE > CHEST    16                   144
// SURVIVING             (MAX-NUM)*10             30
// NOT QUITTING              4                     4
// REACHING "CLOSNG"        25                    25
// "CLOSED": QUIT/KILLED    10
//           KLUTZED        25
//           WRONG WAY      30
//           SUCCESS        45                    45
// CAME TO WITT"S END        1                     1
// ROUND OUT THE TOTAL       2                     2
//                                      TOTAL:   350
// (POINTS CAN ALSO BE DEDUCTED FOR USING HINTS.)

      int i, k;
      char kk[16];    // probably could be shorter, but might be useful

      gm.score = 0;
      gm.mxscor = 0;

// FIRST TALLY UP THE TREASURES.  MUST BE IN BUILDING AND NOT BROKEN.
// GIVE THE POOR GUY 2 POINTS JUST FOR FINDING EACH TREASURE.

      for (i = 50;i<=gm.maxtrs;i++)
      {
        if (gm.ptext[i] != 0)
        {
          if (i > gm.chest) k = 16;
          else if (i  ==  gm.chest) k = 14;
          else k = 12;
          if (gm.prop[i] >=  0) gm.score = gm.score+2;
          if (gm.place[i]  ==  3 && gm.prop[i]  ==  0) gm.score = gm.score+k-2;
          gm.mxscor = gm.mxscor+k;
        }
      }
      // printf("Counting treasures, score so far is %i, max is %i\n",gm.score,gm.mxscor);

// NOW LOOK AT HOW HE FINISHED AND HOW FAR HE GOT.  MAXDIE AND NUMDIE TELL US
// HOW WELL HE SURVIVED.  GAVEUP SAYS WHETHER HE EXITED VIA QUIT.  DFLAG WILL
// TELL US IF HE EVER GOT SUITABLY DEEP INTO THE CAVE.  CLOSNG STILL INDICATES
// WHETHER HE REACHED THE ENDGAME.  AND IF HE GOT AS FAR AS "CAVE CLOSED"
// (INDICATED BY "CLOSED"), THEN BONUS IS ZERO FOR MUNDANE EXITS OR 133, 134,
// 135 IF HE BLEW IT (SO TO SPEAK).

      gm.score = gm.score+(gm.maxdie-gm.numdie)*10;
      gm.mxscor = gm.mxscor+gm.maxdie*10;
      // printf("For survival, score so far is %i, max is %i\n",gm.score,gm.mxscor);
      if ( ! (gm.scorng || gm.gaveup))
        gm.score = gm.score+4;
      gm.mxscor = gm.mxscor+4;
      // printf("For giving up, score so far is %i, max is %i\n",gm.score,gm.mxscor);
      if (gm.dflag != 0)
        gm.score = gm.score+25;
      gm.mxscor = gm.mxscor+25;
      // printf("For getting far enough, score so far is %i, max is %i\n",gm.score,gm.mxscor);
      if (gm.closng)
        gm.score = gm.score+25;
      gm.mxscor = gm.mxscor+25;
      // printf("For getting to end game, score so far is %i, max is %i\n",gm.score,gm.mxscor);
      if (gm.closed)
      {
        if (gm.bonus  ==  0) gm.score = gm.score + 10;
        if (gm.bonus  ==  135) gm.score = gm.score + 25;
        if (gm.bonus  ==  134) gm.score = gm.score + 30;
        if (gm.bonus  ==  133) gm.score = gm.score + 45;
      }
      gm.mxscor = gm.mxscor+45;
      // printf("Counting how he finished, score so far is %i, max is %i\n",gm.score,gm.mxscor);

// DID HE COME TO WITT"S END AS HE SHOULD?

      if (gm.place[gm.magzin]  ==  108)
        gm.score = gm.score + 1;
      gm.mxscor = gm.mxscor + 1;
      // printf("Counting Witt's End, score so far is %i, max is %i\n",gm.score,gm.mxscor);

// ROUND IT OFF.

      gm.score = gm.score+2;
      gm.mxscor = gm.mxscor+2;
      // printf("Rounding off, score so far is %i, max is %i\n",gm.score,gm.mxscor);

// DEDUCT POINTS FOR HINTS.  HINTS < 4 ARE SPECIAL; SEE DATABASE DESCRIPTION.

      for (i = 1;i<=gm.hntmax;i++)
        if (gm.hinted[i])
          gm.score = gm.score-gm.hints[i][2];
      // printf("Allowing for hints, score so far is %i, max is %i\n",gm.score,gm.mxscor);

// RETURN TO SCORE COMMAND IF THAT"S WHERE WE CAME FROM.
//   scorng == TRUE if he asked for his score in a non-terminating situation
      if (scorng) return; // goto 8241;

// THAT SHOULD BE GOOD ENOUGH.  LET"S TELL HIM ALL ABOUT IT.

      printf("YOU SCORED %i OUT OF A POSSIBLE %i, USING %i TURNS.\n",
             gm.score,gm.mxscor,gm.turns);

      for (i = 1;i<=gm.clsses;i++)
      {
        if (gm.cval[i] >=  gm.score)
        {
          speak(gm.ctext[i]);
          if (i != gm.clsses)
          {
            k = gm.cval[i]+1-gm.score;
            strcpy(kk,(k == 1)?". ":"S.");
            printf("TO ACHIEVE THE NEXT HIGHER RATING, YOU NEED %i MORE POINT%s\n",
                   k,kk);
          }
          else printf("TO ACHIEVE THE NEXT HIGHER RATING WOULD BE A NEAT TRICK!\nCONGRATULATIONS!!\n");
          break;
        }
      }
      // printf("YOU JUST WENT OFF MY SCALE!!\n");

} // end calculate_score

void setup_stg_room(void)
{
// ONCE HE"S PANICKED, AND CLOCK2 HAS RUN OUT, WE COME HERE TO SET UP THE
// STORAGE ROOM.  THE ROOM HAS TWO LOCS, HARDWIRED AS 115 (NE) AND 116 (SW).
// AT THE NE END, WE PLACE EMPTY BOTTLES, A NURSERY OF PLANTS, A BED OF
// OYSTERS, A PILE OF LAMPS, RODS WITH STARS, SLEEPING DWARVES, AND HIM.  AND
// THE SW END WE PLACE GRATE OVER TREASURES, SNAKE PIT, COVEY OF CAGED BIRDS,
// MORE RODS, AND PILLOWS.  A MIRROR STRETCHES ACROSS ONE WALL.  MANY OF THE
// OBJECTS COME FROM KNOWN LOCATIONS AND/OR STATES (E.G. THE SNAKE IS KNOWN TO
// HAVE BEEN DESTROYED AND NEEDN"T BE CARRIED AWAY FROM ITS OLD "PLACE"),
// MAKING THE VARIOUS OBJECTS BE HANDLED DIFFERENTLY.  WE ALSO DROP ALL OTHER
// OBJECTS HE MIGHT BE CARRYING (LEST HE HAVE SOME WHICH COULD CAUSE TROUBLE,
// SUCH AS THE KEYS).  WE DESCRIBE THE FLASH OF LIGHT AND TRUNDLE BACK.

      int i;

      gm.prop[gm.bottle] = put(gm.bottle,115,1);
      gm.prop[gm.plant] = put(gm.plant,115,0);
      gm.prop[gm.oyster] = put(gm.oyster,115,0);
      gm.prop[gm.lamp] = put(gm.lamp,115,0);
      gm.prop[gm.rod] = put(gm.rod,115,0);
      gm.prop[gm.dwarf] = put(gm.dwarf,115,0);
      gm.loc = 115;
      gm.oldloc = 115;
      gm.newloc = 115;

// LEAVE THE GRATE WITH NORMAL (NON-NEGATIVE PROPERTY).

      gm.foo = put(gm.grate,116,0);
      gm.prop[gm.snake] = put(gm.snake,116,1);
      gm.prop[gm.bird] = put(gm.bird,116,1);
      gm.prop[gm.cage] = put(gm.cage,116,0);
      gm.prop[gm.rod2] = put(gm.rod2,116,0);
      gm.prop[gm.pillow] = put(gm.pillow,116,0);

      gm.prop[gm.mirror] = put(gm.mirror,115,0);
      gm.fixed[gm.mirror] = 116;

      for (i = 1;i<=100;i++)
        if (toting(i)) 
          dstroy(i);

      rspeak(132);
      gm.closed =  TRUE;
}

void cave_closing(void)
{
// CAVE CLOSING AND SCORING


// THESE SECTIONS HANDLE THE CLOSING OF THE CAVE.  THE CAVE CLOSES "CLOCK1"
// TURNS AFTER THE LAST TREASURE HAS BEEN LOCATED (INCLUDING THE PIRATE"S
// CHEST, WHICH MAY OF COURSE NEVER SHOW UP).  NOTE THAT THE TREASURES NEED NOT
// HAVE BEEN TAKEN YET, JUST LOCATED.  HENCE CLOCK1 MUST BE LARGE ENOUGH TO GET
// OUT OF THE CAVE (IT ONLY TICKS WHILE INSIDE THE CAVE).  WHEN IT HITS ZERO,
// WE BRANCH TO 10000 TO START CLOSING THE CAVE, AND THEN SIT BACK AND WAIT FOR
// HIM TO TRY TO GET OUT.  IF HE DOESN"T WITHIN CLOCK2 TURNS, WE CLOSE THE
// CAVE; IF HE DOES TRY, WE ASSUME HE PANICS, AND GIVE HIM A FEW ADDITIONAL
// TURNS TO GET FRANTIC BEFORE WE CLOSE.  WHEN CLOCK2 HITS ZERO, WE BRANCH TO
// 11000 TO TRANSPORT HIM INTO THE FINAL PUZZLE.  NOTE THAT THE PUZZLE DEPENDS
// UPON ALL SORTS OF RANDOM THINGS.  FOR INSTANCE, THERE MUST BE NO WATER OR
// OIL, SINCE THERE ARE BEANSTALKS WHICH WE DON"T WANT TO BE ABLE TO WATER,
// SINCE THE CODE CAN"T HANDLE IT.  ALSO, WE CAN HAVE NO KEYS, SINCE THERE IS A
// GRATE (HAVING MOVED THE FIXED OBJECT!) THERE SEPARATING HIM FROM ALL THE
// TREASURES.  MOST OF THESE PROBLEMS ARISE FROM THE USE OF NEGATIVE PROP
// NUMBERS TO SUPPRESS THE OBJECT DESCRIPTIONS UNTIL HE"S ACTUALLY MOVED THE
// OBJECTS.

// WHEN THE FIRST WARNING COMES, WE LOCK THE GRATE, DESTROY THE BRIDGE, KILL
// ALL THE DWARVES (AND THE PIRATE), REMOVE THE TROLL AND BEAR (UNLESS DEAD),
// AND SET "CLOSNG" TO TRUE.  LEAVE THE DRAGON; TOO MUCH TROUBLE TO MOVE IT.
// FROM NOW UNTIL CLOCK2 RUNS OUT, HE CANNOT UNLOCK THE GRATE, MOVE TO ANY
// LOCATION OUTSIDE THE CAVE (LOC<9), OR CREATE THE BRIDGE.  NOR CAN HE BE
// RESURRECTED IF HE DIES.  NOTE THAT THE SNAKE IS ALREADY GONE, SINCE HE GOT
// TO THE TREASURE ACCESSIBLE ONLY VIA THE HALL OF THE MT. KING.  ALSO, HE"S
// BEEN IN GIANT ROOM (TO GET EGGS), SO WE CAN REFER TO IT.  ALSO ALSO, HE"S
// GOTTEN THE PEARL, SO WE KNOW THE BIVALVE IS AN OYSTER.  *AND*, THE DWARVES
// MUST HAVE BEEN ACTIVATED, SINCE WE"VE FOUND CHEST.

      int i;

      gm.prop[gm.grate] = 0;
      gm.prop[gm.fissur] = 0;
      for (i = 1;i<=6;i++)
      { 
        gm.dseen[i] =  FALSE;
        gm.dloc[i] = 0;
      }
      move(gm.troll,0);
      move(gm.troll+100,0);
      move(gm.troll2,gm.plac[gm.troll]);
      move(gm.troll2+100,gm.fixd[gm.troll]);
      juggle(gm.chasm);
      if (gm.prop[gm.bear] != 3) dstroy(gm.bear);
      gm.prop[gm.chain] = 0;
      gm.fixed[gm.chain] = 0;
      gm.prop[gm.axe] = 0;
      gm.fixed[gm.axe] = 0;
      rspeak(129);
      gm.clock1 = -1;
      gm.closng =  TRUE;
}
