private void OnProcessedCellHandler(AbstractMazeCell <TSOMazeData> cell) { // get wall configuration cell.CellData.Wall_Config = AbstractMazeGenerator <TSOMazeData> .GetWallConfig(cell); // choose a color from available pools if (AllColorPools.Count > 1) { int index = Rng.Next(0, AllColorPools.Count); cell.CellData.Color = AllColorPools[index].Color; AllColorPools[index].Remaining--; // if the pool is dry, remove it as an option if (AllColorPools[index].Remaining == 0) { AllColorPools.RemoveAt(index); } } else // only one color left { cell.CellData.Color = AllColorPools[0].Color; } // push the cell into the correct list to send to the UIEOD var colorIndex = (int)cell.CellData.Color; if (colorIndex < 4) { ColorCells[colorIndex].Add(cell); } }
/// <summary> /// /// </summary> /// <param name="cell"></param> private void OnProcessedCellHandler(AbstractMazeCell <FreeSOMazeData> cell) { // set the barrier data now for ease of access later byte north = 0; byte east = 0; byte west = 0; byte south = 0; if (cell.North_Neighbor == null) { north = 1; } if (cell.East_Neighbor == null) { east = 1; } if (cell.West_Neighbor == null) { west = 1; } if (cell.South_Neighbor == null) { south = 1; } cell.CellData.SetBarriers(north, east, west, south); }
internal void MoveTo(AbstractMazeCell <FreeSOMazeData> target) { // mark the location we're leaving as visited Location.CellData.UnvisitedSolution = false; if (IsLogicPlayer) { Location.CellData.LogicVisited = true; } else { Location.CellData.CharismaVisited = true; } lock (_BreadCrumbs) { if (target.CellData.UnvisitedSolution) { _BreadCrumbs = new List <AbstractMazeCell <FreeSOMazeData> >(); } else { if (!_BreadCrumbs.Contains(target)) { _BreadCrumbs.Insert(0, Location); } else { _BreadCrumbs.Remove(Location); _BreadCrumbs.Remove(target); } } } Location = target; _TotalMoves++; }
internal void Reset() { _BreadCrumbs = new List <AbstractMazeCell <FreeSOMazeData> >(); _Difficulty = FreeSOMazeDifficulties.Unselected; _Location = null; _Cooldown = 0; _TotalMoves = 0; _Payout = 0; DelayedEvents = new List <Tuple <string, byte[]> >(); }
private void CharismaButtonClickedHandler(string evt, byte[] direction, VMEODClient charPlayer) { // validate move, make move, check for solution if (charPlayer.Equals(CharismaPlayer) && direction.Length == 1 && GameState.Equals(VMEODTwoPersonJobObjectMazePluginStates.Solving)) { var directionByte = direction[0]; AbstractMazeCell <TSOMazeData> nextCell = null; switch (directionByte) { case (byte)AbstractMazeCellCardinalDirections.North: { nextCell = CharismaPlayerOrigin.North_Neighbor; break; } case (byte)AbstractMazeCellCardinalDirections.West: { nextCell = CharismaPlayerOrigin.West_Neighbor; break; } case (byte)AbstractMazeCellCardinalDirections.East: { nextCell = CharismaPlayerOrigin.East_Neighbor; break; } case (byte)AbstractMazeCellCardinalDirections.South: { nextCell = CharismaPlayerOrigin.South_Neighbor; break; } } // if it's a valid move if (nextCell != null) { CharismaPlayerOrigin = nextCell; // if it's the solution/exit if (CharismaPlayerOrigin.CellData.IsExit) { MazeSolved = true; EnqueueGotoState(VMEODTwoPersonJobObjectMazePluginStates.Reacting); } } if (MazeSolved) { SendCharismaPlayerCellData("TSOMaze_Final_Cell"); } else { SendCharismaPlayerCellData("TSOMaze_Update_Cell"); } } }
/// <summary> /// /// </summary> /// <param name="evt"></param> /// <param name="chosenCardinal"></param> /// <param name="client"></param> private void MoveRequestHandler(string evt, byte[] chosenCardinal, VMEODClient client) { if (GameState.Equals(FreeSOMazeStates.NavigatingMaze) && NextState.Equals(FreeSOMazeStates.Invalid)) { FreeSOMazePlayer player = null; FreeSOMazePlayer partner = null; if (LogicPlayer?.Client.Equals(client) ?? false) { player = LogicPlayer; partner = CharismaPlayer; } else if (CharismaPlayer?.Client.Equals(client) ?? false) { player = CharismaPlayer; partner = LogicPlayer; } if (player != null) { if (player.Cooldown >= GLOBAL_COOLDOWN && Enum.IsDefined(typeof(FreeSOMazeCardinals), chosenCardinal[0])) { var location = player.Location; var cardinal = (FreeSOMazeCardinals)Enum.ToObject(typeof(FreeSOMazeCardinals), chosenCardinal[0]); AbstractMazeCell <FreeSOMazeData> target = null; switch (cardinal) { case FreeSOMazeCardinals.North: target = location.North_Neighbor; break; case FreeSOMazeCardinals.East: target = location.East_Neighbor; break; case FreeSOMazeCardinals.West: target = location.West_Neighbor; break; case FreeSOMazeCardinals.South: target = location.South_Neighbor; break; } if (target != null) // it is a legal move { ValidateLegalMove(player, target, cardinal, partner); return; } } SendAllowMazeEvent(player, false); // re-enables input } } }
/// <summary> /// /// </summary> /// <param name="caller"></param> /// <param name="target"></param> /// <param name="cardinal"></param> /// <param name="partner"></param> private void ValidateLegalMove(FreeSOMazePlayer caller, AbstractMazeCell <FreeSOMazeData> target, FreeSOMazeCardinals cardinal, FreeSOMazePlayer partner) { if (caller != null && partner != null) { lock (MoveLock) { if (GameState.Equals(FreeSOMazeStates.NavigatingMaze) && NextState.Equals(FreeSOMazeStates.Invalid) && caller.Cooldown >= GLOBAL_COOLDOWN) { bool rollForHint = true; caller.MoveTo(target); caller.Cooldown = 0; caller.CurrentFacingCardinal = cardinal; // is the partner at the target, meaning have the two met in any cell if (partner.Location.Equals(target)) { // gameover win! rollForHint = false; EnqueueGotoState(FreeSOMazeStates.Gameover); // payout data var skillPayout = (int)Math.Round((caller.Skill + partner.Skill) * SKILL_PAYOUT_MULTIPLIER, 0); var callerPayoutData = new string[] { BasePayouts[ChosenMazeDifficulty] + "", skillPayout + "", RoundTimes[ChosenMazeDifficulty] - MazeTimeRemaining + "", caller.TotalMoves + "", partner.TotalMoves + "" }; var partnerPayoutData = new string[] { BasePayouts[ChosenMazeDifficulty] + "", skillPayout + "", RoundTimes[ChosenMazeDifficulty] - MazeTimeRemaining + "", partner.TotalMoves + "", caller.TotalMoves + "" }; var totalPayout = skillPayout + BasePayouts[ChosenMazeDifficulty]; // queue gameover for caller caller.QueuePayoutEvent("FreeSOMaze_win", callerPayoutData, totalPayout); // queue gameover for partner partner.QueuePayoutEvent("FreeSOMaze_win", partnerPayoutData, totalPayout); // pay the object owner now, keeping in tradition with 10% of participant(s) payout Controller.SendOBJEvent(new VMEODEvent((short)FreeSOMazeEvents.PayOwner, new short[] { (short)(totalPayout / 10) })); } caller.Send("FreeSOMaze_move_to", caller.GetLocationData(GetHint(caller, rollForHint))); if (rollForHint) // don't send allow maze event on a gameover { SendAllowMazeEvent(caller, false); } } } } }
internal FreeSOMazeCardinals GetTargetCardinal(AbstractMazeCell <FreeSOMazeData> source, AbstractMazeCell <FreeSOMazeData> target) { _Client.Send("FreeSOMaze_alert", "Server: source is: " + source.Row + " " + source.Column + " and target: " + target.Row + " " + target.Column); if (source?.North_Neighbor?.Equals(target) ?? false) { return(FreeSOMazeCardinals.North); } if (source?.East_Neighbor?.Equals(target) ?? false) { return(FreeSOMazeCardinals.East); } if (source?.West_Neighbor?.Equals(target) ?? false) { return(FreeSOMazeCardinals.West); } if (source?.South_Neighbor?.Equals(target) ?? false) { return(FreeSOMazeCardinals.South); } return(FreeSOMazeCardinals.Invalid); }
/// <summary> /// /// </summary> /// <param name="maze"></param> private void MazeGeneratedHandler(AbstractMazeCell <FreeSOMazeData>[,] maze) { RawMaze = maze; try { var charIndex = ThankU.Next(0, EveryDeadEndCell.Count); CharismaPlayer.Location = EveryDeadEndCell[charIndex]; lock (EveryDeadEndCell) EveryDeadEndCell.Remove(CharismaPlayer.Location); var logicIndex = ThankU.Next(0, EveryDeadEndCell.Count); LogicPlayer.Location = EveryDeadEndCell[logicIndex]; } catch (Exception e) { Console.WriteLine("oops " + e.Message); } EveryDeadEndCell = new List <AbstractMazeCell <FreeSOMazeData> >(); Solution = CurrentMaze.GetPathFromOriginToExit(CharismaPlayer.Location, LogicPlayer.Location, -1); // add hints based on hint probability if (Solution != null) { MinimumSolutionMoves = Solution.Count; var hintProbability = HintProbabilities[ChosenMazeDifficulty].Item1; for (int cell = 0; cell < Solution.Count; cell++) { Solution[cell].CellData.UnvisitedSolution = true; var roll = ThankU.Next(1, 101); if (roll <= hintProbability) { Solution[cell].CellData.ShowHint = true; } } EnqueueGotoState(FreeSOMazeStates.LoadingMaze); CumulativeHintProbability = HintProbabilities[ChosenMazeDifficulty].Item2; } }
private void MazeGeneratedHandler(AbstractMazeCell <TSOMazeData>[,] maze) { MazeArray = maze; // random number from 0 to 3 inclusive for one of the 4 colors var colorIndex = Rng.Next((int)VMEODTwoPersonJobObjectMazePluginCellColors.Blue, (int)VMEODTwoPersonJobObjectMazePluginCellColors.Blank); ThisRoundOriginColor = colorIndex; var cellList = ColorCells[colorIndex]; // randon number from 0 to list.count for any cell of that color colorIndex = Rng.Next(0, cellList.Count); CharismaPlayerOrigin = cellList[colorIndex]; // get the solution var numberOfMoves = Rng.Next(MIN_MOVES_TO_EXIT, MAX_MOVES_TO_EXIT + 1); SolutionPath = CurrentMaze.GetPathFromOriginToExit(CharismaPlayerOrigin, null, numberOfMoves); if (SolutionPath != null) { SolutionCell = SolutionPath[SolutionPath.Count - 1]; } else { Reset(); } if (SolutionCell != null) { SolutionCell.CellData.Color = VMEODTwoPersonJobObjectMazePluginCellColors.Blue; SolutionCell.CellData.IsExit = true; MazeGenerated = true; } else { Reset(); } }
/// <summary> /// /// </summary> /// <param name="state"></param> private void GotoState(FreeSOMazeStates state) { GameState = state; Tock = 0; switch (state) { case FreeSOMazeStates.Lobby: { ChosenMazeDifficulty = FreeSOMazeDifficulties.Unselected; CharismaPlayer?.Reset(); if (CharismaPlayer?.IsLoaded ?? false) { SendLobbyInfoEvent(CharismaPlayer, LogicPlayer); } LogicPlayer?.Reset(); if (LogicPlayer?.IsLoaded ?? false) { SendLobbyInfoEvent(LogicPlayer, CharismaPlayer); } if (CurrentMaze != null) { CurrentMaze.OnMazeGenerated -= MazeGeneratedHandler; CurrentMaze.OnFinalProcessingCell -= OnProcessedCellHandler; CurrentMaze.OnDeadEndCreation -= OnDeadEndHandler; Solution = null; RawMaze = null; MazeTimeRemaining = 0; BroadcastSharedEvent("FreeSOMaze_time", BitConverter.GetBytes(MazeTimeRemaining)); } else { EveryDeadEndCell = new List <AbstractMazeCell <FreeSOMazeData> >(); } break; } case FreeSOMazeStates.GeneratingMaze: { CurrentMaze = AbstractMazeGenerator <FreeSOMazeData> .GetEmptyMaze(MazeSizes[ChosenMazeDifficulty], MazeSizes[ChosenMazeDifficulty]); CurrentMaze.OnMazeGenerated += MazeGeneratedHandler; CurrentMaze.OnFinalProcessingCell += OnProcessedCellHandler; CurrentMaze.OnDeadEndCreation += OnDeadEndHandler; var origin = ThankU.Next(0, (int)BuildFromOrigins.Dead_Center + 1); CurrentMaze.BuildFromOrigin(origin); BroadcastSharedEvent("FreeSOMaze_goto_maze", BitConverter.GetBytes((int)ChosenMazeDifficulty)); break; } case FreeSOMazeStates.LoadingMaze: { MazeTimeRemaining = 0; int cardinal = 0; if (CharismaPlayer != null) { cardinal = GetSolutionCardinal(CharismaPlayer); CharismaPlayer.CurrentFacingCardinal = (FreeSOMazeCardinals)Enum.ToObject(typeof(FreeSOMazeCardinals), cardinal); CharismaPlayer.Send("FreeSOMaze_show_maze", CharismaPlayer.GetLocationData((int)FreeSOMazeCardinals.Invalid)); } if (LogicPlayer != null) { cardinal = GetSolutionCardinal(LogicPlayer); LogicPlayer.CurrentFacingCardinal = (FreeSOMazeCardinals)Enum.ToObject(typeof(FreeSOMazeCardinals), cardinal); LogicPlayer.Send("FreeSOMaze_show_maze", LogicPlayer.GetLocationData((int)FreeSOMazeCardinals.Invalid)); } break; } case FreeSOMazeStates.NavigatingMaze: { CharismaPlayer.Cooldown = GLOBAL_COOLDOWN; LogicPlayer.Cooldown = GLOBAL_COOLDOWN; SendAllowMazeEvent(CharismaPlayer, false); SendAllowMazeEvent(LogicPlayer, false); MazeTimeRemaining = RoundTimes[ChosenMazeDifficulty]; BroadcastSharedEvent("FreeSOMaze_time", BitConverter.GetBytes(MazeTimeRemaining)); break; } case FreeSOMazeStates.Gameover: { MazeTimeRemaining = 0; break; } } }
/// <summary> /// /// </summary> /// <param name="cell"></param> private void OnDeadEndHandler(AbstractMazeCell <FreeSOMazeData> cell) { cell.CellData.IsDeadEnd = true; EveryDeadEndCell.Add(cell); }