private void FindPotentialRoomMatch(SeenRoom seenRoom, Player player) { seenRoom.PotentialMatches = (from room in player.Model.Rooms where room.Name == seenRoom.Name select room).ToList(); if (seenRoom.PotentialMatches.Count <= 1) { return; } // check descriptions if available seenRoom.PotentialMatches = (from room in seenRoom.PotentialMatches where DoesRoomDescriptionMatch(room, seenRoom) select room).ToList(); if (seenRoom.PotentialMatches.Count <= 1) { return; } // check exits seenRoom.PotentialMatches = (from room in seenRoom.PotentialMatches where room.DoExitsMatch(player, seenRoom.Exits) select room).ToList(); // check NPC's, maybe bosses // check placed objects }
private void UpdateRoomState(Player player, SeenRoom room) { RoomDisplayCommand command; Direction? direction; // parse the users last command to see if we can tell which direction the user is moving. ParseUserCommand(player, out command, out direction); if (followingDirection != null) { command = RoomDisplayCommand.Move; direction = followingDirection; } //if (command != RoomDisplayCommand.Look) //{ // player.UpdateItems( //} if (command == RoomDisplayCommand.Look) { Looking(player, room, direction); } else if (command == RoomDisplayCommand.Move || command == RoomDisplayCommand.Refresh || command == RoomDisplayCommand.Unknown) { MovedOrRefresh(player, room, command, direction); } }
private void ParseRoomInfo(Player player) { player.Interface.DebugText("Room Parsed: " + roomName + ", Last Command: " + player.LastConfirmedCommand); SeenRoom room = new SeenRoom(); room.Name = roomName.Trim(); if (description != null) { room.Description = description.Trim(); } if (items != null) { var itemMatches = player.Model.RoomItemRegex.Matches(items); room.PopulateInventory(itemMatches, null, player.Model); } if (people != null) { var playerMatches = player.Model.RoomPeopleRegex.Matches(people); room.People.AddRange(playerMatches.Cast <Match>().Select(x => x.Groups["name"].Value)); } var exitMatches = player.Model.RoomExitRegex.Matches(exits); room.Exits.AddRange(exitMatches.Cast <Match>().Select(x => x.Groups["name"].Value)); UpdateRoomState(player, room); player.UpdateGameStatus(Commands.GameStatusUpdate.RoomParsed); }
/// <summary> /// Eliminates potential rooms from a web of rooms. Returns true if potentials were eliminated, false otherwise. /// </summary> /// <param name="room"></param> /// <returns></returns> private bool EliminatePotentials(SeenRoom room) { bool eliminated = false; // eliminate potentials on the current room first. foreach (Direction direction in Enum.GetValues(typeof(Direction))) { var adjacent = room.AdjacentRooms[(int)direction]; if (adjacent != null) { var potentials = (from x in room.PotentialMatches let x1 = x.GetExit(direction).AdjacentRoomNumber where adjacent.PotentialMatches.Any(y => y.RoomNumber == x1) select x).ToList(); if (potentials.Count < room.PotentialMatches.Count) { eliminated = true; } room.PotentialMatches = potentials; } } // once the current room's potentials have been minimized according to local data, reduce the potentials // on all adjacent rooms based on what we already know. foreach (Direction direction in Enum.GetValues(typeof(Direction))) { var adjacent = room.AdjacentRooms[(int)direction]; if (adjacent != null) { var adjacentPotentials = (from x in room.PotentialMatches let x1 = x.GetExit(direction).AdjacentRoomNumber let y = adjacent.PotentialMatches.Single(z => z.RoomNumber == x1) select y).ToList(); if (adjacentPotentials.Count < adjacent.PotentialMatches.Count) { eliminated = true; } adjacent.PotentialMatches = adjacentPotentials; } } // Lastly, recurse through the adjacent rooms to repeat the process. foreach (Direction direction in Enum.GetValues(typeof(Direction))) { var adjacent = room.AdjacentRooms[(int)direction]; if (adjacent != null) { if (EliminatePotentials(adjacent)) { eliminated = true; } } } return(eliminated); }
private void MovedOrRefresh(Player player, SeenRoom room, RoomDisplayCommand command, Direction?direction) { if (player.RoomDetectionState == RoomDetectionState.HaveMatch && command == RoomDisplayCommand.Move && direction != null) { // user is moving, verify that the new room we are in is in fact what we think it is. VerifyNewRoom(player.LastSeenRoom, direction.Value, room, player); } else { // first find a potential match for the room. FindPotentialRoomMatch(room, player); if (room.PotentialMatches.Count == 1) { // we found a definite match, simply set the current room and be done with it. SetCurrentRoom(RoomDetectionState.HaveMatch, room, player); } else if (room.PotentialMatches.Count == 0) { // found a room that we have no idea where it is, so we're officially lost. SetCurrentRoom(RoomDetectionState.NoClue, null, player); } else { if (player.RoomDetectionState == RoomDetectionState.HaveMatches && direction != null) { player.LastSeenRoom.AdjacentRooms[(int)direction] = room; SetCurrentRoom(RoomDetectionState.HaveMatches, room, player); CalculateRoomWeb(player); } else if (command == RoomDisplayCommand.Refresh && player.RoomDetectionState == RoomDetectionState.HaveMatch && room.HasMatch(player.LastSeenRoom.Match.RoomNumber)) { // player refreshed, so if we had a match don't overwrite it with an ambiguity. return; } else if (player.RoomDetectionState == RoomDetectionState.HaveMatch && command == RoomDisplayCommand.Move && direction == null) { // We couldn't tell what direction the user moved, so look at the adjacent rooms and see if there's a single match. var adjacentRooms = player.LastSeenRoom.Match.GetAdjacentRoomNumbers(); var narrowedList = room.PotentialMatches.Where(p => adjacentRooms.Any(a => p.RoomNumber == a)); if (narrowedList.Count() == 1) { room.PotentialMatches.RemoveAll(x => x.RoomNumber != narrowedList.First().RoomNumber); // found a definite match, let's assume the user moved there. SetCurrentRoom(RoomDetectionState.HaveMatch, room, player); return; } } else { SetCurrentRoom(RoomDetectionState.HaveMatches, room, player); } } } }
private bool DoesRoomDescriptionMatch(Room candidate, SeenRoom seenRoom) { // no description, simply return all candidates as the user likely just has short mode on if (seenRoom.Description == null) { return(true); } return(Utilities.AssembleDescriptionString(candidate.Desc_0, candidate.Desc_1, candidate.Desc_2, candidate.Desc_3, candidate.Desc_4, candidate.Desc_5, candidate.Desc_6) == seenRoom.Description.ToString()); }
private void Looking(Player player, SeenRoom room, Direction?direction) { if (player.RoomDetectionState == RoomDetectionState.HaveMatches && direction != null) { // user is looking through an exit, and they aren't entirely sure where they are. // So we'll try to use this information to come up with an idea, hopefully narrow down the choices. FindPotentialRoomMatch(room, player); // we're looking and we have a hazy idea of where we are, so add the room to the current web of data // and recalculate. player.LastSeenRoom.AdjacentRooms[(int)direction] = room; CalculateRoomWeb(player); } }
private static bool IsInWeb(SeenRoom start, SeenRoom toCheck) { foreach (Direction direction in Enum.GetValues(typeof(Direction))) { var adjacent = start.AdjacentRooms[(int)direction]; if (adjacent == toCheck) { return(true); } if (adjacent != null && IsInWeb(adjacent, toCheck)) { return(true); } } return(false); }
private static void SetCurrentRoom(RoomDetectionState state, SeenRoom room, Player player) { if (state == RoomDetectionState.HaveMatches) { if (player.SeenRoomAnchor == null) { // we had a hazy idea before, and the new room has done nothing to correct that notion. // set the anchor point so a web can be calculated. player.SeenRoomAnchor = room; } else if (!IsInWeb(player.SeenRoomAnchor, room)) { // The newly seen room isn't in the web, so we might have teleported or some other accident happened. Clear // the anchor so we don't try running a calculation on old data. player.SeenRoomAnchor = room; } } player.LastSeenRoom = room; player.RoomDetectionState = state; switch (state) { case RoomDetectionState.HaveMatch: player.SeenRoomAnchor = null; player.Interface.MapControl.SetRoom(room.Match); player.Interface.DebugText("Room detected: " + room.PotentialMatches[0].Map_Number.ToString() + ":" + room.PotentialMatches[0].Room_Number.ToString()); break; case RoomDetectionState.HaveMatches: player.Interface.DebugText("Potential Room Matches: " + room.PotentialMatches.Count().ToString()); break; case RoomDetectionState.NoClue: player.SeenRoomAnchor = null; player.Interface.DebugText("No room matches found!"); break; } }
/// <summary> /// Called when the user moves from one room to another. This simply verifies that the new room /// is what we expect it to be. /// </summary> /// <param name="lastSeenRoom"></param> /// <param name="movingDirection"></param> /// <param name="room"></param> private void VerifyNewRoom(SeenRoom lastSeenRoom, Direction movingDirection, SeenRoom room, Player player) { FindPotentialRoomMatch(room, player); if (room.PotentialMatches.Count == 1) { // only one match for the current room. Go ahead and set it. SetCurrentRoom(RoomDetectionState.HaveMatch, room, player); return; } if (room.PotentialMatches.Count == 0) { // no matches, not sure what to do. SetCurrentRoom(RoomDetectionState.NoClue, null, player); return; } // ambiguous match found, so attempt to figure out what room we're in by following the // exit that the user used. var exitData = lastSeenRoom.Match.GetExits().SingleOrDefault(x => x.Direction == movingDirection); Room matchedRoom = null; if (exitData != null) { matchedRoom = room.GetMatch(exitData.AdjacentRoomNumber); } if (matchedRoom == null) { // no match. Dunno what happened. User possibly teleported into an ambiguous room. SetCurrentRoom(RoomDetectionState.HaveMatches, room, player); } else { // we have a match. Remove all candidates that aren't the matched room room.PotentialMatches.RemoveAll(x => x != matchedRoom); SetCurrentRoom(RoomDetectionState.HaveMatch, room, player); } }
/// <summary> /// No light in the room, figure out if we're moving and in which direction. /// </summary> /// <param name="player"></param> public static void HandleDarkMovement(Player player) { RoomDisplayCommand command; Direction? direction; // parse the users last command to see if we can tell which direction the user is moving. ParseUserCommand(player, out command, out direction); if (command == RoomDisplayCommand.Move && direction != null && player.RoomDetectionState == RoomDetectionState.HaveMatch) { var exitData = player.LastSeenRoom.Match.GetExits().SingleOrDefault(x => x.Direction == direction); if (exitData != null) { var roomNumber = exitData.AdjacentRoomNumber; var room = player.Model.GetRoom(roomNumber); SeenRoom seen = new SeenRoom(); seen.PotentialMatches = new List <Room>() { room }; SetCurrentRoom(RoomDetectionState.HaveMatch, seen, player); } } }