Frank Duignan
/
Nucleo_microrealms
Microrealms: An adventure game on the mbed platform
realm.cpp@0:4da21a20e2c1, 2014-12-04 (annotated)
- Committer:
- f3d
- Date:
- Thu Dec 04 14:17:50 2014 +0000
- Revision:
- 0:4da21a20e2c1
An adventure game called MicroRealms on the mbed platform. Should work with most mbed enabled devices as it is pretty frugal with resources. ; Requires a dumb terminal program (e.g. hyperterminal,minicom etc)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
f3d | 0:4da21a20e2c1 | 1 | /* |
f3d | 0:4da21a20e2c1 | 2 | Copyright (C) 2014 Frank Duignan |
f3d | 0:4da21a20e2c1 | 3 | |
f3d | 0:4da21a20e2c1 | 4 | This program is free software; you can redistribute it and/or |
f3d | 0:4da21a20e2c1 | 5 | modify it under the terms of the GNU General Public License |
f3d | 0:4da21a20e2c1 | 6 | as published by the Free Software Foundation; either version 2 |
f3d | 0:4da21a20e2c1 | 7 | of the License, or (at your option) any later version. |
f3d | 0:4da21a20e2c1 | 8 | |
f3d | 0:4da21a20e2c1 | 9 | This program is distributed in the hope that it will be useful, |
f3d | 0:4da21a20e2c1 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
f3d | 0:4da21a20e2c1 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
f3d | 0:4da21a20e2c1 | 12 | GNU General Public License for more details. |
f3d | 0:4da21a20e2c1 | 13 | |
f3d | 0:4da21a20e2c1 | 14 | You should have received a copy of the GNU General Public License |
f3d | 0:4da21a20e2c1 | 15 | along with this program; if not, write to the Free Software |
f3d | 0:4da21a20e2c1 | 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
f3d | 0:4da21a20e2c1 | 17 | */ |
f3d | 0:4da21a20e2c1 | 18 | #include "mbed.h" |
f3d | 0:4da21a20e2c1 | 19 | #include "realm.h" |
f3d | 0:4da21a20e2c1 | 20 | #include "serial.h" |
f3d | 0:4da21a20e2c1 | 21 | // Find types: h(ealth),s(trength),m(agic),g(old),w(eapon) |
f3d | 0:4da21a20e2c1 | 22 | const char FindTypes[]={'h','s','m','g','w'}; |
f3d | 0:4da21a20e2c1 | 23 | |
f3d | 0:4da21a20e2c1 | 24 | |
f3d | 0:4da21a20e2c1 | 25 | // The following arrays define the bad guys and |
f3d | 0:4da21a20e2c1 | 26 | // their battle properies - ordering matters! |
f3d | 0:4da21a20e2c1 | 27 | // Baddie types : O(gre),T(roll),D(ragon),H(ag) |
f3d | 0:4da21a20e2c1 | 28 | const char Baddies[]={'O','T','D','H'}; |
f3d | 0:4da21a20e2c1 | 29 | // The following is 4 sets of 4 damage types |
f3d | 0:4da21a20e2c1 | 30 | const byte WeaponDamage[]={10,10,5,25,10,10,5,25,10,15,5,15,5,5,2,10}; |
f3d | 0:4da21a20e2c1 | 31 | #define ICE_SPELL_COST 10 |
f3d | 0:4da21a20e2c1 | 32 | #define FIRE_SPELL_COST 20 |
f3d | 0:4da21a20e2c1 | 33 | #define LIGHTNING_SPELL_COST 30 |
f3d | 0:4da21a20e2c1 | 34 | const byte FreezeSpellDamage[]={10,20,5,0}; |
f3d | 0:4da21a20e2c1 | 35 | const byte FireSpellDamage[]={20,10,5,0}; |
f3d | 0:4da21a20e2c1 | 36 | const byte LightningSpellDamage[]={15,10,25,0}; |
f3d | 0:4da21a20e2c1 | 37 | const byte BadGuyDamage[]={10,10,15,5}; |
f3d | 0:4da21a20e2c1 | 38 | int GameStarted = 0; |
f3d | 0:4da21a20e2c1 | 39 | tPlayer thePlayer; |
f3d | 0:4da21a20e2c1 | 40 | tRealm theRealm; |
f3d | 0:4da21a20e2c1 | 41 | void delay(int len); |
f3d | 0:4da21a20e2c1 | 42 | |
f3d | 0:4da21a20e2c1 | 43 | void delay(int len) |
f3d | 0:4da21a20e2c1 | 44 | { |
f3d | 0:4da21a20e2c1 | 45 | wait(len/1000); |
f3d | 0:4da21a20e2c1 | 46 | } |
f3d | 0:4da21a20e2c1 | 47 | void runGame(void) |
f3d | 0:4da21a20e2c1 | 48 | { |
f3d | 0:4da21a20e2c1 | 49 | char ch; |
f3d | 0:4da21a20e2c1 | 50 | |
f3d | 0:4da21a20e2c1 | 51 | printString("MicroRealms on mbed."); |
f3d | 0:4da21a20e2c1 | 52 | showHelp(); |
f3d | 0:4da21a20e2c1 | 53 | while(GameStarted == 0) |
f3d | 0:4da21a20e2c1 | 54 | { |
f3d | 0:4da21a20e2c1 | 55 | |
f3d | 0:4da21a20e2c1 | 56 | showGameMessage("Press S to start a new game"); |
f3d | 0:4da21a20e2c1 | 57 | ch = getUserInput(); |
f3d | 0:4da21a20e2c1 | 58 | |
f3d | 0:4da21a20e2c1 | 59 | if ( (ch == 'S') || (ch == 's') ) |
f3d | 0:4da21a20e2c1 | 60 | GameStarted = 1; |
f3d | 0:4da21a20e2c1 | 61 | } |
f3d | 0:4da21a20e2c1 | 62 | |
f3d | 0:4da21a20e2c1 | 63 | initRealm(&theRealm); |
f3d | 0:4da21a20e2c1 | 64 | initPlayer(&thePlayer,&theRealm); |
f3d | 0:4da21a20e2c1 | 65 | showPlayer(&thePlayer); |
f3d | 0:4da21a20e2c1 | 66 | showRealm(&theRealm,&thePlayer); |
f3d | 0:4da21a20e2c1 | 67 | showGameMessage("Press H for help"); |
f3d | 0:4da21a20e2c1 | 68 | |
f3d | 0:4da21a20e2c1 | 69 | while (1) |
f3d | 0:4da21a20e2c1 | 70 | { |
f3d | 0:4da21a20e2c1 | 71 | ch = getUserInput(); |
f3d | 0:4da21a20e2c1 | 72 | ch = ch | 32; // enforce lower case |
f3d | 0:4da21a20e2c1 | 73 | switch (ch) { |
f3d | 0:4da21a20e2c1 | 74 | case 'h' : { |
f3d | 0:4da21a20e2c1 | 75 | showHelp(); |
f3d | 0:4da21a20e2c1 | 76 | break; |
f3d | 0:4da21a20e2c1 | 77 | } |
f3d | 0:4da21a20e2c1 | 78 | case 'n' : { |
f3d | 0:4da21a20e2c1 | 79 | showGameMessage("North"); |
f3d | 0:4da21a20e2c1 | 80 | step('n',&thePlayer,&theRealm); |
f3d | 0:4da21a20e2c1 | 81 | break; |
f3d | 0:4da21a20e2c1 | 82 | } |
f3d | 0:4da21a20e2c1 | 83 | case 's' : { |
f3d | 0:4da21a20e2c1 | 84 | showGameMessage("South"); |
f3d | 0:4da21a20e2c1 | 85 | step('s',&thePlayer,&theRealm); |
f3d | 0:4da21a20e2c1 | 86 | break; |
f3d | 0:4da21a20e2c1 | 87 | |
f3d | 0:4da21a20e2c1 | 88 | } |
f3d | 0:4da21a20e2c1 | 89 | case 'e' : { |
f3d | 0:4da21a20e2c1 | 90 | showGameMessage("East"); |
f3d | 0:4da21a20e2c1 | 91 | step('e',&thePlayer,&theRealm); |
f3d | 0:4da21a20e2c1 | 92 | break; |
f3d | 0:4da21a20e2c1 | 93 | } |
f3d | 0:4da21a20e2c1 | 94 | case 'w' : { |
f3d | 0:4da21a20e2c1 | 95 | showGameMessage("West"); |
f3d | 0:4da21a20e2c1 | 96 | step('w',&thePlayer,&theRealm); |
f3d | 0:4da21a20e2c1 | 97 | break; |
f3d | 0:4da21a20e2c1 | 98 | } |
f3d | 0:4da21a20e2c1 | 99 | case '#' : { |
f3d | 0:4da21a20e2c1 | 100 | if (thePlayer.wealth) |
f3d | 0:4da21a20e2c1 | 101 | { |
f3d | 0:4da21a20e2c1 | 102 | showRealm(&theRealm,&thePlayer); |
f3d | 0:4da21a20e2c1 | 103 | thePlayer.wealth--; |
f3d | 0:4da21a20e2c1 | 104 | } |
f3d | 0:4da21a20e2c1 | 105 | else |
f3d | 0:4da21a20e2c1 | 106 | showGameMessage("No gold!"); |
f3d | 0:4da21a20e2c1 | 107 | break; |
f3d | 0:4da21a20e2c1 | 108 | } |
f3d | 0:4da21a20e2c1 | 109 | case 'p' : { |
f3d | 0:4da21a20e2c1 | 110 | showPlayer(&thePlayer); |
f3d | 0:4da21a20e2c1 | 111 | break; |
f3d | 0:4da21a20e2c1 | 112 | } |
f3d | 0:4da21a20e2c1 | 113 | } // end switch |
f3d | 0:4da21a20e2c1 | 114 | } // end while |
f3d | 0:4da21a20e2c1 | 115 | } |
f3d | 0:4da21a20e2c1 | 116 | void step(char Direction,tPlayer *Player,tRealm *Realm) |
f3d | 0:4da21a20e2c1 | 117 | { |
f3d | 0:4da21a20e2c1 | 118 | int new_x, new_y; |
f3d | 0:4da21a20e2c1 | 119 | new_x = Player->x; |
f3d | 0:4da21a20e2c1 | 120 | new_y = Player->y; |
f3d | 0:4da21a20e2c1 | 121 | byte AreaContents; |
f3d | 0:4da21a20e2c1 | 122 | switch (Direction) { |
f3d | 0:4da21a20e2c1 | 123 | case 'n' : |
f3d | 0:4da21a20e2c1 | 124 | { |
f3d | 0:4da21a20e2c1 | 125 | if (new_y > 0) |
f3d | 0:4da21a20e2c1 | 126 | new_y--; |
f3d | 0:4da21a20e2c1 | 127 | break; |
f3d | 0:4da21a20e2c1 | 128 | } |
f3d | 0:4da21a20e2c1 | 129 | case 's' : |
f3d | 0:4da21a20e2c1 | 130 | { |
f3d | 0:4da21a20e2c1 | 131 | if (new_y < MAP_HEIGHT-1) |
f3d | 0:4da21a20e2c1 | 132 | new_y++; |
f3d | 0:4da21a20e2c1 | 133 | break; |
f3d | 0:4da21a20e2c1 | 134 | } |
f3d | 0:4da21a20e2c1 | 135 | case 'e' : |
f3d | 0:4da21a20e2c1 | 136 | { |
f3d | 0:4da21a20e2c1 | 137 | if (new_x < MAP_WIDTH-1) |
f3d | 0:4da21a20e2c1 | 138 | new_x++; |
f3d | 0:4da21a20e2c1 | 139 | break; |
f3d | 0:4da21a20e2c1 | 140 | } |
f3d | 0:4da21a20e2c1 | 141 | case 'w' : |
f3d | 0:4da21a20e2c1 | 142 | { |
f3d | 0:4da21a20e2c1 | 143 | if (new_x > 0) |
f3d | 0:4da21a20e2c1 | 144 | new_x--; |
f3d | 0:4da21a20e2c1 | 145 | break; |
f3d | 0:4da21a20e2c1 | 146 | } |
f3d | 0:4da21a20e2c1 | 147 | } |
f3d | 0:4da21a20e2c1 | 148 | AreaContents = Realm->map[new_y][new_x]; |
f3d | 0:4da21a20e2c1 | 149 | if ( AreaContents == '*') |
f3d | 0:4da21a20e2c1 | 150 | { |
f3d | 0:4da21a20e2c1 | 151 | showGameMessage("A rock blocks your path."); |
f3d | 0:4da21a20e2c1 | 152 | return; |
f3d | 0:4da21a20e2c1 | 153 | } |
f3d | 0:4da21a20e2c1 | 154 | Player->x = new_x; |
f3d | 0:4da21a20e2c1 | 155 | Player->y = new_y; |
f3d | 0:4da21a20e2c1 | 156 | int Consumed = 0; |
f3d | 0:4da21a20e2c1 | 157 | switch (AreaContents) |
f3d | 0:4da21a20e2c1 | 158 | { |
f3d | 0:4da21a20e2c1 | 159 | |
f3d | 0:4da21a20e2c1 | 160 | // const char Baddies[]={'O','T','B','H'}; |
f3d | 0:4da21a20e2c1 | 161 | case 'O' :{ |
f3d | 0:4da21a20e2c1 | 162 | showGameMessage("A smelly green Ogre appears before you"); |
f3d | 0:4da21a20e2c1 | 163 | Consumed = doChallenge(Player,0); |
f3d | 0:4da21a20e2c1 | 164 | break; |
f3d | 0:4da21a20e2c1 | 165 | } |
f3d | 0:4da21a20e2c1 | 166 | case 'T' :{ |
f3d | 0:4da21a20e2c1 | 167 | showGameMessage("An evil troll challenges you"); |
f3d | 0:4da21a20e2c1 | 168 | Consumed = doChallenge(Player,1); |
f3d | 0:4da21a20e2c1 | 169 | break; |
f3d | 0:4da21a20e2c1 | 170 | } |
f3d | 0:4da21a20e2c1 | 171 | case 'D' :{ |
f3d | 0:4da21a20e2c1 | 172 | showGameMessage("A smouldering Dragon blocks your way !"); |
f3d | 0:4da21a20e2c1 | 173 | Consumed = doChallenge(Player,2); |
f3d | 0:4da21a20e2c1 | 174 | break; |
f3d | 0:4da21a20e2c1 | 175 | } |
f3d | 0:4da21a20e2c1 | 176 | case 'H' :{ |
f3d | 0:4da21a20e2c1 | 177 | showGameMessage("A withered hag cackles at you wickedly"); |
f3d | 0:4da21a20e2c1 | 178 | Consumed = doChallenge(Player,3); |
f3d | 0:4da21a20e2c1 | 179 | break; |
f3d | 0:4da21a20e2c1 | 180 | } |
f3d | 0:4da21a20e2c1 | 181 | case 'h' :{ |
f3d | 0:4da21a20e2c1 | 182 | showGameMessage("You find an elixer of health"); |
f3d | 0:4da21a20e2c1 | 183 | setHealth(Player,Player->health+10); |
f3d | 0:4da21a20e2c1 | 184 | Consumed = 1; |
f3d | 0:4da21a20e2c1 | 185 | break; |
f3d | 0:4da21a20e2c1 | 186 | |
f3d | 0:4da21a20e2c1 | 187 | } |
f3d | 0:4da21a20e2c1 | 188 | case 's' :{ |
f3d | 0:4da21a20e2c1 | 189 | showGameMessage("You find a potion of strength"); |
f3d | 0:4da21a20e2c1 | 190 | Consumed = 1; |
f3d | 0:4da21a20e2c1 | 191 | setStrength(Player,Player->strength+1); |
f3d | 0:4da21a20e2c1 | 192 | break; |
f3d | 0:4da21a20e2c1 | 193 | } |
f3d | 0:4da21a20e2c1 | 194 | case 'g' :{ |
f3d | 0:4da21a20e2c1 | 195 | showGameMessage("You find a shiny golden nugget"); |
f3d | 0:4da21a20e2c1 | 196 | Player->wealth++; |
f3d | 0:4da21a20e2c1 | 197 | Consumed = 1; |
f3d | 0:4da21a20e2c1 | 198 | break; |
f3d | 0:4da21a20e2c1 | 199 | } |
f3d | 0:4da21a20e2c1 | 200 | case 'm' :{ |
f3d | 0:4da21a20e2c1 | 201 | showGameMessage("You find a magic charm"); |
f3d | 0:4da21a20e2c1 | 202 | Player->magic++; |
f3d | 0:4da21a20e2c1 | 203 | Consumed = 1; |
f3d | 0:4da21a20e2c1 | 204 | break; |
f3d | 0:4da21a20e2c1 | 205 | } |
f3d | 0:4da21a20e2c1 | 206 | case 'w' :{ |
f3d | 0:4da21a20e2c1 | 207 | Consumed = addWeapon(Player,random(MAX_WEAPONS-1)+1); |
f3d | 0:4da21a20e2c1 | 208 | showPlayer(Player); |
f3d | 0:4da21a20e2c1 | 209 | break; |
f3d | 0:4da21a20e2c1 | 210 | } |
f3d | 0:4da21a20e2c1 | 211 | case 'X' : { |
f3d | 0:4da21a20e2c1 | 212 | // Player landed on the exit |
f3d | 0:4da21a20e2c1 | 213 | printString("A door! You exit into a new realm"); |
f3d | 0:4da21a20e2c1 | 214 | setHealth(Player,100); // maximize health |
f3d | 0:4da21a20e2c1 | 215 | initRealm(&theRealm); |
f3d | 0:4da21a20e2c1 | 216 | showRealm(&theRealm,Player); |
f3d | 0:4da21a20e2c1 | 217 | } |
f3d | 0:4da21a20e2c1 | 218 | } |
f3d | 0:4da21a20e2c1 | 219 | if (Consumed) |
f3d | 0:4da21a20e2c1 | 220 | Realm->map[new_y][new_x] = '.'; // remove any item that was found |
f3d | 0:4da21a20e2c1 | 221 | } |
f3d | 0:4da21a20e2c1 | 222 | int doChallenge(tPlayer *Player,int BadGuyIndex) |
f3d | 0:4da21a20e2c1 | 223 | { |
f3d | 0:4da21a20e2c1 | 224 | char ch; |
f3d | 0:4da21a20e2c1 | 225 | char Damage; |
f3d | 0:4da21a20e2c1 | 226 | const byte *dmg; |
f3d | 0:4da21a20e2c1 | 227 | int BadGuyHealth = 100; |
f3d | 0:4da21a20e2c1 | 228 | printString("Press F to fight"); |
f3d | 0:4da21a20e2c1 | 229 | ch = getUserInput() | 32; // get user input and force lower case |
f3d | 0:4da21a20e2c1 | 230 | if (ch == 'f') |
f3d | 0:4da21a20e2c1 | 231 | { |
f3d | 0:4da21a20e2c1 | 232 | printString("Choose action"); |
f3d | 0:4da21a20e2c1 | 233 | while ( (Player->health > 0) && (BadGuyHealth > 0) ) |
f3d | 0:4da21a20e2c1 | 234 | { |
f3d | 0:4da21a20e2c1 | 235 | // Player takes turn first |
f3d | 0:4da21a20e2c1 | 236 | if (Player->magic > ICE_SPELL_COST) |
f3d | 0:4da21a20e2c1 | 237 | printString("(I)CE spell"); |
f3d | 0:4da21a20e2c1 | 238 | if (Player->magic > FIRE_SPELL_COST) |
f3d | 0:4da21a20e2c1 | 239 | printString("(F)ire spell"); |
f3d | 0:4da21a20e2c1 | 240 | if (Player->magic > LIGHTNING_SPELL_COST) |
f3d | 0:4da21a20e2c1 | 241 | printString("(L)ightning spell"); |
f3d | 0:4da21a20e2c1 | 242 | if (Player->Weapon1) |
f3d | 0:4da21a20e2c1 | 243 | { |
f3d | 0:4da21a20e2c1 | 244 | eputs("(1)Use "); |
f3d | 0:4da21a20e2c1 | 245 | printString(getWeaponName(Player->Weapon1)); |
f3d | 0:4da21a20e2c1 | 246 | } |
f3d | 0:4da21a20e2c1 | 247 | if (Player->Weapon2) |
f3d | 0:4da21a20e2c1 | 248 | { |
f3d | 0:4da21a20e2c1 | 249 | eputs("(2)Use "); |
f3d | 0:4da21a20e2c1 | 250 | printString(getWeaponName(Player->Weapon2)); |
f3d | 0:4da21a20e2c1 | 251 | } |
f3d | 0:4da21a20e2c1 | 252 | printString("(P)unch"); |
f3d | 0:4da21a20e2c1 | 253 | ch = getUserInput(); |
f3d | 0:4da21a20e2c1 | 254 | switch (ch) |
f3d | 0:4da21a20e2c1 | 255 | { |
f3d | 0:4da21a20e2c1 | 256 | case 'i': |
f3d | 0:4da21a20e2c1 | 257 | case 'I': |
f3d | 0:4da21a20e2c1 | 258 | { |
f3d | 0:4da21a20e2c1 | 259 | printString("FREEZE!"); |
f3d | 0:4da21a20e2c1 | 260 | Player->magic -= ICE_SPELL_COST; |
f3d | 0:4da21a20e2c1 | 261 | BadGuyHealth -= FreezeSpellDamage[BadGuyIndex]+random(10); |
f3d | 0:4da21a20e2c1 | 262 | zap(); |
f3d | 0:4da21a20e2c1 | 263 | break; |
f3d | 0:4da21a20e2c1 | 264 | } |
f3d | 0:4da21a20e2c1 | 265 | case 'f': |
f3d | 0:4da21a20e2c1 | 266 | case 'F': |
f3d | 0:4da21a20e2c1 | 267 | { |
f3d | 0:4da21a20e2c1 | 268 | printString("BURN!"); |
f3d | 0:4da21a20e2c1 | 269 | Player->magic -= FIRE_SPELL_COST; |
f3d | 0:4da21a20e2c1 | 270 | BadGuyHealth -= FireSpellDamage[BadGuyIndex]+random(10); |
f3d | 0:4da21a20e2c1 | 271 | zap(); |
f3d | 0:4da21a20e2c1 | 272 | break; |
f3d | 0:4da21a20e2c1 | 273 | } |
f3d | 0:4da21a20e2c1 | 274 | case 'l': |
f3d | 0:4da21a20e2c1 | 275 | case 'L': |
f3d | 0:4da21a20e2c1 | 276 | { |
f3d | 0:4da21a20e2c1 | 277 | printString("ZAP!"); |
f3d | 0:4da21a20e2c1 | 278 | Player->magic -= LIGHTNING_SPELL_COST; |
f3d | 0:4da21a20e2c1 | 279 | BadGuyHealth -= LightningSpellDamage[BadGuyIndex]+random(10); |
f3d | 0:4da21a20e2c1 | 280 | zap(); |
f3d | 0:4da21a20e2c1 | 281 | break; |
f3d | 0:4da21a20e2c1 | 282 | } |
f3d | 0:4da21a20e2c1 | 283 | case '1': |
f3d | 0:4da21a20e2c1 | 284 | { |
f3d | 0:4da21a20e2c1 | 285 | dmg = WeaponDamage+(Player->Weapon1<<2)+BadGuyIndex; |
f3d | 0:4da21a20e2c1 | 286 | printString("Take that!"); |
f3d | 0:4da21a20e2c1 | 287 | BadGuyHealth -= *dmg + random(Player->strength); |
f3d | 0:4da21a20e2c1 | 288 | setStrength(Player,Player->strength-1); |
f3d | 0:4da21a20e2c1 | 289 | break; |
f3d | 0:4da21a20e2c1 | 290 | } |
f3d | 0:4da21a20e2c1 | 291 | case '2': |
f3d | 0:4da21a20e2c1 | 292 | { |
f3d | 0:4da21a20e2c1 | 293 | dmg = WeaponDamage+(Player->Weapon2<<2)+BadGuyIndex; |
f3d | 0:4da21a20e2c1 | 294 | printString("Take that!"); |
f3d | 0:4da21a20e2c1 | 295 | BadGuyHealth -= *dmg + random(Player->strength); |
f3d | 0:4da21a20e2c1 | 296 | setStrength(Player,Player->strength-1); |
f3d | 0:4da21a20e2c1 | 297 | break; |
f3d | 0:4da21a20e2c1 | 298 | } |
f3d | 0:4da21a20e2c1 | 299 | case 'p': |
f3d | 0:4da21a20e2c1 | 300 | case 'P': |
f3d | 0:4da21a20e2c1 | 301 | { |
f3d | 0:4da21a20e2c1 | 302 | printString("Thump!"); |
f3d | 0:4da21a20e2c1 | 303 | BadGuyHealth -= 1+random(Player->strength); |
f3d | 0:4da21a20e2c1 | 304 | setStrength(Player,Player->strength-1); |
f3d | 0:4da21a20e2c1 | 305 | break; |
f3d | 0:4da21a20e2c1 | 306 | } |
f3d | 0:4da21a20e2c1 | 307 | default: { |
f3d | 0:4da21a20e2c1 | 308 | printString("You fumble. Uh oh"); |
f3d | 0:4da21a20e2c1 | 309 | } |
f3d | 0:4da21a20e2c1 | 310 | } |
f3d | 0:4da21a20e2c1 | 311 | // Bad guy then gets a go |
f3d | 0:4da21a20e2c1 | 312 | |
f3d | 0:4da21a20e2c1 | 313 | if (BadGuyHealth < 0) |
f3d | 0:4da21a20e2c1 | 314 | BadGuyHealth = 0; |
f3d | 0:4da21a20e2c1 | 315 | Damage = BadGuyDamage[BadGuyIndex]+random(5); |
f3d | 0:4da21a20e2c1 | 316 | setHealth(Player,Player->health - Damage); |
f3d | 0:4da21a20e2c1 | 317 | eputs("Health: you "); printHex(Player->health); |
f3d | 0:4da21a20e2c1 | 318 | eputs(", them " );printHex(BadGuyHealth); |
f3d | 0:4da21a20e2c1 | 319 | eputs("\r\n"); |
f3d | 0:4da21a20e2c1 | 320 | } |
f3d | 0:4da21a20e2c1 | 321 | if (Player->health == 0) |
f3d | 0:4da21a20e2c1 | 322 | { // You died |
f3d | 0:4da21a20e2c1 | 323 | printString("You are dead. Press Reset to restart"); |
f3d | 0:4da21a20e2c1 | 324 | while(1); |
f3d | 0:4da21a20e2c1 | 325 | } |
f3d | 0:4da21a20e2c1 | 326 | else |
f3d | 0:4da21a20e2c1 | 327 | { // You won! |
f3d | 0:4da21a20e2c1 | 328 | Player->wealth = 50 + random(50); |
f3d | 0:4da21a20e2c1 | 329 | showGameMessage("You win! Their gold is yours"); |
f3d | 0:4da21a20e2c1 | 330 | return 1; |
f3d | 0:4da21a20e2c1 | 331 | } |
f3d | 0:4da21a20e2c1 | 332 | |
f3d | 0:4da21a20e2c1 | 333 | } |
f3d | 0:4da21a20e2c1 | 334 | else |
f3d | 0:4da21a20e2c1 | 335 | { |
f3d | 0:4da21a20e2c1 | 336 | showGameMessage("Our 'hero' chickens out"); |
f3d | 0:4da21a20e2c1 | 337 | return 0; |
f3d | 0:4da21a20e2c1 | 338 | } |
f3d | 0:4da21a20e2c1 | 339 | } |
f3d | 0:4da21a20e2c1 | 340 | int addWeapon(tPlayer *Player, int Weapon) |
f3d | 0:4da21a20e2c1 | 341 | { |
f3d | 0:4da21a20e2c1 | 342 | char c; |
f3d | 0:4da21a20e2c1 | 343 | eputs("You stumble upon "); |
f3d | 0:4da21a20e2c1 | 344 | switch (Weapon) |
f3d | 0:4da21a20e2c1 | 345 | { |
f3d | 0:4da21a20e2c1 | 346 | case 1: |
f3d | 0:4da21a20e2c1 | 347 | { |
f3d | 0:4da21a20e2c1 | 348 | printString("a mighty axe"); |
f3d | 0:4da21a20e2c1 | 349 | break; |
f3d | 0:4da21a20e2c1 | 350 | } |
f3d | 0:4da21a20e2c1 | 351 | case 2: |
f3d | 0:4da21a20e2c1 | 352 | { |
f3d | 0:4da21a20e2c1 | 353 | printString("a sword with mystical runes"); |
f3d | 0:4da21a20e2c1 | 354 | break; |
f3d | 0:4da21a20e2c1 | 355 | } |
f3d | 0:4da21a20e2c1 | 356 | case 3: |
f3d | 0:4da21a20e2c1 | 357 | { |
f3d | 0:4da21a20e2c1 | 358 | printString("a bloody flail"); |
f3d | 0:4da21a20e2c1 | 359 | break; |
f3d | 0:4da21a20e2c1 | 360 | } |
f3d | 0:4da21a20e2c1 | 361 | default: |
f3d | 0:4da21a20e2c1 | 362 | printHex(Weapon); |
f3d | 0:4da21a20e2c1 | 363 | } |
f3d | 0:4da21a20e2c1 | 364 | if ( (Player->Weapon1) && (Player->Weapon2) ) |
f3d | 0:4da21a20e2c1 | 365 | { |
f3d | 0:4da21a20e2c1 | 366 | // The player has two weapons already. |
f3d | 0:4da21a20e2c1 | 367 | showPlayer(Player); |
f3d | 0:4da21a20e2c1 | 368 | printString("You already have two weapons"); |
f3d | 0:4da21a20e2c1 | 369 | printString("(1) drop Weapon1, (2) for Weapon2, (0) skip"); |
f3d | 0:4da21a20e2c1 | 370 | c = getUserInput(); |
f3d | 0:4da21a20e2c1 | 371 | switch(c) |
f3d | 0:4da21a20e2c1 | 372 | { |
f3d | 0:4da21a20e2c1 | 373 | case '0':{ |
f3d | 0:4da21a20e2c1 | 374 | return 0; // don't pick up |
f3d | 0:4da21a20e2c1 | 375 | } |
f3d | 0:4da21a20e2c1 | 376 | case '1':{ |
f3d | 0:4da21a20e2c1 | 377 | Player->Weapon1 = Weapon; |
f3d | 0:4da21a20e2c1 | 378 | break; |
f3d | 0:4da21a20e2c1 | 379 | } |
f3d | 0:4da21a20e2c1 | 380 | case '2':{ |
f3d | 0:4da21a20e2c1 | 381 | Player->Weapon2 = Weapon; |
f3d | 0:4da21a20e2c1 | 382 | break; |
f3d | 0:4da21a20e2c1 | 383 | } |
f3d | 0:4da21a20e2c1 | 384 | } |
f3d | 0:4da21a20e2c1 | 385 | } |
f3d | 0:4da21a20e2c1 | 386 | else |
f3d | 0:4da21a20e2c1 | 387 | { |
f3d | 0:4da21a20e2c1 | 388 | if (!Player->Weapon1) |
f3d | 0:4da21a20e2c1 | 389 | { |
f3d | 0:4da21a20e2c1 | 390 | Player->Weapon1 = Weapon; |
f3d | 0:4da21a20e2c1 | 391 | } |
f3d | 0:4da21a20e2c1 | 392 | else if (!Player->Weapon2) |
f3d | 0:4da21a20e2c1 | 393 | { |
f3d | 0:4da21a20e2c1 | 394 | Player->Weapon2 = Weapon; |
f3d | 0:4da21a20e2c1 | 395 | } |
f3d | 0:4da21a20e2c1 | 396 | } |
f3d | 0:4da21a20e2c1 | 397 | return 1; |
f3d | 0:4da21a20e2c1 | 398 | } |
f3d | 0:4da21a20e2c1 | 399 | const char *getWeaponName(int index) |
f3d | 0:4da21a20e2c1 | 400 | { |
f3d | 0:4da21a20e2c1 | 401 | switch (index) |
f3d | 0:4da21a20e2c1 | 402 | { |
f3d | 0:4da21a20e2c1 | 403 | case 0:return "Empty"; break; |
f3d | 0:4da21a20e2c1 | 404 | case 1:return "Axe";break; |
f3d | 0:4da21a20e2c1 | 405 | case 2:return "Sword"; break; |
f3d | 0:4da21a20e2c1 | 406 | case 3:return "Flail"; break; |
f3d | 0:4da21a20e2c1 | 407 | } |
f3d | 0:4da21a20e2c1 | 408 | } |
f3d | 0:4da21a20e2c1 | 409 | |
f3d | 0:4da21a20e2c1 | 410 | void setHealth(tPlayer *Player,int health) |
f3d | 0:4da21a20e2c1 | 411 | { |
f3d | 0:4da21a20e2c1 | 412 | if (health > 100) |
f3d | 0:4da21a20e2c1 | 413 | health = 100; |
f3d | 0:4da21a20e2c1 | 414 | if (health < 0) |
f3d | 0:4da21a20e2c1 | 415 | health = 0; |
f3d | 0:4da21a20e2c1 | 416 | Player->health = health; |
f3d | 0:4da21a20e2c1 | 417 | |
f3d | 0:4da21a20e2c1 | 418 | } |
f3d | 0:4da21a20e2c1 | 419 | void setStrength(tPlayer *Player, byte strength) |
f3d | 0:4da21a20e2c1 | 420 | { |
f3d | 0:4da21a20e2c1 | 421 | if (strength > 100) |
f3d | 0:4da21a20e2c1 | 422 | strength = 100; |
f3d | 0:4da21a20e2c1 | 423 | if (strength < 0) |
f3d | 0:4da21a20e2c1 | 424 | strength = 0; |
f3d | 0:4da21a20e2c1 | 425 | Player->strength = strength; |
f3d | 0:4da21a20e2c1 | 426 | } |
f3d | 0:4da21a20e2c1 | 427 | void initPlayer(tPlayer *Player,tRealm *theRealm) |
f3d | 0:4da21a20e2c1 | 428 | { |
f3d | 0:4da21a20e2c1 | 429 | // get the player name |
f3d | 0:4da21a20e2c1 | 430 | int index=0; |
f3d | 0:4da21a20e2c1 | 431 | byte x,y; |
f3d | 0:4da21a20e2c1 | 432 | char ch=0; |
f3d | 0:4da21a20e2c1 | 433 | // Initialize the player's attributes |
f3d | 0:4da21a20e2c1 | 434 | eputs("Enter the player's name: "); |
f3d | 0:4da21a20e2c1 | 435 | while ( (index < MAX_NAME_LEN) && (ch != '\n') && (ch != '\r')) |
f3d | 0:4da21a20e2c1 | 436 | { |
f3d | 0:4da21a20e2c1 | 437 | ch = getUserInput(); |
f3d | 0:4da21a20e2c1 | 438 | if ( ch > '0' ) // strip conrol characters |
f3d | 0:4da21a20e2c1 | 439 | { |
f3d | 0:4da21a20e2c1 | 440 | |
f3d | 0:4da21a20e2c1 | 441 | Player->name[index++]=ch; |
f3d | 0:4da21a20e2c1 | 442 | eputc(ch); |
f3d | 0:4da21a20e2c1 | 443 | } |
f3d | 0:4da21a20e2c1 | 444 | } |
f3d | 0:4da21a20e2c1 | 445 | Player->name[index]=0; // terminate the name |
f3d | 0:4da21a20e2c1 | 446 | setHealth(Player,100); |
f3d | 0:4da21a20e2c1 | 447 | Player->strength=50+random(50); |
f3d | 0:4da21a20e2c1 | 448 | Player->magic=50+random(50); |
f3d | 0:4da21a20e2c1 | 449 | Player->wealth=10+random(10); |
f3d | 0:4da21a20e2c1 | 450 | Player->Weapon1 = 0; |
f3d | 0:4da21a20e2c1 | 451 | Player->Weapon2 = 0; |
f3d | 0:4da21a20e2c1 | 452 | // Initialize the player's location |
f3d | 0:4da21a20e2c1 | 453 | // Make sure the player does not land |
f3d | 0:4da21a20e2c1 | 454 | // on an occupied space to begin with |
f3d | 0:4da21a20e2c1 | 455 | do { |
f3d | 0:4da21a20e2c1 | 456 | x=random(MAP_WIDTH); |
f3d | 0:4da21a20e2c1 | 457 | y=random(MAP_HEIGHT); |
f3d | 0:4da21a20e2c1 | 458 | |
f3d | 0:4da21a20e2c1 | 459 | } while(theRealm->map[y][x] != '.'); |
f3d | 0:4da21a20e2c1 | 460 | Player->x=x; |
f3d | 0:4da21a20e2c1 | 461 | Player->y=y; |
f3d | 0:4da21a20e2c1 | 462 | } |
f3d | 0:4da21a20e2c1 | 463 | void showPlayer(tPlayer *thePlayer) |
f3d | 0:4da21a20e2c1 | 464 | { |
f3d | 0:4da21a20e2c1 | 465 | eputs("\r\nName: "); |
f3d | 0:4da21a20e2c1 | 466 | printString(thePlayer->name); |
f3d | 0:4da21a20e2c1 | 467 | eputs("health: "); |
f3d | 0:4da21a20e2c1 | 468 | printHex(thePlayer->health); |
f3d | 0:4da21a20e2c1 | 469 | eputs("\r\nstrength: "); |
f3d | 0:4da21a20e2c1 | 470 | printHex(thePlayer->strength); |
f3d | 0:4da21a20e2c1 | 471 | eputs("\r\nmagic: "); |
f3d | 0:4da21a20e2c1 | 472 | printHex(thePlayer->magic); |
f3d | 0:4da21a20e2c1 | 473 | eputs("\r\nwealth: "); |
f3d | 0:4da21a20e2c1 | 474 | printHex(thePlayer->wealth); |
f3d | 0:4da21a20e2c1 | 475 | eputs("\r\nLocation : "); |
f3d | 0:4da21a20e2c1 | 476 | printHex(thePlayer->x); |
f3d | 0:4da21a20e2c1 | 477 | eputs(" , "); |
f3d | 0:4da21a20e2c1 | 478 | printHex(thePlayer->y); |
f3d | 0:4da21a20e2c1 | 479 | eputs("\r\nWeapon1 : "); |
f3d | 0:4da21a20e2c1 | 480 | printString(getWeaponName(thePlayer->Weapon1)); |
f3d | 0:4da21a20e2c1 | 481 | eputs("Weapon2 : "); |
f3d | 0:4da21a20e2c1 | 482 | printString(getWeaponName(thePlayer->Weapon2)); |
f3d | 0:4da21a20e2c1 | 483 | } |
f3d | 0:4da21a20e2c1 | 484 | void initRealm(tRealm *Realm) |
f3d | 0:4da21a20e2c1 | 485 | { |
f3d | 0:4da21a20e2c1 | 486 | int x,y; |
f3d | 0:4da21a20e2c1 | 487 | int Rnd; |
f3d | 0:4da21a20e2c1 | 488 | // clear the map to begin with |
f3d | 0:4da21a20e2c1 | 489 | for (y=0;y < MAP_HEIGHT; y++) |
f3d | 0:4da21a20e2c1 | 490 | { |
f3d | 0:4da21a20e2c1 | 491 | for (x=0; x < MAP_WIDTH; x++) |
f3d | 0:4da21a20e2c1 | 492 | { |
f3d | 0:4da21a20e2c1 | 493 | Rnd = random(100); |
f3d | 0:4da21a20e2c1 | 494 | |
f3d | 0:4da21a20e2c1 | 495 | if (Rnd >= 98) // put in some baddies |
f3d | 0:4da21a20e2c1 | 496 | Realm->map[y][x]= Baddies[random(sizeof(Baddies))]; |
f3d | 0:4da21a20e2c1 | 497 | else if (Rnd >= 95) // put in some good stuff |
f3d | 0:4da21a20e2c1 | 498 | Realm->map[y][x]= FindTypes[random(sizeof(FindTypes))]; |
f3d | 0:4da21a20e2c1 | 499 | else if (Rnd >= 90) // put in some rocks |
f3d | 0:4da21a20e2c1 | 500 | Realm->map[y][x]='*'; |
f3d | 0:4da21a20e2c1 | 501 | else // put in empty space |
f3d | 0:4da21a20e2c1 | 502 | Realm->map[y][x] = '.'; |
f3d | 0:4da21a20e2c1 | 503 | } |
f3d | 0:4da21a20e2c1 | 504 | } |
f3d | 0:4da21a20e2c1 | 505 | |
f3d | 0:4da21a20e2c1 | 506 | // finally put the exit to the next level in |
f3d | 0:4da21a20e2c1 | 507 | x = random(MAP_WIDTH); |
f3d | 0:4da21a20e2c1 | 508 | y = random(MAP_HEIGHT); |
f3d | 0:4da21a20e2c1 | 509 | Realm->map[y][x]='X'; |
f3d | 0:4da21a20e2c1 | 510 | } |
f3d | 0:4da21a20e2c1 | 511 | void showRealm(tRealm *Realm,tPlayer *thePlayer) |
f3d | 0:4da21a20e2c1 | 512 | { |
f3d | 0:4da21a20e2c1 | 513 | int x,y; |
f3d | 0:4da21a20e2c1 | 514 | printString("The Realm:"); |
f3d | 0:4da21a20e2c1 | 515 | for (y=0;y<MAP_HEIGHT;y++) |
f3d | 0:4da21a20e2c1 | 516 | { |
f3d | 0:4da21a20e2c1 | 517 | for (x=0;x<MAP_WIDTH;x++) |
f3d | 0:4da21a20e2c1 | 518 | { |
f3d | 0:4da21a20e2c1 | 519 | |
f3d | 0:4da21a20e2c1 | 520 | if ( (x==thePlayer->x) && (y==thePlayer->y)) |
f3d | 0:4da21a20e2c1 | 521 | eputc('@'); |
f3d | 0:4da21a20e2c1 | 522 | else |
f3d | 0:4da21a20e2c1 | 523 | eputc(Realm->map[y][x]); |
f3d | 0:4da21a20e2c1 | 524 | } |
f3d | 0:4da21a20e2c1 | 525 | eputs("\r\n"); |
f3d | 0:4da21a20e2c1 | 526 | } |
f3d | 0:4da21a20e2c1 | 527 | printString("\r\nLegend"); |
f3d | 0:4da21a20e2c1 | 528 | printString("(T)roll, (O)gre, (D)ragon, (H)ag, e(X)it"); |
f3d | 0:4da21a20e2c1 | 529 | printString("(w)eapon, (g)old), (m)agic, (s)trength"); |
f3d | 0:4da21a20e2c1 | 530 | printString("@=You"); |
f3d | 0:4da21a20e2c1 | 531 | } |
f3d | 0:4da21a20e2c1 | 532 | void showHelp() |
f3d | 0:4da21a20e2c1 | 533 | { |
f3d | 0:4da21a20e2c1 | 534 | |
f3d | 0:4da21a20e2c1 | 535 | printString("Help"); |
f3d | 0:4da21a20e2c1 | 536 | printString("N,S,E,W : go North, South, East, West"); |
f3d | 0:4da21a20e2c1 | 537 | printString("# : show map (cost: 1 gold piece)"); |
f3d | 0:4da21a20e2c1 | 538 | printString("(H)elp"); |
f3d | 0:4da21a20e2c1 | 539 | printString("(P)layer details"); |
f3d | 0:4da21a20e2c1 | 540 | |
f3d | 0:4da21a20e2c1 | 541 | } |
f3d | 0:4da21a20e2c1 | 542 | |
f3d | 0:4da21a20e2c1 | 543 | void showGameMessage(char *Msg) |
f3d | 0:4da21a20e2c1 | 544 | { |
f3d | 0:4da21a20e2c1 | 545 | printString(Msg); |
f3d | 0:4da21a20e2c1 | 546 | printString("Ready"); |
f3d | 0:4da21a20e2c1 | 547 | } |
f3d | 0:4da21a20e2c1 | 548 | char getUserInput() |
f3d | 0:4da21a20e2c1 | 549 | { |
f3d | 0:4da21a20e2c1 | 550 | char ch = 0; |
f3d | 0:4da21a20e2c1 | 551 | |
f3d | 0:4da21a20e2c1 | 552 | while (ch == 0) |
f3d | 0:4da21a20e2c1 | 553 | { |
f3d | 0:4da21a20e2c1 | 554 | ch = egetc(); |
f3d | 0:4da21a20e2c1 | 555 | prbs(); // cycle the prbs generator while waiting for user input |
f3d | 0:4da21a20e2c1 | 556 | } |
f3d | 0:4da21a20e2c1 | 557 | return ch; |
f3d | 0:4da21a20e2c1 | 558 | } |
f3d | 0:4da21a20e2c1 | 559 | unsigned prbs() |
f3d | 0:4da21a20e2c1 | 560 | { |
f3d | 0:4da21a20e2c1 | 561 | // This is an unverified 31 bit PRBS generator |
f3d | 0:4da21a20e2c1 | 562 | // It should be maximum length but this has not been verified |
f3d | 0:4da21a20e2c1 | 563 | static unsigned long shift_register=0xa5a5a5a5; |
f3d | 0:4da21a20e2c1 | 564 | unsigned long new_bit=0; |
f3d | 0:4da21a20e2c1 | 565 | static int busy=0; // need to prevent re-entrancy here |
f3d | 0:4da21a20e2c1 | 566 | if (!busy) |
f3d | 0:4da21a20e2c1 | 567 | { |
f3d | 0:4da21a20e2c1 | 568 | busy=1; |
f3d | 0:4da21a20e2c1 | 569 | new_bit= ((shift_register & (1<<27))>>27) ^ ((shift_register & (1<<30))>>30); |
f3d | 0:4da21a20e2c1 | 570 | new_bit= ~new_bit; |
f3d | 0:4da21a20e2c1 | 571 | new_bit = new_bit & 1; |
f3d | 0:4da21a20e2c1 | 572 | shift_register=shift_register << 1; |
f3d | 0:4da21a20e2c1 | 573 | shift_register=shift_register | (new_bit); |
f3d | 0:4da21a20e2c1 | 574 | busy=0; |
f3d | 0:4da21a20e2c1 | 575 | } |
f3d | 0:4da21a20e2c1 | 576 | return shift_register & 0x7ffffff; // return 31 LSB's |
f3d | 0:4da21a20e2c1 | 577 | } |
f3d | 0:4da21a20e2c1 | 578 | unsigned random(unsigned range) |
f3d | 0:4da21a20e2c1 | 579 | { |
f3d | 0:4da21a20e2c1 | 580 | // Implementing my own version of modulus |
f3d | 0:4da21a20e2c1 | 581 | // as it is a lot smaller than the library version |
f3d | 0:4da21a20e2c1 | 582 | // To prevent very long subtract loops, the |
f3d | 0:4da21a20e2c1 | 583 | // size of the value returned from prbs has been |
f3d | 0:4da21a20e2c1 | 584 | // restricted to 8 bits. |
f3d | 0:4da21a20e2c1 | 585 | int Rvalue = (prbs()&0xff); |
f3d | 0:4da21a20e2c1 | 586 | while (Rvalue >= range) |
f3d | 0:4da21a20e2c1 | 587 | Rvalue -= range; |
f3d | 0:4da21a20e2c1 | 588 | return Rvalue; |
f3d | 0:4da21a20e2c1 | 589 | } |
f3d | 0:4da21a20e2c1 | 590 | void zap() |
f3d | 0:4da21a20e2c1 | 591 | { |
f3d | 0:4da21a20e2c1 | 592 | |
f3d | 0:4da21a20e2c1 | 593 | } |