-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgameDefinition.js
More file actions
190 lines (168 loc) · 5.79 KB
/
gameDefinition.js
File metadata and controls
190 lines (168 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/**
* Main game object that controls game flow.
*/
class Game {
/**
* @param setupData An object specifcally formatted to provide info to the game.
* See config.js for example structure.
*/
constructor(setupData) {
// Link the DOM command input area using jQuery
const $userInput = $("#command")
// Link the DOM output areas using jQuery
const $messageArea = $("#message")
const messenger = new Messenger($messageArea)
const $nameArea = $("#name")
const roomNamer = new Descriptor($nameArea)
const $descriptionArea = $("#description")
const descriptor = new Descriptor($descriptionArea)
//create a new interpreter/parser with availible commands and synonyms
const parser = new Parser({
go: ['go', 'walk', 'run', 'flee'],
look: ['look', 'l', 'view', 'examine', 'inspect'],
take: ['take', 't', 'pick', 'grab', 'steal'],
inventory: ['inventory', 'i', 'stuff', 'pack', 'backpack'],
use: ['use', 'u', 'operate'],
drop: ['drop', 'd', 'leave', 'throw', 'abandon']
})
// Initialize the game state
let {_player, _rooms, _doors, _currentRoom} = loadGame(setupData)
/**
* Loads a game from a saved game state (or initializes from a default state).
*
* @param gameData Specifically formatted object that represents the game state.
* See config.js for example structure.
*/
function loadGame(gameData) {
const player = gameData.entities.player
const gameState = {
// Create player object from gameData
_player: new Player(
player.name,
player.descriptions[0],
player.health,
player.strength,
player.inventory.map(item =>
new Item(item.name, item.descriptions[0])),
player.hunger),
// Create room objects from setupData
//TODO add entities to the room objs once entity class is implemented
_rooms: gameData.rooms.map(room => new Room(
room.name,
room.descriptions[0],
room.items.map(item =>
new Item(item.name, item.descriptions[0]))
))
}//end gameState init
// Create door objects and connect rooms from gameData/gameState
gameState._doors = gameData.doors.map(door => new Door(
door.name,
door.descriptions[0],
door.connectingRooms.map(connection => ({
room: successOrError(
gameState._rooms.find(room => room.name() === connection.inRoom),
`Connect failed for room "${connection.inRoom}" on door "${door.name}"`
),
located: connection.located
})),
))
// Set current room from gameData
gameState._currentRoom = successOrError(
gameState._rooms.find(room => room.name() === gameData.game.startingRoom),
`Set current room failed for room "${gameData.game.startingRoom}"`
)
return gameState
}
// Function to display initial info about the current room
function displayRoomInfo(room) {
roomNamer.display(room.name())
descriptor.display(room.description())
}
//run function starts the game accepting input
this.run = () => {
displayRoomInfo(_currentRoom)
$userInput.on('keydown', (event) => {
//user presses enter
if (event.which === 13) {
let commands = parser.validate($userInput.val())
let command = {}
while (command = commands.next().value) {
switch (command.action) {
case 'go':
go(command.payload)
break
case 'take':
take(command.payload)
break
case 'inventory':
inventory()
break
case 'drop':
drop(command.payload)
break
default:
throw new Error('Something went wrong in the parser for command', command)
}
}//end while, no more commands to switch
//clear the input field
$userInput.val('')
displayRoomInfo(_currentRoom)
}
else if(event.which === 38){//Up arror pushed
$userInput.val(parser.getLastCommandHistory())
}
else if(event.which === 40){//Down arror pushed
$userInput.val(parser.getNextCommandHistory())
}
})
}
/// Functions for commands start here *******
function go(direction) {
if (_currentRoom.canGo(direction)) {
_currentRoom = _currentRoom.connectedRoom(direction)
checkWinningConditions()
}
else{
messenger.addMessage(`You can't go ${direction}.`)
}
}
function take(itemName) {
if (_currentRoom.hasItem(itemName)) {
let item = _currentRoom.removeItem(itemName)
_player.take(item)
$('#items').text(_currentRoom.listOfItems())
}
else{
messenger.addMessage(`There's no ${itemName} here.`)
}
}
function inventory() {
messenger.addMessage(_player.inventory())
}
function drop(itemName) {
if (_player.has(itemName)) {
let item = _player.drop(itemName)
_currentRoom.addItem(item)
}
else{
messenger.addMessage(`You don't have a ${itemName}.`)
}
checkWinningConditions()
}
function checkWinningConditions() {
// Hacked in game-winning condition.
if (_currentRoom.name() === 'Secret Room'
&& _currentRoom.hasItem('toy')
&& _currentRoom.hasItem('knife')) {
_currentRoom = new Room('You win!',
"You've completed the game by giving the man the toy and the knife.")
}
}
function successOrError(test, errMsg){
if(!test){
throw new Error(errMsg)
}
return test
}
} //end constructor
}