/// <summary> /// Constructor... creates new Trie with given properrties /// </summary> /// <param name="children">Children tries in tree</param> /// <param name="containsEmptyString">Boolean if it is a word</param> /// <param name="map">Map of Chars to Indices and vice versa to use</param> public ImmutableTrie(ImmutableTrie[] children, bool containsEmptyString, CharMap map) { _containsEmptyString = containsEmptyString; _map = map; _children = (ImmutableTrie[])children.Clone(); }
public BitmapLabel(ImageSource source, CharMap c, string value) { this.Container = new Canvas(); this.Source = source; this.CharMap = c; this.Text = value; }
/// <summary> /// Consturcts a new Key /// </summary> /// <param name="chars">Chars in the word</param> /// <param name="charMap">Charmap mapping the chars to indices</param> public Key(Queue<char> chars, CharMap charMap) { _charmap = charMap; foreach (char c in chars) { char dequeued = chars.Dequeue(); _amountOccurances[charMap.GetLocation(c)]++; chars.Enqueue(dequeued); } // Use polynomial hashing to compute the hash code. foreach (char c in chars) { unchecked { _hashCode *= 35; _hashCode += _amountOccurances[charMap.GetLocation(c)]; } } }
private static CharMap CreateMap(string intcode) { var map = new CharMap(); var pos = Point.From(0, 0); new Engine() .WithMemory(intcode) .OnOutput(engine => { var ch = (char)engine.Output.Take(); if (ch == '\n') { pos = Point.From(0, pos.Y + 1); } else { map[pos] = ch; pos = pos.Right; } }) .Execute(); return(map); }
protected AbstractFile(GenericCharMap charmap, FFTTextFactory.FileInfo layout, IList <IList <string> > strings, string fileComments, IList <string> sectionComments, bool compressible) : this(charmap, layout, fileComments, sectionComments, compressible) { List <IList <string> > sections = new List <IList <string> >(NumberOfSections); for (int i = 0; i < NumberOfSections; i++) { string[] thisSection = new string[strings[i].Count]; strings[i].CopyTo(thisSection, 0); for (int j = 0; j < thisSection.Length; j++) { if (!CharMap.ValidateString(thisSection[j], layout.AllowedTerminators[0])) { throw new InvalidStringException(layout.Guid.ToString(), i, j, thisSection[j]); } } sections.Add(thisSection); } this.Sections = sections.AsReadOnly(); PopulateDisallowedSections(); }
protected override int Part1(string[] input) { var map = CharMap.FromArray(input, '.'); var(_, p2) = map.MinMax(); var p = Pose.From(p2.X / 2, p2.Y / 2, Direction.Up); var infections = 0; for (var i = 0; i < 10000; i++) { // If the current node is infected, it turns to its right. Otherwise, it turns to its left. (Turning is done in-place; the current node does not change.) // If the current node is clean, it becomes infected. Otherwise, it becomes cleaned. (This is done after the node is considered for the purposes of changing direction.) // The virus carrier moves forward one node in the direction it is facing. if (map[p.Point] == '#') { p.TurnRight(); } else { p.TurnLeft(); } if (map[p.Point] == '.') { map[p.Point] = '#'; infections++; } else { map[p.Point] = '.'; } p.Move(1); } return(infections); }
private bool ExecuteRound(ref CharMap map) { CharMap result = new CharMap(map); bool wasSeatChanged = false; foreach ((int x, int y, char c) in map) { int neighborCount = _countNeighbors(map, x, y); if (c == Seat && neighborCount == 0) { result[x, y] = Person; wasSeatChanged = true; } else if (c == Person && neighborCount >= _neighborLimit) { result[x, y] = Seat; wasSeatChanged = true; } } map = result; return(wasSeatChanged); }
protected override int Part2(string[] input) { var map = new CharMap(); var lines = input; for (var y = 0; y < lines.Length; y++) { var line = lines[y]; for (var x = 0; x < line.Length; x++) { map[x][y] = line[x]; } } var width = 5; var height = 5; var levels = new List <CharMap> { map }; var center = Point.From(2, 2); for (var t = 0; t < 200; t++) { if (levels.First().AllPoints(c => c == '#').Any(p => p.X == 0 || p.Y == 0 || p.X == width - 1 || p.Y == height - 1)) { var outer = new CharMap('.'); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { outer[x][y] = '.'; } } levels.Insert(0, outer); } var lowestlevel = levels.Last(); if (center.LookAround().Any(p => lowestlevel[p] == '#')) { var inner = new CharMap('.'); for (var x = 0; x < width; x++) { for (var y = 0; y < height; y++) { inner[x][y] = '.'; } } levels.Add(inner); } // Now go to work, one outer and its inner at a time var nextlevels = new List <CharMap>(); for (var i = 0; i < levels.Count(); i++) { var outer = i > 0 ? levels[i - 1] : null; var level = levels[i]; var inner = i < levels.Count() - 1 ? levels[i + 1] : null; var innerBugs = inner?.AllPoints(c => c == '#').ToArray(); var nextmap = new CharMap(); foreach (var pos in level.AllPoints().Where(p => p != center)) // ToArray should not be needed? { var n = DirectionExtensions.LookAroundDirection().Select(d => BugsInDirection(outer, level, innerBugs, pos, d)).Sum(); var isOnBug = level[pos] == '#'; nextmap[pos] = isOnBug ? n == 1 ? '#' : '.' : n == 1 || n == 2 ? '#' : '.'; } nextlevels.Add(nextmap); } levels = nextlevels; //Console.WriteLine(); //Console.WriteLine($"After {t} minutes"); //var leveldepth = lowest; //foreach (var l in levels) //{ // Console.WriteLine($"Depth {leveldepth++}:"); // l.ConsoleWrite(false); // Console.WriteLine(); //} //Console.WriteLine($"{levels.Count} levels, lowest={lowest}"); //Console.ReadLine(); } var bugs = levels.Sum(l => l.AllPoints(c => c == '#').Count()); return(bugs); int BugsInDirection(CharMap outer, CharMap level, Point[] innerBugs, Point pos0, Direction direction) { var pos = pos0.Move(direction); if (pos.X < 0) { return(outer?[center.Left] == '#' ? 1 : 0); } if (pos.X >= width) { return(outer?[center.Right] == '#' ? 1 : 0); } if (pos.Y < 0) { return(outer?[center.Up] == '#' ? 1 : 0); } if (pos.Y >= height) { return(outer?[center.Down] == '#' ? 1 : 0); } if (pos == center) { switch (direction) { case Direction.Down: return(innerBugs?.Count(p => p.Y == 0) ?? 0); case Direction.Left: return(innerBugs?.Count(p => p.X == width - 1) ?? 0); case Direction.Up: return(innerBugs?.Count(p => p.Y == height - 1) ?? 0); case Direction.Right: return(innerBugs?.Count(p => p.X == 0) ?? 0); } } return(level[pos] == '#' ? 1 : 0); } //IEnumerable<CharMap> PaddedLevels(IEnumerable<CharMap> maps) //{ // yield return new CharMap('.'); // foreach (var m in maps) // { // yield return m; // } // yield return new CharMap('.'); //} //Console.WriteLine($"Day 24 Puzzle 2: {}"); //Debug.Assert(beampoints == 141); }
/// <summary> /// Battle Constructor, created once a unit engages an enemy in battle /// </summary> /// <param name="m">The player's unit</param> /// <param name="e">The enemy's unit</param> /// <param name="fregion">The region where the battle was engaged</param> /// <param name="fgoal">The region's condition for victory</param> public Battle(Unit m, Unit e, Region fregion, Objective fgoal) { MainWindow.BackgroundImage = Content.Graphics.Instance.Images.background.bg_smallMenu; orgls = new List<String>(); region = fregion; goal = fgoal; ally = m; enemy = e; tm=new Tilemap("battle"); cmap = new CharMap(tm); cmap.ShowMisc = true; map = new Map(tm); map.ArrowEnabled = true; map.SelectionEnabled = false; map.changeCurp = changeCurp; map.curSelection = sel; map.focus(5, 6); MainWindow.add(map); lbl_actions = new Label("Actions"); lbl_actions.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_actions.Position = new Vector2(280, 390); lbl_actions.Visible = false; MainWindow.add(lbl_actions); menu_actions = new Menu(5); menu_actions.Position = new Vector2(280, 390); menu_actions.Visible = false; MainWindow.add(menu_actions); menu_actions.Enabled = false; menu_actions.ArrowEnabled = false; lbl_moved = new Label("MOVED"); lbl_moved.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.SPECIAL; lbl_moved.Position = new Vector2(520, 414); lbl_moved.Visible = false; MainWindow.add(lbl_moved); lbl_enemyTurn = new Label("DAMAGE"); lbl_enemyTurn.Color = Color.Red; lbl_enemyTurn.Position = new Vector2(50, 50/*420*/); lbl_enemyTurn.Visible = false; MainWindow.add(lbl_enemyTurn); lbl_name = new Label("Name"); lbl_name.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_name.Position = new Vector2(50, 390); MainWindow.add(lbl_name); lbl_charName = new Label("Derp"); lbl_charName.Position = new Vector2(110, 390); MainWindow.add(lbl_charName); lbl_lvl = new Label("Level"); lbl_lvl.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_lvl.Position = new Vector2(50, 420); MainWindow.add(lbl_lvl); lbl_charLvl = new Label("20"); lbl_charLvl.Position = new Vector2(110, 420); MainWindow.add(lbl_charLvl); lbl_exp = new Label("Exp"); lbl_exp.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_exp.Position = new Vector2(150, 420); MainWindow.add(lbl_exp); lbl_charExp = new Label("42"); lbl_charExp.Position = new Vector2(200, 420); MainWindow.add(lbl_charExp); lbl_hp = new Label("HP"); lbl_hp.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_hp.Position = new Vector2(50, 450); MainWindow.add(lbl_hp); lbl_curHp = new Label("100"); lbl_curHp.Position = new Vector2(90, 450); MainWindow.add(lbl_curHp); lbl_hpSlash = new Label("/"); lbl_hpSlash.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_hpSlash.Position = new Vector2(140, 450); MainWindow.add(lbl_hpSlash); lbl_maxHp = new Label("100"); lbl_maxHp.Position = new Vector2(160, 450); MainWindow.add(lbl_maxHp); lbl_mp = new Label("MP"); lbl_mp.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_mp.Position = new Vector2(50, 480); MainWindow.add(lbl_mp); lbl_curMp = new Label("50"); lbl_curMp.Position = new Vector2(90, 480); MainWindow.add(lbl_curMp); lbl_mpSlash = new Label("/"); lbl_mpSlash.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_mpSlash.Position = new Vector2(140, 480); MainWindow.add(lbl_mpSlash); lbl_maxMp = new Label("50"); lbl_maxMp.Position = new Vector2(160, 480); MainWindow.add(lbl_maxMp); lbl_moveLeft = new Label("Move Left"); lbl_moveLeft.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_moveLeft.Position = new Vector2(50, 510); MainWindow.add(lbl_moveLeft); lbl_move = new Label(""); lbl_move.Position = new Vector2(150, 510); MainWindow.add(lbl_move); lbl_enter = new Label("ENTER"); lbl_enter.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.CONTROL; lbl_enter.Position = new Vector2(520, 462); MainWindow.add(lbl_enter); lbl_enterAction = new Label("Select Unit"); lbl_enterAction.Position = new Vector2(600, 462); MainWindow.add(lbl_enterAction); lbl_v = new Label("V"); lbl_v.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.CONTROL; lbl_v.Position = new Vector2(520, 438); MainWindow.add(lbl_v); lbl_vAction = new Label("View Character"); lbl_vAction.Position = new Vector2(550, 438); MainWindow.add(lbl_vAction); lbl_esc = new Label("ESC"); lbl_esc.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.CONTROL; lbl_esc.Position = new Vector2(520, 486); lbl_esc.Visible = false; MainWindow.add(lbl_esc); lbl_escAction = new Label("Cancel Movement"); lbl_escAction.Position = new Vector2(570, 486); lbl_escAction.Visible = false; MainWindow.add(lbl_escAction); lbl_e = new Label("E"); lbl_e.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.CONTROL; lbl_e.Position = new Vector2(520, 510); MainWindow.add(lbl_e); lbl_eAction = new Label("End Turn"); lbl_eAction.Position = new Vector2(550, 510); MainWindow.add(lbl_eAction); lbl_turnCount = new Label("Turn: " + turnCount + " / 10"); lbl_turnCount.LabelFun = ColorTheme.LabelColorTheme.LabelFunction.BOLD; lbl_turnCount.Position = new Vector2(520, 390); MainWindow.add(lbl_turnCount); lbl_dmg = new Label(""); lbl_dmg.Color = Color.Red; lbl_dmg.Position = new Vector2(0, 0); lbl_dmg.Visible = false; MainWindow.add(lbl_dmg); lbl_actionTaken = new Label(""); lbl_actionTaken.Color = Color.Black; lbl_actionTaken.Position = new Vector2(250, 30); lbl_actionTaken.Font = Content.Graphics.Instance.ActionFont; lbl_actionTaken.Visible = false; MainWindow.add(lbl_actionTaken); lbl_armyTurn = new Label("TO BATTLE, COMRADES!"); lbl_armyTurn.Font = Content.Graphics.Instance.TurnFont; lbl_armyTurn.center(50); lbl_armyTurn.doneShowing = armyTurnDone; lbl_armyTurn.visibleTemp(2000); MainWindow.add(lbl_armyTurn); lbl_battleOutcome = new Label("VICTORY!"); lbl_battleOutcome.Font = Content.Graphics.Instance.TurnFont; lbl_battleOutcome.center(50); lbl_battleOutcome.doneShowing = endOfBattle; lbl_battleOutcome.Visible = false; MainWindow.add(lbl_battleOutcome); deploy(m, true); deploy(e, false); cmap.update(map); freemode = true; actionMode = false; targetMode = false; spellMode = false; itemMode = false; changeCurp(null, new EventArgObject(new Point(5, 6))); scp = new Point(5, 6); endTurnP = new Point(5, 6); setAllNotMoved(); ai = new AI(); ai.set(map, tm, cmap); ai.done = ai_done; MainWindow.InputEnabled = false; }
private static Point derpnearest(CharMap cmap, Point src, String org) { if (isOrgPresent(cmap, new Point(src.X, src.Y - 1), org)) return new Point(src.X, src.Y - 1); if (isOrgPresent(cmap, new Point(src.X + 1, src.Y), org)) return new Point(src.X + 1, src.Y); if (isOrgPresent(cmap, new Point(src.X, src.Y + 1), org)) return new Point(src.X, src.Y + 1); if (isOrgPresent(cmap, new Point(src.X - 1, src.Y), org)) return new Point(src.X - 1, src.Y); if (isOrgPresent(cmap, new Point(src.X - 1, src.Y - 1), org)) return new Point(src.X - 1, src.Y - 1); if (isOrgPresent(cmap, new Point(src.X + 1, src.Y - 1), org)) return new Point(src.X + 1, src.Y - 1); if (isOrgPresent(cmap, new Point(src.X - 1, src.Y + 1), org)) return new Point(src.X - 1, src.Y + 1); if (isOrgPresent(cmap, new Point(src.X + 1, src.Y + 1), org)) return new Point(src.X + 1, src.Y + 1); //inner cercle checked //very inefficient int mr = Gen.max(cmap.NumX, cmap.NumY); for (int r = 2; r < mr + 1; r++) for (int i = -r; i < r + 1; i++) for (int e = -r; e < r + 1; e++) { if (i != -r && i != r && e != -r && e != r) continue; if (isOrgPresent(cmap, new Point(src.X + i, src.Y + e), org)) return new Point(src.X + i, src.Y + e); } return new Point(-1, -1); }
public int GetCharacterCount() => CharMap.Sum(list => list.Value);
public int getChar(char c) { return(CharMap.ContainsKey(c) ? CharMap[c] : SPACE_WIDTH); }
protected override int Part2(string[] input) { var inputMap = CharMap.FromArray(input); // Use a 2D array for fastest storage (faster than CharMap/sparse array // or Dictionary). Trials show that x,y stray <300 steps from origin so // that'll do with a bit of margin. Shift all x,y coordinates into positive // numbers by xyOffset so x,y can index the char[,]-map directly. var xyOffset = 500; var map = new char[xyOffset * 2, xyOffset *2]; // Populate the map with all known infections foreach (var(p, ch) in inputMap.All(c => c == '#')) { map[p.X + xyOffset, p.Y + xyOffset] = '#'; } // Initial x,y is at the centre of the map var(_, size) = inputMap.MinMax(); var x = (uint)size.X / 2 + xyOffset; var y = (uint)size.Y / 2 + xyOffset; // Setup fast lookups for determining dx/dy-movements and turns, // using the current direction as index. // This is faster than a switch or PointWithDirection. var(up, right, down, left) = (0, 1, 2, 3); var dx = new [] { 0, 1, 0, -1 }; var dy = new [] { -1, 0, 1, 0 }; var turnleft = new [] { left, up, right, down }; var turnright = new [] { right, down, left, up }; var turnaround = new [] { down, left, up, right }; int dir = up; var infections = 0; for (var i = 0; i < 10_000_000; i++) { // Clean nodes become weakened. // Weakened nodes become infected. // Infected nodes become flagged. // Flagged nodes become clean. // Decide which way to turn based on the current node: // If it is clean, it turns left. // If it is weakened, it does not turn, and will continue moving in the same direction. // If it is infected, it turns right. // If it is flagged, it reverses direction, and will go back the way it came. // Modify the state of the current node, as described above. // The virus carrier moves forward one node in the direction it is facing. switch (map[x, y]) { case '\0': map[x, y] = 'w'; dir = turnleft[dir]; break; case 'w': map[x, y] = '#'; infections++; break; case '#': map[x, y] = 'f'; dir = turnright[dir]; break; case 'f': map[x, y] = '\0'; dir = turnaround[dir]; break; } x += dx[dir]; y += dy[dir]; } return(infections); }
private static Point pathFindFallBack(CharMap cmap, Tilemap tm, Point src, Point dest, String org) { Dictionary<Point, int> map = new Dictionary<Point, int>(); Queue<PointCounter> main = new Queue<PointCounter>(); Queue<PointCounter> temp = new Queue<PointCounter>(); PointCounter cur; PointCounter tcur; main.Enqueue(new PointCounter(dest, 0)); map[dest] = 0; int cc; bool f = false; while (main.Count > 0) { cur = main.Dequeue(); temp.Clear(); if (cur.p == src) { f = true; break; } cc = cur.c + 1; temp.Enqueue(new PointCounter(cur.p.X, cur.p.Y - 1, cc)); temp.Enqueue(new PointCounter(cur.p.X + 1, cur.p.Y, cc)); temp.Enqueue(new PointCounter(cur.p.X, cur.p.Y + 1, cc)); temp.Enqueue(new PointCounter(cur.p.X - 1, cur.p.Y, cc)); while (temp.Count > 0) { tcur = temp.Dequeue(); if (tcur.p != src) { if (!inMap(tm, tcur.p) || !canMove(tm, tcur.p, org)) continue; if (map.ContainsKey(tcur.p) && map[tcur.p] <= tcur.c) continue; } map[tcur.p] = tcur.c; main.Enqueue(tcur); } } if (!f) return src; Point ret = src; cc = map[src]; temp.Clear(); temp.Enqueue(new PointCounter(src.X, src.Y - 1, 0)); temp.Enqueue(new PointCounter(src.X + 1, src.Y, 0)); temp.Enqueue(new PointCounter(src.X, src.Y + 1, 0)); temp.Enqueue(new PointCounter(src.X - 1, src.Y, 0)); while (temp.Count > 0) { tcur = temp.Dequeue(); if (map.ContainsKey(tcur.p) && map[tcur.p] < cc) { cc = map[tcur.p]; ret = tcur.p; } } if (!canMove(cmap, tm, ret)) return src; return ret; }
private static (CharMap, int) BuildMapAndFindOxygen(string intcode) { var map = new CharMap(); var movements = new MoveGenerator(); map[movements.Current.Position] = MapSpace; var stepsToOxygen = 0; var debug = false; var engine2 = new Engine() .WithMemory(intcode) .OnInput(engine => { var movement = movements.NextProposal(map); if (movement == MoveNone) { engine.Halt = true; } if (debug) { Console.Clear(); Console.WriteLine($"Moves: {movements}"); foreach (var line in map.Render(MapOverlay)) { Console.WriteLine(line); } Console.ReadKey(); } engine.Input.Add(movement); }) .OnOutput(engine => { var status = engine.Output.Take(); switch (status) { case StatusHitTheWall: map[movements.ProposedPosition] = MapWall; break; case StatusMoved: movements.ApproveMove(); map[movements.Current.Position] = MapSpace; break; case StatusFoundOxygen: movements.ApproveMove(); map[movements.Current.Position] = MapOxygen; stepsToOxygen = movements.Moves; break; } }) .Execute(); return(map, stepsToOxygen); // Draw Droid on top of map char MapOverlay(Point p, char val) { var droid = movements.Current?.Position; return(p == droid ? MapDroid : val); } }
/// <summary> /// Handles a Find event. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void uxFind_Click(object sender, EventArgs e) { uxAnagrams.Items.Clear(); _dictionary = new Dictionary<Key, ImmutableTrie>(); if (uxInput.Text == "") uxNumber.Text = "0"; else { try { _map = new CharMap(uxInput.Text.ToLower().ToCharArray()); ImmutableTrie results = FindAnagrams(trie, GetQueue(uxInput.Text.ToLower().ToCharArray())); if (results != null) results.CopyToList(uxAnagrams.Items); uxNumber.Text = uxAnagrams.Items.Count.ToString(); } catch (ArgumentException ae) { MessageBox.Show("Text can only be lower case letters. " + ae.Message); } } }
/// <summary> /// Generates a TileMap with the given CharMap and Character (and Tilemap and Organization) /// </summary> /// <param name="cmap">The CharMap to use</param> /// <param name="c">The Character to base the map on</param> /// <param name="tm">Tilemap (not the pathfind one)</param> /// <param name="org">Organization to base the map from (determins who is ally and who is enemy)</param> /// <returns>a PathFind.TileMap</returns> public static TileMap gen(CharMap cmap, Tilemap tm, String org, Character c) { TileMap ptm = new TileMap(tm.NumX, tm.NumY); for (int i = 0; i < tm.NumX; i++) for (int e = 0; e < tm.NumY; e++) if (!c.canMove(tm.get(i, e).Type)) ptm.set(i, e, Tile_Type.BLOCK_TERRAIN); else if (!cmap.canMove(i, e)) ptm.set(i, e, Tile_Type.BLOCK_UNIT); else ptm.set(i, e, Tile_Type.NOTHING); return ptm; }
private static bool isOrgPresent(CharMap cmap, Point p, String org) { if (p.X < 0 || p.Y < 0 || p.X >= cmap.NumX || p.Y >= cmap.NumY) return false; if (!cmap.isChar(p.X, p.Y)) return false; return cmap.get(p.X, p.Y).Organization == org; }
public PortalMaze(CharMap map) : base(map) { var portalinfo = Map.AllPoints(char.IsUpper).OrderBy(p => p.Y).ThenBy(p => p.X); var portalsByName = new Dictionary <string, List <Tuple <Point, Point> > >(); // Map all entry-portals foreach (var p in portalinfo) { if (Map[p.Down] == '.') { // X // p -> Y <- exit // . <- arrival AddPortal(p.Up, p, p, p.Down); } else if (Map[p.Up] == '.') { // . <- arrival // p -> X <- exit // Y AddPortal(p, p.Down, p, p.Up); } //}; //// Next find the portal exits and match with their entry //foreach (var p in portalinfo) //{ else if (Map[p.Right] == '.') { // exit vv arrival // XY. // ^ p AddPortal(p.Left, p, p, p.Right); } else if (Map[p.Left] == '.') { // arrival vv exit // .XY // ^ p AddPortal(p, p.Right, p, p.Left); } } ; // Link up portals Entry = portalsByName["AA"].First().Item2; Exit = portalsByName["ZZ"].First().Item2; Map[portalsByName["AA"].First().Item1] = '#'; Map[portalsByName["ZZ"].First().Item1] = '#'; ExternalMapPoints = new Point[] { Exit }; Portals = new SparseMap <Portal>(); var area = Map.MinMax(); foreach (var pair in portalsByName.Where(p => p.Key != "AA" && p.Key != "ZZ")) { var p1 = pair.Value[0]; var p2 = pair.Value[1]; Portals[p1.Item1] = new Portal { Name = pair.Key, Pos = p2.Item2, IsDownward = !IsOuterPortal(p1.Item1) }; Portals[p2.Item1] = new Portal { Name = pair.Key, Pos = p1.Item2, IsDownward = !IsOuterPortal(p2.Item1) }; } bool IsOuterPortal(Point p) => p.X <4 || p.X> area.Item2.X - 4 || p.Y <4 || p.Y> area.Item2.Y - 4; void AddPortal(Point pos1, Point pos2, Point departure, Point arrival) { var name = new string(new char[] { Map[pos1], Map[pos2] }); if (!portalsByName.TryGetValue(name, out var pn)) { portalsByName[name] = new List <Tuple <Point, Point> >(); } portalsByName[name].Add(new Tuple <Point, Point>(departure, arrival)); } }
public PortalMaze(string[] lines) : this(CharMap.FromArray(lines)) { }
private static Point targetCharacter(Character c, Point p, CharMap cmap) { bool targetable = false; bool castable = false; List<Point> targetableChar = new List<Point>(); Point target = new Point(-1, -1); if (c is Fighter || c is Scout) { if (cmap.isChar(p.X - 1, p.Y) && cmap.get(p.X - 1, p.Y).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X - 1, p.Y)); } if (cmap.isChar(p.X, p.Y - 1) && cmap.get(p.X, p.Y - 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X, p.Y - 1)); } if (cmap.isChar(p.X + 1, p.Y) && cmap.get(p.X + 1, p.Y).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X + 1, p.Y)); } if (cmap.isChar(p.X, p.Y + 1) && cmap.get(p.X, p.Y + 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X, p.Y + 1)); } } else if (c is Archer) { if (cmap.isChar(p.X - 1, p.Y + 1) && cmap.get(p.X - 1, p.Y + 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X - 1, p.Y + 1)); } if (cmap.isChar(p.X - 1, p.Y - 1) && cmap.get(p.X - 1, p.Y - 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X - 1, p.Y - 1)); } if (cmap.isChar(p.X + 1, p.Y + 1) && cmap.get(p.X + 1, p.Y + 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X + 1, p.Y + 1)); } if (cmap.isChar(p.X + 1, p.Y - 1) && cmap.get(p.X + 1, p.Y - 1).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X + 1, p.Y - 1)); } if (cmap.isChar(p.X - 2, p.Y) && cmap.get(p.X - 2, p.Y).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X - 2, p.Y)); } if (cmap.isChar(p.X, p.Y - 2) && cmap.get(p.X, p.Y - 2).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X, p.Y - 2)); } if (cmap.isChar(p.X + 2, p.Y) && cmap.get(p.X + 2, p.Y).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X + 2, p.Y)); } if (cmap.isChar(p.X, p.Y + 2) && cmap.get(p.X, p.Y + 2).Organization == "main") { targetable = true; targetableChar.Add(new Point(p.X, p.Y + 2)); } } else if (c is Healer) { if (cmap.isChar(p.X - 1, p.Y) && cmap.get(p.X - 1, p.Y).Organization == "ennemy") { castable = true; targetableChar.Add(new Point(p.X - 1, p.Y)); } if (cmap.isChar(p.X, p.Y - 1) && cmap.get(p.X, p.Y - 1).Organization == "ennemy") { castable = true; targetableChar.Add(new Point(p.X, p.Y - 1)); } if (cmap.isChar(p.X + 1, p.Y) && cmap.get(p.X + 1, p.Y).Organization == "ennemy") { castable = true; targetableChar.Add(new Point(p.X + 1, p.Y)); } if (cmap.isChar(p.X, p.Y + 1) && cmap.get(p.X, p.Y + 1).Organization == "ennemy") { castable = true; targetableChar.Add(new Point(p.X, p.Y + 1)); } } else if (c is Caster) { if (cmap.isChar(p.X - 1, p.Y) && cmap.get(p.X - 1, p.Y).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X - 1, p.Y)); } if (cmap.isChar(p.X, p.Y - 1) && cmap.get(p.X, p.Y - 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X, p.Y - 1)); } if (cmap.isChar(p.X + 1, p.Y) && cmap.get(p.X + 1, p.Y).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X + 1, p.Y)); } if (cmap.isChar(p.X, p.Y + 1) && cmap.get(p.X, p.Y + 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X, p.Y + 1)); } if (cmap.isChar(p.X - 1, p.Y + 1) && cmap.get(p.X - 1, p.Y + 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X - 1, p.Y + 1)); } if (cmap.isChar(p.X - 1, p.Y - 1) && cmap.get(p.X - 1, p.Y - 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X - 1, p.Y - 1)); } if (cmap.isChar(p.X + 1, p.Y + 1) && cmap.get(p.X + 1, p.Y + 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X + 1, p.Y + 1)); } if (cmap.isChar(p.X + 1, p.Y - 1) && cmap.get(p.X + 1, p.Y - 1).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X + 1, p.Y - 1)); } if (cmap.isChar(p.X - 2, p.Y) && cmap.get(p.X - 2, p.Y).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X - 2, p.Y)); } if (cmap.isChar(p.X, p.Y - 2) && cmap.get(p.X, p.Y - 2).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X, p.Y - 2)); } if (cmap.isChar(p.X + 2, p.Y) && cmap.get(p.X + 2, p.Y).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X + 2, p.Y)); } if (cmap.isChar(p.X, p.Y + 2) && cmap.get(p.X, p.Y + 2).Organization == "main") { castable = true; targetableChar.Add(new Point(p.X, p.Y + 2)); } } if (targetable) { foreach (Point pt in targetableChar) { if (target == new Point(-1, -1) || cmap.get(pt.X, pt.Y).stats.hp < cmap.get(target.X, target.Y).stats.hp) target = pt; } } if (castable) { foreach (Point pt in targetableChar) { if (target == new Point(-1, -1) || cmap.get(pt.X, pt.Y).stats.hp < cmap.get(target.X, target.Y).stats.hp) target = pt; } } return target; }
public int getChar(char a) { return(CharMap.ContainsKey(a) ? CharMap[a] : SPACE_WIDTH); }
private static bool canMove(CharMap cmap, Tilemap tm, Point dest) { if (tm.get(dest.X, dest.Y).Type == Tile.TileType.MOUNTAIN || tm.get(dest.X, dest.Y).Type == Tile.TileType.WATER) return false; return cmap.canMove(dest.X, dest.Y); }
/// <summary> /// Setup map info /// </summary> public void set(Map fmap, Tilemap ftm, CharMap fcmap) { set(fmap, ftm); cmap = fcmap; }
private static Point nearest(CharMap cmap, Point src, String org) { int mr = Gen.max(cmap.NumX, cmap.NumY); for (int r = 1; r <= mr; r++) { for (int i = -r; i <= r; i++) { for (int e = -r; e <= r; e++) { if (Math.Abs(i) + Math.Abs(e) != r) continue; if (isOrgPresent(cmap, new Point(src.X + i, src.Y + e), org)) return new Point(src.X + i, src.Y + e); } } } return new Point(-1, -1); }
public Challenge() { _map = new CharMap(inputList.ToArray()); }
public static Boolean battle(CharMap cmap, Tilemap tm, String org, Map map, Unit ally, Unit enemy, Label dmg, Label action, ref Boolean gameOver, ref Boolean defeat, GameTime gameTime) { Character c = cmap.get(map.CursorPosition.X, map.CursorPosition.Y); Character m; Point p; Point ne; if (c != null && c.Organization == org && c.stats.movement != 0) { if(c is Healer) ne = nearest(cmap, map.CursorPosition, "ennemy"); else ne = nearest(cmap, map.CursorPosition, "main"); if (isAdj(map.CursorPosition, ne)) { c.stats.movement = 0; p = map.CursorPosition; } else { //finds path to nearest ennemy p = pathFind(cmap, tm, map.CursorPosition, nearest(cmap, map.CursorPosition, "main"), org); if (c.stats.movement > 0) { cmap.move(map.CursorPosition.X, map.CursorPosition.Y, p.X, p.Y); map.changeCursor(new Point(p.X, p.Y)); } c.stats.movement--; } if (c.stats.movement == 0) { Point tar = targetCharacter(c, p, cmap); if (tar != new Point(-1, -1)) { m = cmap.get(tar.X, tar.Y); map.CurLs.Add(tar, Content.Graphics.Instance.Images.gui.cursorRed); if (c is Fighter) dmg.Text = ((Fighter)c).attack(m); else if (c is Archer) dmg.Text = ((Archer)c).attack(m); else if (c is Scout) dmg.Text = ((Scout)c).attack(m); else if (c is Healer) { dmg.Text = ((Healer)c).heal(m).ToString(); action.Text = "Heal"; } else if (c is Caster) { dmg.Text = ((Caster)c).attack(m, new Spell("DerpCast", 1, 5, 1, 5)); action.Text = "DerpCast"; } else dmg.Text = "Cant"; if (action.Text == "") action.Text = "Attack"; dmg.Position = new Vector2(tar.X * 64 - map.getTlc.X * 64, tar.Y * 64 - map.getTlc.Y * 64 + 20); dmg.visibleTemp(500); action.visibleTemp(500); if (dmg.Text != "miss" || dmg.Text != "Cant") { enemy.set(c.Position.X, c.Position.Y, c); ally.set(m.Position.X, m.Position.Y, m); if (m.stats.hp <= 0) { if (m.isMainChar()) gameOver = true; ally.delete(m.Position.X, m.Position.Y); cmap.set(tar.X, tar.Y, null); cmap.update(map); if (ally.Characters.Count <= 0) defeat = true; } } } } return false; } else { for (int e = cmap.NumY - 1; e >= 0; e--) for (int i = cmap.NumX - 1; i >= 0; i--) if (cmap.isChar(i, e) && cmap.get(i, e).stats.movement != 0 && cmap.get(i, e).Organization == org) { if (map.CursorPosition != new Point(i, e)) { map.CurLs.Clear(); dmg.Visible = false; action.Visible = false; action.Text = ""; map.changeCursor(new Point(i, e)); return false; } } } cmap.resetAllMovement(org); return true; }