Magic-numnber elimination.
[open-adventure.git] / score.c
1 #include <stdlib.h>
2 #include "advent.h"
3 #include "database.h"
4 #include "newdb.h"
5
6 /*
7  * scoring and wrap-up
8  */
9
10 void score(enum termination mode)
11 /* mode is 'report' if scoring, 'quit' if quitting, 'end' if died or won */
12 {
13     long score = 0, mxscor = 0;
14
15     /*  The present scoring algorithm is as follows:
16      *     Objective:          Points:        Present total possible:
17      *  Getting well into cave   25                    25
18      *  Each treasure < chest    12                    60
19      *  Treasure chest itself    14                    14
20      *  Each treasure > chest    16                   224
21      *  Surviving             (MAX-NUM)*10             30
22      *  Not quitting              4                     4
23      *  Reaching "game.closng"   25                    25
24      *  "Closed": Quit/Killed    10
25      *            Klutzed        25
26      *            Wrong way      30
27      *            Success        45                    45
28      *  Came to Witt's End        1                     1
29      *  Round out the total       2                     2
30      *                                       TOTAL:   430
31      *  Points can also be deducted for using hints or too many turns, or for
32      *  saving intermediate positions. */
33
34     /*  First tally up the treasures.  Must be in building and not broken.
35      *  Give the poor guy 2 points just for finding each treasure. */
36     for (long i=MINTRS; i<=MAXTRS; i++) {
37         if(object_descriptions[i].inventory != 0) {
38             long k=12;
39             if(i == CHEST)k=14;
40             if(i > CHEST)k=16;
41             if(game.prop[i] >= 0)
42                 score += 2;
43             if(game.place[i] == 3 && game.prop[i] == 0)
44                 score += k-2;
45             mxscor += k;
46         }
47     }
48
49     /*  Now look at how he finished and how far he got.  MAXDIE and
50      *  game.numdie tell us how well he survived.  game.dflag will tell us
51      *  if he ever got suitably deep into the cave.  game.closng still
52      *  indicates whether he reached the endgame.  And if he got as far as
53      *  "cave closed" (indicated by "game.closed"), then bonus is zero for
54      *  mundane exits or 133, 134, 135 if he blew it (so to speak). */
55     score += (MAXDIE-game.numdie)*10;
56     mxscor += MAXDIE*10;
57     if(mode == endgame)
58         score += 4;
59     mxscor += 4;
60     if(game.dflag != 0)score += 25;
61     mxscor += 25;
62     if(game.closng)score += 25;
63     mxscor += 25;
64     if(game.closed) {
65         if(game.bonus == 0)
66             score += 10;
67         if(game.bonus == 135)
68             score += 25;
69         if(game.bonus == 134)
70             score += 30;
71         if(game.bonus == 133)
72             score += 45;
73     }
74     mxscor += 45;
75
76     /* Did he come to Witt's End as he should? */
77     if(game.place[MAGZIN] == 108)
78         score += 1;
79     mxscor += 1;
80
81     /* Round it off. */
82     score += 2;
83     mxscor += 2;
84
85     /* Deduct for hints/turns/saves. Hints < 4 are special; see database desc. */
86     for (long i=1; i<=HNTMAX; i++) {
87         if(game.hinted[i])
88             score=score-HINTS[i][2];
89     }
90     if(game.novice)
91         score -= 5;
92     if(game.clshnt)
93         score -= 10;
94     score=score-game.trnluz-game.saved;
95
96     /* Return to score command if that's where we came from. */
97     if(mode == scoregame) {
98         SETPRM(1,score,mxscor);
99         SETPRM(3,game.turns,game.turns);
100         RSPEAK(GARNERED_POINTS);
101         return;
102     }
103
104     /* that should be good enough.  Let's tell him all about it. */
105     if(score+game.trnluz+1 >= mxscor && game.trnluz != 0)
106         RSPEAK(TOOK_LONG);
107     if(score+game.saved+1 >= mxscor && game.saved != 0)
108         RSPEAK(WITHOUT_SUSPENDS);
109     SETPRM(1,score,mxscor);
110     SETPRM(3,game.turns,game.turns);
111     RSPEAK(TOTAL_SCORE);
112     for (long i=1; i<=CLSSES; i++) {
113         if(CVAL[i] >= score) {
114             newspeak(class_messages[i]);
115             i=CVAL[i]+1-score;
116             SETPRM(1,i,i);
117             RSPEAK(NEXT_HIGHER);
118             exit(0);
119         }
120     }
121     RSPEAK(OFF_SCALE);
122     RSPEAK(NO_HIGHER);
123     exit(0);
124
125 }