LCOV - code coverage report
Current view: top level - open-adventure - score.c (source / functions) Hit Total Coverage
Test: advent.info Lines: 70 70 100.0 %
Date: 2018-03-12 03:52:32 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Scoring and wrap-up.
       3             :  *
       4             :  * Copyright (c) 1977, 2005 by Will Crowther and Don Woods
       5             :  * Copyright (c) 2017 by Eric S. Raymond
       6             :  * SPDX-License-Identifier: BSD-2-clause
       7             :  */
       8             : #include <stdlib.h>
       9             : #include "advent.h"
      10             : #include "dungeon.h"
      11             : 
      12             : static int mxscor;      /* ugh..the price for having score() not exit. */
      13             : 
      14          92 : long score(enum termination mode)
      15             : /* mode is 'scoregame' if scoring, 'quitgame' if quitting, 'endgame' if died
      16             :  * or won */
      17             : {
      18          92 :     int score = 0;
      19             : 
      20             :     /*  The present scoring algorithm is as follows:
      21             :      *     Objective:          Points:        Present total possible:
      22             :      *  Getting well into cave   25                    25
      23             :      *  Each treasure < chest    12                    60
      24             :      *  Treasure chest itself    14                    14
      25             :      *  Each treasure > chest    16                   224
      26             :      *  Surviving             (MAX-NUM)*10             30
      27             :      *  Not quitting              4                     4
      28             :      *  Reaching "game.closng"   25                    25
      29             :      *  "Closed": Quit/Killed    10
      30             :      *            Klutzed        25
      31             :      *            Wrong way      30
      32             :      *            Success        45                    45
      33             :      *  Came to Witt's End        1                     1
      34             :      *  Round out the total       2                     2
      35             :      *                                       TOTAL:   430
      36             :      *  Points can also be deducted for using hints or too many turns, or for
      37             :      *  saving intermediate positions. */
      38             : 
      39             :     /*  First tally up the treasures.  Must be in building and not broken.
      40             :      *  Give the poor guy 2 points just for finding each treasure. */
      41          92 :     mxscor = 0;
      42        6440 :     for (int i = 1; i <= NOBJECTS; i++) {
      43        6348 :         if (!objects[i].is_treasure)
      44        4508 :             continue;
      45        1840 :         if (objects[i].inventory != 0) {
      46        1840 :             int k = 12;
      47        1840 :             if (i == CHEST)
      48          92 :                 k = 14;
      49        1840 :             if (i > CHEST)
      50        1288 :                 k = 16;
      51        1840 :             if (game.prop[i] > STATE_NOTFOUND)
      52         737 :                 score += 2;
      53        1840 :             if (game.place[i] == LOC_BUILDING && game.prop[i] == STATE_FOUND)
      54         505 :                 score += k - 2;
      55        1840 :             mxscor += k;
      56             :         }
      57             :     }
      58             : 
      59             :     /*  Now look at how he finished and how far he got.  NDEATHS and
      60             :      *  game.numdie tell us how well he survived.  game.dflag will tell us
      61             :      *  if he ever got suitably deep into the cave.  game.closng still
      62             :      *  indicates whether he reached the endgame.  And if he got as far as
      63             :      *  "cave closed" (indicated by "game.closed"), then bonus is zero for
      64             :      *  mundane exits or 133, 134, 135 if he blew it (so to speak). */
      65          92 :     score += (NDEATHS - game.numdie) * 10;
      66          92 :     mxscor += NDEATHS * 10;
      67          92 :     if (mode == endgame)
      68          18 :         score += 4;
      69          92 :     mxscor += 4;
      70          92 :     if (game.dflag != 0)
      71          66 :         score += 25;
      72          92 :     mxscor += 25;
      73          92 :     if (game.closng)
      74          13 :         score += 25;
      75          92 :     mxscor += 25;
      76          92 :     if (game.closed) {
      77           9 :         if (game.bonus == none)
      78           5 :             score += 10;
      79           9 :         if (game.bonus == splatter)
      80           1 :             score += 25;
      81           9 :         if (game.bonus == defeat)
      82           1 :             score += 30;
      83           9 :         if (game.bonus == victory)
      84           2 :             score += 45;
      85             :     }
      86          92 :     mxscor += 45;
      87             : 
      88             :     /* Did he come to Witt's End as he should? */
      89          92 :     if (game.place[MAGAZINE] == LOC_WITTSEND)
      90          13 :         score += 1;
      91          92 :     mxscor += 1;
      92             : 
      93             :     /* Round it off. */
      94          92 :     score += 2;
      95          92 :     mxscor += 2;
      96             : 
      97             :     /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */
      98        1012 :     for (int i = 0; i < NHINTS; i++) {
      99         920 :         if (game.hinted[i])
     100          10 :             score = score - hints[i].penalty;
     101             :     }
     102          92 :     if (game.novice)
     103           2 :         score -= 5;
     104          92 :     if (game.clshnt)
     105           1 :         score -= 10;
     106          92 :     score = score - game.trnluz - game.saved;
     107             : 
     108             :     /* Return to score command if that's where we came from. */
     109          92 :     if (mode == scoregame) {
     110           3 :         rspeak(GARNERED_POINTS, score, mxscor, game.turns, game.turns);
     111             :     }
     112             : 
     113          92 :     return score;
     114             : }
     115             : 
     116          89 : void terminate(enum termination mode)
     117             : /* End of game.  Let's tell him all about it. */
     118             : {
     119          89 :     long points = score(mode);
     120             : 
     121          89 :     if (points + game.trnluz + 1 >= mxscor && game.trnluz != 0)
     122           1 :         rspeak(TOOK_LONG);
     123          89 :     if (points + game.saved + 1 >= mxscor && game.saved != 0)
     124           2 :         rspeak(WITHOUT_SUSPENDS);
     125          89 :     rspeak(TOTAL_SCORE, points, mxscor, game.turns, game.turns);
     126         283 :     for (int i = 1; i <= (long)NCLASSES; i++) {
     127         282 :         if (classes[i].threshold >= points) {
     128          88 :             speak(classes[i].message);
     129          88 :             i = classes[i].threshold + 1 - points;
     130          88 :             rspeak(NEXT_HIGHER, i, i);
     131          88 :             exit(EXIT_SUCCESS);
     132             :         }
     133             :     }
     134           1 :     rspeak(OFF_SCALE);
     135           1 :     rspeak(NO_HIGHER);
     136           1 :     exit(EXIT_SUCCESS);
     137             : }
     138             : 
     139             : /* end */

Generated by: LCOV version 1.13