LCOV - code coverage report
Current view: top level - open-adventure - score.c (source / functions) Hit Total Coverage
Test: advent.info Lines: 72 72 100.0 %
Date: 2024-02-15 17:57:54 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.14